详细数据流转:

1️⃣ 用户发起指令与系统组装 (CLI & Initialization)

  • 用户动作:在终端输入 RuiZN run --goal "读取当前目录下的 README.md"

  • 数据流转

    1. cli/main.py 接收到原生命令行参数,argparse 将其解析为字符串 goal

    2. AgentRunner 启动,生成全局唯一的 run_id(如 20260722-182000-a1b2c3),并创建 ExecutionContext,将 goal 写入上下文作为初始目标。

    3. 建立订阅网络AgentRunner 将负责终端 UI 的 StdoutPrinter 和负责写日志的 EventWriter 绑定到 EventBus 上。

    4. 发布起点事件EventBus 广播 RunStartedEventEventWriter 收到后立刻在 events.jsonl 中追加写入第一行 JSON 数据并 flush 刷盘。

2️⃣ 第一次 Loop:发送 Context 给 LLM (Plan 阶段)

  • 数据流转

    1. AgentLoop 读取当前 ExecutionContext 中的 messages(此时包含系统 prompt 和用户的 goal)。

    2. 构造 API 请求AnthropicProviderToolRegistry 获取所有工具的 Schema(如 ReadFileTool 的输入参数结构),并向 system prompt 和工具列表末尾注入 "cache_control": {"type": "ephemeral"} 标记。

    3. 发起 HTTP/gRPC 流式请求:数据发送给 Anthropic Claude API。

    4. 流式 Token 处理

      • API 逐字返回文本 Chunk,AnthropicProvider 捕获到 Chunk 后,向 EventBus 发布 LlmTokenEvent

      • StdoutPrinter 收到 LlmTokenEvent,调用 print(token, end="", flush=True) 在终端呈现打字机效果,并将内部标志位 _inline 置为 True(表示当前处于未换行的流式输出状态)。

3️⃣ LLM 决策使用工具 (Observe 阶段)

  • 数据流转

    1. API 响应接收完毕,LLM 判断需要调用工具,返回响应:

      • stop_reason: "tool_use"

      • content: 包含 ToolCallBlock(id="call_123", name="read_file", input={"path": "README.md"})

    2. 解析与入栈AnthropicProvider 将其包装为 LlmResponse 数据对象并返回给 AgentLoop

    3. AgentLoop 将 LLM 的这条带有 tool_useassistant 消息完整追加到 ExecutionContext.messages 中,作为对后续工具调用的上下文约束。

4️⃣ 安全调度与工具执行 (Act & Result 阶段)

  • 数据流转

    1. 响应格式化AgentLoop 发现 LLM 的返回中包含 tool_calls,发起 invoke_tool() 调用。

    2. 发布启动事件:向 EventBus 发布 ToolCallStartedEvent

      • StdoutPrinter 收到事件,检查到 _inline == True,先调用 _ensure_newline() 补打一个 \n 换行,然后再打印 [tool] read_file {"path": "README.md"},避免日志与流式 Token 粘在一起。

    3. 安全拦截与执行(以 ReadFileTool 为例)

      • 路由查找ToolRegistry 查找是否存在名为 read_file 的工具。

      • 必填校验:校验 path 参数是否存在。

      • 安全防线 1(路径检查):检查 path 中是否包含 ".."。若包含,直接抛出 PermissionError

      • 安全防线 2(超时控制):通过 asyncio.wait_for(..., timeout=10.0) 执行异步读取;

      • 安全防线 3(内存防爆):读取文件二进制流,若超过 512KB,截断前面部分并追加 \n[truncated]

    4. 封装结果

      • 若成功:返回 ToolResult(content="文件内容...", is_error=False)

      • 若报错(例如文件不存在或越界):被 invoke_tool() 内部的 try...except 捕获,不让异常抛出崩溃,而是转换为 ToolResult(content="PermissionError: ...", is_error=True)

    5. 写回上下文AgentLoopToolResult 包装成 user 角色的 tool_result 格式,追加回 ExecutionContext.messages(如果一轮中有多个工具调用,ExecutionContext 内部会自动进行数据合并)。

5️⃣ 第二次 Loop 与优雅收尾 (Final Step & Termination)

  • 数据流转

    1. 再次发起 API 请求AgentLoop 带有最新的 messages(包含上一步读取到的文件内容/错误信息)再次调用 AnthropicProvider

    2. 缓存命中:因为头部 Prompt 和 Tools 未变,Anthropic 服务端直接命中 Prompt Caching,响应速度大幅提升。

    3. 生成最终回答:LLM 结合文件内容生成总结文本,通过流式 Token 实时打字呈现在终端。

    4. 检测终止标志:本次 API 返回的 stop_reason == "end_turn",且没有新的 tool_callsAgentLoop 识别到任务完成,退出 while 循环,更新 context.status = "success"

    5. 生命周期闭环 (AgentRunner)

      • AgentRunner 捕获到 Loop 结束,向 EventBus 发布 RunFinishedEvent

      • StdoutPrinter 打印最终统计日志(如 [run] success 2 steps 1.5s)。

      • EventWriter 写入最后一条 JSONL 日志,在 async with 上下文退出时安全关闭 events.jsonl 文件句柄。

      • 整个进程以 Exit Code 0 干净退出。

核心组件与名称含义全解析

