ladydd

Python

多 worker 场景下,Python 日志按天落盘为什么会“串日期”

在一个多 worker 的 Python 服务里,日志按天落盘本来是件很普通的事,但真正跑进 Docker 和多进程环境之后,事情往往没有想象中那么简单。我们这次遇到的,就是一个非常典型、也非常容易被忽视的问题:日志文件日期彻底混乱了。 最离谱的时候,目录里会看到一个名字像这样的文件: app.log.2026-04-18 但打开之后,里面却混进了 2026-04-23 的日志。 这种现象第一眼看上去很玄学,实际上原因并不玄学。核心就是一句话: 多 worker 进程同时写同一个轮转日志文件,天然就容易出事。 这篇文章把这个问题的成因、误区,以及我们当前先落地的临时方案整理一下。也提前说明:这不是最终版日志架构,只是先把现在线上最痛的跨天串文件问题止住。 背景 项目运行在 Docker 里,服务启动方式是: uvicorn src.main:app --host 0.0.0.0

By ladydd

AI

一次看起来像“模型不兼容”,其实是 `max_tokens` 把输出截断了

最近在给这套商品图提示词服务接入新的 OpenAI-compatible 供应商时,我们踩了一个很典型、也很容易误判的坑: * 同样是 /chat/completions * 同样是 OpenAI 兼容请求格式 * 旧供应商 qwen3-vl-plus 跑得很正常 * 新供应商 gemini-3-flash-preview 却频繁只返回半句话 最开始看现象,直觉很容易往这几个方向怀疑: * 这个供应商的 OpenAI 兼容实现不完整 * 多模态图片传递格式不对 * 响应解析逻辑没兼容到位 * 模型本身不稳定 但最后复盘下来,真正的主因比想象中直接很多:我们显式传了 max_tokens,而这个第三方 OpenAI-compatible 供应商上的 gemini-3-flash-preview 组合,很可能把图片理解和推理消耗也算进了输出预算里,导致最终文本阶段只剩下一小截。 这篇文章就把整个问题、排查过程和最终处理方法完整记录一下。 背景 我们的服务很简单: 1. 前端提交商品标题、图片 URL、模型配置 2. 后端调用 Op

By ladydd

MCP

MCP 服务端的隐藏设计:结论性数据如何改变

Agent 的工作方式 我们以为 MCP 服务只是查数据的管道,拆开一看,发现服务端已经把分析结论都算好了。这个发现改变了我对 Agent 架构的理解。 起因:一次对 MCP 服务的逆向探索 最近在研究 MCP(Model Context Protocol)的实际应用,我选了一个真实的商业 MCP 服务 —— 某电商卖家流量分析平台作为研究对象。该服务提供了 27 个工具,覆盖关键词分析、流量运营、广告洞察等领域。 最初的预期很简单:MCP 服务就是一个数据接口,Agent(LLM)调用它拿到原始数据,然后自己分析、得出结论、给用户建议。 实际拆开一看,完全不是这么回事。 第一个发现:返回数据里藏着完整的分析结论 我写了一个 Python 脚本,绕过所有 AI 客户端,直接用

By ladydd

Python

FastAPI 异步任务服务的并发设计演进:从单进程轮询到多 Worker 协程直处理

本文记录了一个 FastAPI 异步任务服务在并发架构上的思考和演进过程。这个服务的本质很简单:接收客户端请求,转发给下游 AI API,把结果存起来供客户端轮询。它不做复杂的业务计算,不做数据聚合,就是一个纯转发层——接活、派活、存结果。正因为场景足够简单,我们才有机会做一次化繁为简的架构妥协,把原本"看起来该用任务队列"的设计砍到只剩三行核心配置。 一、先说清楚场景:我们到底在干什么 这个服务做的事情可以用一句话概括: 客户端提交参数 → 服务转发给下游 AI API → 等结果 → 存 Redis → 客户端来取。 关键特征: * 纯 IO 转发:服务本身不做任何 CPU 密集计算,所有耗时都花在等下游 API 返回。一次调用几秒到几十秒不等,全是网络等待。 * 异步模式:客户端提交任务后立即拿到 task_id,

By ladydd

MCP

从连上一个 MCP 服务到理解 AI 系统的工程本质

一次从"会用"到"理解原理"再到"能优化"的完整探索记录。 本文记录了我通过实际动手连接一个远程 MCP 服务(SIF —— 亚马逊卖家流量分析平台),一步步深入理解 MCP 协议机制、LLM 上下文管理、注意力资源分配、以及工具编排优化方案的全过程。 一、起点:连上一个真实的 MCP 服务 什么是 MCP? MCP(Model Context Protocol)是 Anthropic 主导设计的一个开放协议,目的是标准化 AI 应用与外部工具/数据源之间的通信方式。你可以把它理解为"AI 世界的 USB 接口"

By ladydd

agent

OpenCLI 学习 08:现实约束与兼容层思路

