会话、追踪与人在环路
本章讲三个横切整个 run 的机制:会话记忆(自动管理多轮历史)、追踪(自动可观测)、人在环路(让工具调用暂停等人类批准再继续)。
4.1 会话(Session):自动记住多轮对话
它要解决的小问题
多轮对话里,你不想每次 Runner.run 都手动把上一轮的全部历史拼进 input。你希望「把这轮的新输入丢进去,SDK 自己接着上次的历史跑,并把这轮产物存回去」。
思路:一个极简的存储协议
Session 是个 Protocol(memory/session.py:14),只要求四个方法:
| 方法 | 干什么 |
|---|---|
get_items(limit) | 取历史 item |
add_items(items) | 追加新 item |
pop_item() | 弹出最后一个(用于回滚/重试) |
clear_session() | 清空 |
就这么薄。任何实现了这四个方法的对象都能当会话用。SDK 内置 SQLiteSession(memory/sqlite_session.py),pyproject.toml 里还有 Redis / SQLAlchemy / MongoDB 等可选实现(pyproject.toml:46-50 的 optional 依赖)。
run 循环怎么用它
传了 session 后,AgentRunner.run 在开头用 prepare_input_with_session(run.py:527、run.py:541)把「会话历史 + 本轮新输入」合并成喂给模型的 input;run 过程中用 save_result_to_session(run.py:751 等多处)把新产物持久化。
注意一个互斥: 会话持久化只在「没用 OpenAI 服务端对话追踪」时启用(run.py:571 的 session_persistence_enabled = session is not None and server_conversation_tracker is None)。如果你用了 conversation_id / previous_response_id(让 OpenAI 服务端管历史),本地 Session 就不再重复存。
4.2 追踪(Tracing):每一步都留痕
它要解决的小问题
agent 跑起来是个黑盒:调了几次模型?每次花多少 token?跑了哪些工具?哪一步交接的?出问题要能回放。
思路:trace + 嵌套 span
SDK 借用分布式追踪的模型:一次 run 是一个 trace,里面嵌套一棵 span 树。你在 01 章的循环里其实已经见过它们:task_span、agent_span、turn_span 在 run.py 里被层层 start(run.py:645、run.py:1045、run.py:1166)。
常见 span 类型(tracing/__init__.py):
| span | 包住什么 |
|---|---|
agent_span | 某个 agent 的整段执行 |
turn_span | 一个回合 |
generation_span / response_span | 一次模型调用 |
function_span | 一次工具调用 |
handoff_span / guardrail_span | 交接 / 护栏 |
上报机制:批量异步导出
默认的处理器是 BatchTraceProcessor(tracing/processors.py:522),默认导出器 BackendSpanExporter(tracing/processors.py:33)会把 span 批量 POST 到 OpenAI 的追踪后端(tracing/processors.py:34 的 _OPENAI_TRACING_INGEST_ENDPOINT = "https://api.openai.com/v1/traces/ingest"),所以你在 OpenAI 控制台能看到可视化的 run。
你可以换处理器(add_trace_processor / set_trace_processors,tracing/__init__.py:46、58)接到自己的可观测系统,或用 set_tracing_disabled / run_config.tracing_disabled 关掉。