跳转到内容

架构分层与 run_internal 内部设计

DEV-01: 架构分层与 run_internal 内部设计

学习目标

  • 理解 run.pyrun_internal/ 的分层边界
  • 掌握 run_internal/ 各模块的职责划分
  • 理解添加新工具/输出项类型时的 7 文件联动
  • 掌握 RunState 序列化版本管理机制

项目实践

run.py:精简编排入口

run.py(93KB)仅保留公共流程控制:

  • Runner 类:三个入口方法(run/run_sync/run_streamed
  • AgentRunner 类:主循环编排(初始化 → 循环 → 结果构建)
  • RunConfig:运行时配置(max_turns、guardrails、sandbox 等)
  • 循环内部的 guardrails 调度与 NextStep 分发

所有循环 internals 外包到 run_internal/

run_internal/ 模块职责

模块核心函数职责
run_loop.pyrun_single_turn(), get_new_response()模型调用、工具执行编排、单步结果构建
turn_resolution.pyprocess_model_response(), check_for_final_output_from_tools()模型响应解析、handoff/tool/final-output 判定
tool_execution.py_execute_tool_plan(), _FunctionToolBatchExecutor工具并行执行、故障仲裁、guardrails 执行
tool_planning.py_build_plan_for_fresh_turn(), execute_mcp_approval_requests()工具规划、MCP 审批收集
items.py归一化、去重RunItem 类型转换、审批过滤
session_persistence.pysave_result_to_session(), rewind_session_items()Session 保存/回退
oai_conversation.pyOpenAIServerConversationTracker服务端对话 delta 计算
error_handlers.py_handle_run_error()错误处理分发

7 文件联动:添加新工具类型

添加新的工具/输出项类型时,需要同步更新:

  1. src/agents/items.py — RunItem 类型定义与转换
  2. src/agents/run_internal/run_steps.py — ProcessedResponse 与工具运行结构体
  3. src/agents/run_internal/turn_resolution.py — 模型输出处理与 RunItem 提取
  4. src/agents/run_internal/tool_execution.py — 工具执行
  5. src/agents/run_internal/tool_planning.py — 工具规划
  6. src/agents/run_internal/items.py — 归一化、去重、审批过滤
  7. src/agents/stream_events.py — 流事件名称
  8. src/agents/run_state.py — RunState 序列化/反序列化

为什么需要这么多文件:每个文件负责一个横切面(类型系统、执行、规划、流事件、持久化),新类型需要在每个横切面注册。

RunState 序列化版本管理

RunState 是可序列化的运行快照,支持暂停/恢复(HITL 场景)。

版本管理机制

  • CURRENT_SCHEMA_VERSION = "1.10"
  • SUPPORTED_SCHEMA_VERSIONS:所有历史版本 "1.0" ~ "1.10" 的集合
  • 每个版本有一行摘要在 SCHEMA_VERSION_SUMMARIES
  • 反序列化对不支持的版本直接失败(fail-fast),清晰列出支持的版本
  • 未发布的 schema 版本可在发布前重编号/压缩(中间快照有意不支持)

序列化内容

  • current_turn, current_agent(含重复名称的 BFS 身份解析)
  • original_input, model_responses(含 usage、output、response_id)
  • context(usage、approvals、tool_input、类型往返警告)
  • generated_items, session_items(完整 RunItem 列表)
  • last_processed_response(工具动作、中断、嵌套 agent-as-tool 状态)
  • current_step(待处理工具审批)
  • Guardrail 结果(重新创建返回序列化输出的 stub guardrail 函数)

问题与规避

问题规避方案
修改 RunState 格式后旧版本无法加载更新 CURRENT_SCHEMA_VERSION 并在 SCHEMA_VERSION_SUMMARIES 添加变更说明
Agent 重复名称导致反序列化身份混淆BFS 遍历解析 agent 图,使用稳定身份键
Context 类型在序列化/反序列化中丢失使用 context_override / context_deserializer 优先级恢复

设计取舍

为什么选择 run_internal 分包而非单个巨型文件

将 80KB+ 的循环逻辑拆分为 8 个模块:(1) 每个模块可独立测试;(2) 修改循环 internals 不影响 run.py 的公共 API;(3) 代码导航更清晰。

代价:新工具类型需要跨 7-8 个文件同步修改。SDK 通过清晰的模块边界和命名约定来降低认知负担。

参考来源