生产化 · 后端、可观测性、成本与安全

Agent; 可观测性; 成本控制; 安全; 生产化 2217 words 12 min read
This post is not yet available in English. Showing the original.

前面十二篇讲的都是”Agent 怎么工作”——循环、工具、记忆、编排、Harness。这一篇讲一件不一样的事:当这个 Agent 要放到生产里、要对真实用户负责、要有人半夜被它的告警叫醒时,还需要什么。

这些东西在 demo 里都不重要,在生产里全都是生死线。我把它们收在一篇里,因为它们有一个共同点:都是”Agent 之外”的工程,但决定了 Agent 能不能活下来。

本文主要参考 agentic 课程 Ch.15-18(后端 / 可观测性 / 成本 / 安全),并对照 agent开发 系列对 16 个开源项目安全与执行层的横评。

一、后端:Agent 跑在哪里

一个交互式 CLI Agent 跑在你的终端里,进程就是全部。但一个要服务多用户、要长期运行、要能重启恢复的 Agent,需要真正的后端架构。核心是三个决策:

存储选型。小规模单用户用 SQLite 就够——agent开发 里 Goose 就是 SQLite(还做到了 V1→V11 的 schema 自动迁移)。多租户、要横向扩展就上 Postgres。审计日志(Ch.05 的 append-only 那一份)追加写、永不改;可查询的召回走索引。

执行后端。Agent 的工具(尤其是 run_shellcode_run)在哪里执行?agent开发 里 Hermes 提供了六种执行后端(local / docker / model / managed_model / ssh / singularity),一行配置切换——local 用于开发,docker 用于隔离,ssh 用于远程,singularity 用于 HPC 集群。这个抽象层的价值是:Agent 的推理核心不需要知道自己的手伸在哪台机器上。

多入口共享核心。同一个 Agent 内核,可能同时服务交互式 REPL、SDK 调用、Web 请求、定时任务。好的架构让这些入口共享同一条经过验证的核心路径(这正是 Claude Code QueryEngine 的设计),而不是每个入口一套逻辑。

二、可观测性:让失败可见

Agent 极难从日志调试。 “Agent 卡住了""它理解错了需求”——这些话对修 bug 毫无帮助。你需要的是一棵 trace 树:哪次模型调用触发了哪次工具调用、哪个工具结果改变了下一轮的 prompt、花了多少 token、延迟在哪、为什么停。

四根支柱

经典的可观测性讲三根支柱:trace、metric、log。对 Agent 来说要加第四根——eval(评估),因为”Agent 有没有做对事”这个问题,光看延迟和 token 是答不出来的。

支柱回答的问题量级形态
Traces这一次运行发生了什么?每次运行一棵span 树
Metrics所有运行整体在发生什么?连续时序
Logs系统在某个时刻说了什么?结构化行
EvalsAgent 有没有产出正确结果?抽样通过/失败 + 分数

trace 树以「运行」为单位

一次 run 是根 span,往下每一步是子 span:agent.runagent.step(第 N 轮)→ model.call(带 input/output token)+ tool.call(带工具名和参数)。当出问题时,你打开这棵树,就能看到 prompt 怎么拼的、召回了什么记忆、工具参数是什么、输出多大、为什么停。

用 OpenTelemetry 的 GenAI 约定

OpenTelemetry 的 GenAI 语义约定是目前最接近”标准”的 Agent 遥测规范。虽然很多字段还在 Development 稳定级别(意思是”字段名可能改”),但形态已经稳定到值得现在就采用、以后再迁移。关键字段:

  • gen_ai.request.model / gen_ai.response.model——请求的模型 vs 实际服务的模型(fallback 时会不同)
  • gen_ai.usage.input_tokens / output_tokens——计费 token
  • gen_ai.usage.cache_read_input_tokens / cache_creation_input_tokens——缓存命中 vs 写入(对应 [[04-提示词上下文与缓存]])
  • gen_ai.response.finish_reasons——end_turn / tool_use / max_tokens(对应 [[02-对话循环与最难的停]] 的停止原因)
  • gen_ai.tool.name——模型调用的工具

每一章都埋了一个指标

这一层最妙的地方:前面每一章都埋了一个依赖这一层的指标。缓存命中率(Ch.04)、压缩方法直方图(Ch.05)、召回触及率(Ch.06)、curator 动作直方图(Ch.07)、run-state 转移计数(Ch.08)、replan 率(Ch.09)、子代理成功率(Ch.10)、审批漏斗(Ch.12)、成本账本(Ch.15)。可观测性这一层,就是把这些散落的信号收拢成一个共享的形状——收集、关联、可查询。