1. 入口与生命周期管理层 (CLI & Lifecycle)

  • RuiZN

    • 含义与职责:本 AI Agent 框架的 CLI 命令行工具名称。

  • main.py / commands.py

    • 含义与职责:CLI 命令入口。解析参数(如 --goal),捕获系统级信号(如 UNIX SIGINT / KeyboardInterrupt),并驱动异步主协程启动。

  • AgentRunner (运行组装车间)

    • 含义与职责:Agent 的“工厂与收尾车间”。

    • 干什么的

      1. 生成本次调用的唯一编号 run_id(如 20260511-161020-abc123)。

      2. 实例化并组装所有零散组件(EventBus, ExecutionContext, Provider, Registry)。

      3. 注册订阅者(StdoutPrinterEventWriter)。

      4. 负责安全收尾:无论 Agent 是成功退出、超步数崩溃还是被 Ctrl+C 中断,都保证发布 RunFinishedEvent,并在安全关闭日志文件后再重新抛出 CancelledError

2. 状态与内存管理层 (Context & Events)

  • ExecutionContext (工作记忆与状态机)

    • 含义与职责:Agent 的“大脑内存卡”与“运行状态追踪器”。

    • 干什么的:存储当前任务的 goalrun_id、当前步数 step、终止状态 status 以及核心的对话历史 messages

    • 关键细节:封装了 Anthropic API 的消息合并逻辑(同一轮次中的多个 tool_result 必须合并进同一条 user 消息中)。

  • EventBus (事件总线)

    • 含义与职责:解耦的“内部广播中心”。

    • 干什么的:维护订阅者列表 _subscribers。当 Loop、Tool 或 Provider 发生关键动作时发布事件(如 Token 生成、工具启动、运行完成),总线按顺序并发通知所有订阅者。

  • EventWriter (日志写入器)

    • 含义与职责:持久化“黑匣子”日志记录员。

    • 干什么的:订阅 EventBus,每收到一个事件就将其序列化为 JSON 并立刻写入 events.jsonl 文件(无缓冲区打折,强制 flush),保证进程突发崩溃时日志不丢失。

  • StdoutPrinter (终端输出格式化器)

    • 含义与职责:终端 UI 渲染控制者。

    • 干什么的:订阅 EventBus,将事件转化为终端看得懂的打印输出。

    • 关键细节:维护 _inline 标志位。当 LLM 处于流式打字机输出状态(未换行)时突然收到工具调用通知,_ensure_newline() 会先自动补全一个换行,避免输出混成一团。

3. 大模型与通信层 (LLM Provider)

  • AnthropicProvider (模型适配器)

    • 含义与职责:与 Anthropic (Claude) API 通信的底层驱动。

    • 干什么的:封装流式请求(Streaming),将 API 返回的文本片段实时转化为 LlmTokenEvent 抛给 EventBus;同时负责将本地 ToolRegistry 的工具定义转为 API 格式。

  • Prompt Caching (提示词缓存机制)

    • 含义与职责:API 成本与性能优化手段。

    • 干什么的:在 system prompt 和 tools 列表末尾加上 cache_control: {"type": "ephemeral"} 标记,让后续轮次的重复上下文命中服务端缓存,降低 90% 的 Token 费用并加快响应。

4. 主循环控制器 (Control Loop)

  • AgentLoop (主循环状态机)

    • 含义与职责:Agent 的“核心发动机/调度控制器”。

    • 干什么的:驱动 Observe ──► Act 状态循环。按顺序完成:调用 LLM 决策 $\rightarrow$ 记录 LLM 回复到上下文 $\rightarrow$ 执行工具 $\rightarrow$ 记录工具返回结果 $\rightarrow$ 检查终止条件(如 end_turn 或达到 max_steps)。

5. 工具系统 (Tool System)

  • BaseTool (工具基类/模板)

    • 含义与职责:所有工具必须遵循的抽象接口规范(继承自 abc.ABC)。

    • 干什么的:定义工具的元数据(name, description, input_schema),并强制实现 async def invoke() 方法。

  • ToolResult (工具返回数据结构)

    • 含义与职责:工具执行结果的标准数据包(dataclass)。

    • 核心字段

      • content: str:给 LLM 看的工具输出内容。

      • is_error: bool:标记工具执行是否出错(即使出错也不抛出 Python 异常,而是作为结果返回)。

      • error_type: str | None:错误类型标记(如 timeout, permission_error, runtime_error)。

  • ToolRegistry (工具注册表)

    • 含义与职责:工具的“仓库管理者”。

    • 干什么的:维护工具字典 _tools。提供 tool_schemas() 方法直接导出适配 Anthropic API 的 tools 格式,供 LLM 了解当前可用的工具列表。

  • invoke_tool() (安全执行包装器)

    • 含义与职责:工具调用的“安全隔离舱/调度员”。

    • 干什么的

      1. 查找与校验:检查工具是否存在、必填参数(required)是否缺失。

      2. 超时控制:使用 asyncio.wait_for(..., timeout=10.0) 防死锁。

      3. 异常捕获与 _fail() 兜底:捕获所有运行时报错与超时,不让异常冒泡到 AgentLoop,统一转为带 is_error=TrueToolResult

  • ReadFileTool (内置读取文件工具)

    • 含义与职责:S1 阶段内置的具体工具示例。

    • 内部三层安全边界

      1. 防路径穿越:若路径包含 ".." 则抛出 PermissionError,禁止读取上层路径。

      2. 防内存/Token 溢出:文件超过 512KB 时自动截断,并在末尾追加 \n[truncated] 告知 LLM。

      3. 错误转化:触发任何错误后由 invoke_tool() 捕获并转为错误结果给 LLM,触发 LLM 的自我纠错机制。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