上线

专栏:Agent 工程 · 第 15 / 18 篇
Agent生产化可观测性

专栏最后一篇。前面十四篇的产出拼起来已经是一个完整的 agent;这篇讲让它敢上线的三件事:看得见(可观测性)、算得清(成本预算)、放得稳(渐进式放权)。两个解剖对象的上线形态就是现成的蓝图。

:::info 学习目标 完成本篇后你能够:为 agent 补齐轨迹/token/生命周期三类日志与 headless 入口;建立步数与 token 双预算;制定一份按周推进的放权计划。 前置:第 4~14 篇全部完成。预计时长:90 分钟。 :::

:::note 本章术语速查(新手建议先读)

  • 可观测性(Observability):出问题时能回答”它当时看到了什么、想了什么、做了什么”。
  • Headless(无头模式):不启动界面,命令行一次性执行任务并输出结果——方便脚本和定时任务调用。
  • 退出码:程序结束时留给脚本的数字信号(0=成功)。headless agent 用它表达任务成败。
  • 渐进式放权:上线初期权限最严,随着审计数据证明可靠再逐步放宽。 :::

一、可观测性:每一次决策都可回放

上线第一天就会学到:用户报”它做错了”时,你需要还原模型当时看了什么、想了什么、做了什么。答案还是那件老事——仅追加的会话日志,但上线的日志要多记三类:

  1. 轨迹(trajectory):每步的工具调用序列、参数摘要、结果摘要、耗时。第 13 篇评测时的轨迹记录直接复用;
  2. token 计量:每步的用量与累计——Codex 的 TokenUsageRecord 落 rollout、dsh 的 usage 嵌进 assistant/message,都是为了让”这次任务花了多少钱”可以逐轮次回答;
  3. 生命周期事件:轮次开始/结束及原因(completed/aborted/error/max-tokens)、压缩发生、审批决定。排障时这些边界事件比消息本身更有用。

如果做的是服务化部署,把轨迹导出到标准遥测栈(OpenTelemetry)——dsh 内建了 session-telemetry-otel(且用 DSH_TELEMETRY_DISABLED 一键关掉,遥测默认尊重用户);Codex 每个采样请求包着 tracing span(trace_span!("stream_request")),掉进任何 tracing 后端都能看。

部署形态也是可观测性的一部分。两个系统的三件套可以直接抄:TUI/GUI(交互)、headless(一次性任务,退出码即成败)、SDK/服务接口(程序化集成)。给 mini-agent 补上 headless 入口:agent-run "任务" + 退出码 + stdout 只出最终答案——CI 和 cron 从此能用。

二、成本预算:给每次任务立规矩

上线的第二个问题是”这个任务要花多少钱”。三层控制,从粗到细:

  1. 步数上限:第 4 篇就有的 max_steps——最粗但最有效的保险丝;
  2. token 预算:累计用量超阈值就收尾。Codex 做得更细:token 预算耗尽时触发预算型压缩(跳过总结、直接换窗口),任务不被中断而是”续命”;get_context_remaining 让模型自己知道预算余量;
  3. 模型分级:简单步骤用便宜模型(摘要、改写),关键决策用强模型。dsh 的多适配器架构天然支持(不同步骤绑不同 provider/model)。

记一本账:按任务聚合的 token/成本报表。上线两周后你会拿着它做架构决策——哪些工具的结果该截断、哪些步骤该换小模型。

三、渐进式放权:信任是用出来的

安全篇(第 12 篇)装的三层防线,上线时按信任增长逐步放宽:

图表(ship-your-agent.md)

放权的依据是第 12 篇的审计数据(哪些操作从未被拒、哪些命令反复人工放行),不是胆量。Codex 的默认 read-only + on-request、dsh 的默认 workspace-write + ask 都验证了同一节奏:从最严开始,逐步放宽never/danger-full-access 留给 CI 等隔离环境,交互场景别去。

Codex 的默认 read-only + on-request、dsh 的默认 workspace-write + ask 都验证了同一节奏:从最严开始,用审计记录(第 12 篇的结构化审批事件)证明哪些操作可以免审——放权的依据是数据,不是胆量。never/danger-full-access 留给 CI 等隔离环境,交互场景别去。

动手:headless 入口(20 行)

# agent_run.py —— 给 CI / cron 用的无头入口
import sys, json
from mini_agent import run

def main():
    task = " ".join(sys.argv[1:])
    if not task.strip():
        print("usage: agent_run.py <task>", file=sys.stderr); sys.exit(2)
    answer = run(task, max_steps=25)
    print(answer)                                   # stdout 只出最终答案
    sys.exit(0 if "未确认完成" not in answer else 1)  # 退出码即成败

if __name__ == "__main__":
    main()

验收:python agent_run.py "统计代码行数" 的退出码为 0 且 stdout 不含中间步骤;任务未完成时退出码为 1。对照 Codex 的 codex exec——语义完全一致。

上线检查清单

  • 轨迹、token 计量、生命周期事件全部落日志
  • headless 入口 + 退出码语义(completed→0,否则非 0)
  • 步数上限 + token 预算双保险
  • 沙箱默认 read-only,审批默认 ask
  • 审批事件结构化、可回放
  • 评测集接进 CI,改动必跑
  • 有一键关闭遥测的开关(尊重用户)

专栏收束

十五篇走完,回头看开篇那张循环图:模型 + 工具 + 循环 + 终止条件,50 行。而两个生产级系统用 10 万行量级告诉你,剩下的是什么——会话溯源、上下文经济、压缩与记忆、权限沙箱、评测与渐进放权。这些全是”模型之外”的可靠性工程,且彼此独立团队得出同一批答案(第 18 篇的十条共识)。

番外的源码对照(Codex 架构工具与沙箱十条共识)与 DeepSeek Harness 专栏的 14 篇逐行解读,是这条路的下一步。祝你的 agent 顺利上线。

← 返回文章列表