一个立刻能上的手段:给渲染后的 prompt 前缀记一个 SHA 指纹([[04-提示词上下文与缓存]] 提过),每轮记录,一旦”什么都没改但指纹变了”,就是缓存泄漏。

三、成本与延迟:模型策略

Agent 的成本不是单次调用,而是长会话累积。控制成本的杠杆按性价比排序:

  1. 缓存对齐(Ch.04)——最便宜。前缀字节稳定,cache read 通常只要 cache write 的约 10% 价格。fleet 规模下这是几个零的差距。
  2. 上下文压缩(Ch.05)——免费手段(裁剪/去重)优先,LLM 摘要垫后。
  3. 模型路由——便宜模型做窄任务(压缩摘要、探索搜索),贵模型做深推理。vibecoding/11 里提到的”haiku 规划、sonnet 执行、opus 复核”就是这个思路。
  4. 预算上限——token/成本超阈值就停,返回已产出的部分并标记为 partial(对应 [[02-对话循环与最难的停]] 的成本上限停止条件)。

延迟侧最大的杠杆是并行([[09-多智能体编排-谁决定并行度]])和流式输出——让用户实时看到进度,而不是干等一整轮结束。

四、安全:两条相反的路线

Agent 安全不是加个 if 判断就完事。agent开发 系列横评了 16 个项目后,提炼出两条互补的路线

路线一:主动防御(以 Goose 为代表)

每次工具调用都过一条五层检查链,针对的威胁是”恶意内容注入 Agent”(比如用户让 Agent 读一个网页,网页里藏了 prompt injection):

  • 静态命令检测——八大威胁类别,拦截 rm -rf 这类危险命令
  • 出网检测(Egress Inspector)——防数据外泄
  • LLM 审查(Adversary Inspector,可选)——用 LLM 审 LLM
  • 循环检测(Repetition Inspector)——对应 [[02-对话循环与最难的停]] 的 doom-loop
  • 四种权限模式(Auto / Approve / Smart / Chat)

注意 Goose 的 Adversary Inspector(LLM 审查 LLM)有个弱点:审查者和被审查者共享同样的盲区,且存在 Fail Open 风险(审查失败时默认放行)。这是”代码层安全”的天然局限。

路线二:被动隔离(以 Nano Cloud 为代表)

不试图检测每个危险动作,而是从架构上让危险动作无处可去,针对的威胁是”Agent 本身成为攻击者”:

  • 容器隔离——内核级文件系统隔离,Agent 再想删库也只能删容器里的
  • 零信任凭证注入——API Key 通过宿主机的代理注入,容器内的 Agent 永远看不到密钥。这是架构层解决,不依赖代码正确性

关键结论

架构层安全(Nano Cloud)是基础,代码层安全(Goose)是补充——两者互补,不是二选一。

这也呼应了 [[12-Skills子代理与行为塑造]] 里 Superpowers 的发现:行为塑造(让 AI 遵守规则)不是技术安全——它能提高合规率,但一个真正的攻击者不会被 prompt 里的”请不要”拦住。技术安全必须落在权限、沙箱、隔离这些确定性机制上。

fail-closed:贯穿一切的默认值

agent开发 和 Claude Code vs Codex 的对比都指向同一条铁律([[07-状态持久化与中断恢复]] 也提过):默认值必须保守。新增能力时如果默认偏激进,迟早有一个早晨你醒来发现昨夜烧了几十万次 API 调用,或者 Agent 删了不该删的东西。SandboxPolicy::ReadOnlysafeParse 失败默认不并发、权限默认 ask——每一处默认值都应该在”忘了显式声明”时导向更安全而非更危险的行为。

小结

生产化的四件事——后端、可观测性、成本、安全——有一个统一的精神:把不变量从”希望模型不犯错”挪到”系统结构上不可能犯错”。 可观测性让失败可见,成本控制让长会话可持续,安全的两条路线让”Agent 出错”的后果被物理地框住。

这也是整个 Agent 系统设计反复出现的主题:[[10-AgentHarness-把一切装起来]] 承担不变量,模型承担决策。生产化,就是把这条原则贯彻到运维层。


本文参考:agentic 课程 Ch.15 后端基础设施 / Ch.16 可观测性 / Ch.17 成本延迟与模型策略 / Ch.18 安全与对抗输入;agent开发《项目差异对比总览》维度 6 安全、维度 8 执行层;《7 安全与权限模型》。