1. 我当前面对的现实约束 虽然我现在越来越倾向于: * 上层做 Agent * 下层做 Harness 但现实里调用我的人,很多时候只会通过 API 的形式来调用能力。 这意味着: * 我未必能决定上层最终长成什么样 * 外部接入形式可能仍然是 HTTP、函数调用或者一次性接口 2. 我当前的重要判断 我现在认为,这并不和 Agent + Harness 的方向冲突。 更合理的理解是: * Agent + Harness 是内部核心结构 * API、函数调用、HTTP 等形式是外部兼容层 也就是说,我真正需要先做好的是: * Agent 的能力设计 * Harness 的抽象与落地 * Agent 和 Harness 之间的接口关系 而不是一开始就被外部接入形式绑死。 3. 一个重要认识:不是 API 和 Agent 二选一 我当前更认可的分层是:

By ladydd

agent

OpenCLI 学习 07:我的工作方向与方法抽象

1. 我目前开始形成的一个工作判断 我觉得之后我的工作可以分成两个主要方向。 方向一:构建一个聪明且通用的 Agent 这个 Agent 的重点,不是把所有具体业务逻辑都写死在内部,而是让它擅长: * 理解任务 * 选择工具 * 读取状态 * 逐步决策 * 失败后调整 * 结合 Skill 和结构化输出来完成多步编排 也就是说,它更像是一个通用的编排和判断层。 方向二:把具体业务需求落成 Agent-Friendly Harness 当一个具体业务需求到来时,我不再优先想着: * 直接暴露零散 API * 直接写一个固定 workflow 而是优先考虑: * 能不能把这类业务能力整理成命令树 * 能不能有清晰的状态模型 * 能不能有结构化输出 * 能不能让 Agent 更容易识别这些能力并自主组合 也就是说,重点从“写固定流程”转向“设计能力接口”。 2. 一个重要修正:不是不要 API,而是不要把 API 直接等同于

By ladydd

agent

OpenCLI 学习 06:Agent-First 与设计重心

1. 我当前对这个项目最核心的一个判断 我现在越来越觉得,这个项目的核心是 agent-first。 也就是说,它是先站在“未来软件能力会越来越需要被 Agent 调用”的前提出发,再反过来思考: * 接口应该长什么样 * 能力该如何暴露 * 什么样的形式最适合 Agent 理解和调用 在这个前提下,CLI 形式的 harness 就变成了一种非常现实的工程落地方式。 2. 为什么它不把流程写死 我当前的一个重要理解是: 这个项目不想做固定工作流系统。 它更希望做的是: * 把领域能力整理成结构化命令树 * 把这些能力作为一组可组合的工具暴露出来 * 把具体任务编排尽量交给 Agent 自己决定 所以它信任 Agent 的地方在于: * 让 Agent 去选命令 * 让 Agent 去组合步骤 * 让 Agent 去形成任务级流程 3. 但这不是“少设计” 这一点是我现在特别明确的一个修正。 不能把这个项目理解成: * 因为相信

By ladydd

agent

OpenCLI 学习 05:能力暴露与自由组合

1. 我当前最强烈的一个感受 不同 Agent、不同底层模型,对同一套 CLI 的理解能力并不一样。 这意味着: * 同样一个 harness * 不同 Agent 的使用效果可能差很多 所以真正重要的不只是“有没有这些命令”,而是: 这些能力是如何暴露给 Agent 的。 2. 我目前理解到的关键点 这个项目不是简单把旧软件的功能堆成一堆命令,而是在思考: * 怎么让 Agent 更容易理解工具能力 * 怎么让 Agent 在面对真实任务时更容易选对命令 * 怎么降低不同模型之间的理解差异带来的问题 也就是说,命令设计、文档、Skill、JSON 输出,这些都不是附属物,而是能力暴露设计的一部分。 3. 我目前觉得这个项目最精髓的地方 它没有把任务流程完全写死。 它做的是: * 提供一棵结构化的能力树 * 让 Agent 根据真实需求去决定调用哪几个命令 * 让 Agent 自己把这些命令组合成实际工作过程

By ladydd

agent

OpenCLI 学习 04:Harness 目录与文件分工

1. 为什么我在这一部分容易混乱 因为一个 harness 目录里通常会同时出现: * 设计文档 * README * Skill * CLI 入口 * core 业务模块 * utils 后端桥接 * tests 如果不先按职责区分,很容易把这些文件都看成“某种说明文档”或者“某种脚本入口”。 2. 一个标准 harness 的结构 我目前可以把一个标准 harness 粗略理解成: <software>/ └── agent-harness/ ├── <SOFTWARE>.md ├── setup.py └── cli_anything/ └── <software>/ ├── __main__.py ├── README.md ├── <software>_cli.

By ladydd

agent

OpenCLI 学习 03:Agent 边界与设计张力

1. Agent 和 harness 的边界 这是我在理解过程中非常关键的一点。 当前我的理解: * Agent 负责“决定做什么” * Harness 负责“把事情做成可调用能力” 也就是说: * Agent 更像策略层、决策层、编排层 * Harness 更像能力层、执行层、适配层 Harness 本身不是 Agent,它更像是 Agent 可调用的工具系统。 2. 这个项目的反馈机制属于哪一类 我之前会自然想到“自我反思型”的 harness: * 会自动评估自己做得好不好 * 会自动调整策略 * 会自动重规划 但这个项目里的 harness 并不强内建这种运行时自我反思。 它更强的是: * 可观察:info、list、status、history * 可验证:真实输出检查、E2E 测试、

By ladydd
陕公网安备61011302002223号 | 陕ICP备2025083092号