发布于 

业务Agent该怎么设计?

本文为 Anthropic 原文的阅读笔记。

原文:The anatomy of effective commerce agents

背景:Anthropic 与零售、旅行、票务、电信等企业合作落地商业业务 Agent 的经验。

1. 架构

图 1

1.1. 单 Agent 优先

一个主模型在标准 Agent Loop 中持续:理解目标 → 获取上下文 → 调工具 → 观察结果 → 澄清 → 继续行动。Anthropic 认为,传统的 Multi-Agent 架构(orchestrator + subagent)有几个劣势:

  1. 每次委派都会损失状态、增加 token 和秒级延迟。
  2. 业务域是分不清楚的,某一个 subagent 所需要的输入/上下文,可能是另外一个 subagent 的输出,subagent 之间也有重合。
  3. LLM 是越来越聪明的,要面向未来设计。

替代方案是 Agent Skills,把分领域的指令包成 Skill,按需加载进已经掌握全部历史的主代理。那什么情况还是适合 Subagent 的方式呢?

  1. 深度研究、代码执行等边界清晰、可压缩成一个结果的任务。
  2. 药品、金融等拥有独立合规体系,需要真正把对话控制权移交出去的场景。

1.2. System Prompt 和 Skill 的划分

图 2 如果是单 Agent 的话,我们该怎么划分什么信息该放在 System Prompt,什么该放在 Skill 里呢?Anthropic 的答案是:按照频率来。

  • 约三分之一以上流量都会用到的指令,放 System Prompt。
  • 长尾能力:放 Skill。
  • 安全、法律、品牌规范、过敏信息等关键约束:无论频率如何都放 System Prompt。
  • 如果能根据入口页面提前判断需要哪个 Skill,就由框架预加载,避免多消耗一次模型轮次。

本质是,利用业务逻辑来优化 Agent Skill loading 策略。

1.3. Tool

1.3.1. Tool 不应该重写业务逻辑

业务逻辑(商品排序、库存、促销、履约、支付等逻辑)应继续由原有系统负责。Agent Tool 只是这些系统的接口。Tool 返回值也是模型上下文,因此要:

  • 只保留推理需要的字段。
  • 删除无关的大字段。
  • 把错误码转成可行动的提示。
  • 避免让 Tool 本身逐渐堆积大量业务规则。

1.3.2. UI 组件搞成 Tool

图 3 不要让模型输出自定义 XML/标签再由前端解析。商品卡片、行程单、套餐对比、座位图等都应该是有类型约束的展示 Tool,例如:

present_products(...)

这样展示结构天然进入消息历史,用户之后说“左边第三个酒店”时,模型知道屏幕上的真实布局。

2. 优化

2.1. 减少真实任务延迟

任务完成延迟概括为:总延迟 = Σ(每轮模型生成时间 + Tool 执行时间)。

因此有三个杠杆:

  • 减少轮数:
  • 预加载页面上下文。
  • 提高模型能力:更聪明但单轮更慢的模型,有时反而拥有更低的总延迟,因为它规划更好、调用轮数更少。
  • 并行调用独立工具。
  • 加速 Tool:
  • 优化后端接口。
  • 在参数生成完成后立即执行:单个工具调用的参数已经完整,但模型还在继续生成后续工具调用或文本时,框架就可以先执行这个工具。
  • 也可以要求模型“最慢的 Tool 先输出”,这样减少整体时长。
  • 加速生成:通过 Eval 能力来选择与平衡速度和效果。

2.2. 感知延迟优化

在总耗时相同的情况下:

  • Tool 参数一边生成,前端一边渐进渲染组件。
  • 工具执行期间展示“正在查找临水酒店”之类的进度信息。

这样用户看到的是推进过程,而不是五秒钟的加载动画。

2.3. Prompt caching 优化

图 4 推荐的上下文顺序是:

Global:全局稳定内容
Session:用户/会话内容
Volatile:当前时间、页面等易变内容

图 5 缓存是前缀匹配的。把时间戳放在 System Prompt 顶部,会导致后面的缓存全部失效。Anthropic 称其见到的优秀电商 Agent 可以达到 90%–99% 缓存命中率。

2.4. 模型选择

更大的模型:更好的理解、规划和工具调用,更高单 token 成本;生成可能更慢。

更高的 effort:更充分的推理和检查;更多推理时间和 token。

更小模型/低 effort:单次调用更快、更便宜;可能多走几轮、出错或任务失败。

2.4.1. 明确目标

先定义究竟要优化什么,以及不可突破的底线。例如购物 Agent 可以定义:

  • 任务完成率 ≥ 92%。
  • 商品信息有据可查率 ≥ 99%。
  • 推荐相关性 ≥ 4.2/5。
  • p50 总延迟 ≤ 4 秒(代表普通用户体验)。
  • p99 总延迟 ≤ 15 秒(代表最慢的那部分用户体验)。
  • 每个成功任务成本 ≤ 0.08 美元。

2.4.2. Sweep

其实就是模型 + effort,排列组合测试,比如:

Sonnet + low effort
Sonnet + medium effort
Sonnet + high effort
Opus + low effort
Opus + medium effort
Opus + high effort

测试样本要尽量对准线上流量分布,比如:

60% 简单商品查询;
25% 多条件推荐;
10% 售后处理;
5% 复杂购物规划。

不同模型对于不同 Prompt 的适配程度是不一样的,所以如果 prompt 不变的话,其实测的是模型能力 + Prompt 与该模型的适配程度。

Anthropic 建议流程是这样:

  1. 先用相同基线 Prompt 跑 Sweep。
  2. 查看每个候选模型的失败案例。
  3. 针对明显的 Prompt 不适配做几轮有限迭代。
  4. 再进行比较。
  5. 记录每个模型使用的 Prompt 版本。

否则很容易因为一个为 Sonnet 长期调优的 Prompt,对 Opus 或更小模型作出不公平判断。

2.4.3. 最终选择

选择分数高的,但是如果有分数接近的,选能力更强的配置。原因:

  1. 更好的复杂请求覆盖。
  2. 更低的长尾失败率。
  3. 给未来新增功能留下能力余量。
  4. 更少的 Prompt 特例和补丁。
  5. 更好的用户采用率、复用率和留存。

整体流程:

定义业务指标和硬底线
↓
用真实流量构成建立 Eval
↓
Sweep 模型 × effort
↓
分析各配置失败案例
↓
有限度地适配各自 Prompt
↓
重新测质量、任务总延迟、成功任务成本
↓
剔除不满足硬底线的配置
↓
在剩余配置中选择最佳性价比

3. 产品化

3.1. 记忆设计

3.1.1. 记忆不是完整聊天记录,是结构化事实

Anthropic 不建议把所有内容长期放在一份 Markdown 用户画像里。小规模时这样简单,但生产系统通常会遇到:

  1. 用户事实越来越多。
  2. 需要按字段查询。
  3. 其他业务系统也需要读取。
  4. 某些字段要触发确定性规则。
  5. 要支持权限、修改、删除和保留期限。
  6. 要与已有用户、门店和账号数据关联。

因此,最终应该使用业务数据库,把每条记忆保存为小型、带类型、带来源的事实记录。

3.1.2. 记忆治理

  1. 建立允许保存的记忆类型,并在写入路径用代码校验,比如:
ALLOWED_MEMORY_TYPES = {
  "shoe_size",
  "default_store",
  "dietary_constraint",
  "fulfillment_preference",
  "preferred_report_metrics",
}
  1. 建议记忆必须进入数据权利流程,用户能看到系统记住了什么,也可以改正错误事实。
  2. 偏好会过期,几年前的鞋码、地址或常用门店可能已经失效,因此要设置更新/失效策略。

3.1.3. 记忆写入

做成异步的,比如一个工具 save_memory() 让 Agent 调用(依赖 Agent 的推理能力,可能还需要给 Agent 一个 tool output),或者固定时机保存记忆(每轮对话结束)。

并且,记忆保存工具只能读用户和助手文本,避免把 tool_result,比如商品描述,错误地存成用户偏好,更安全。 图 6

3.1.4. 记忆读取

根据频率分层,通常为 3 层:

  1. 每轮固定携带:适合几乎所有请求都会使用的小量事实,比如默认门店、默认配送方式、关键安全约束。
  2. 根据当前请求预取:根据当前页面、请求类型或预加载的 Skill,提前查询相关事实,比如:
用户搜索鞋子
→ 预取鞋码、常购品牌、宽脚偏好
  1. 通过 Tool 按需查找:低频、数量较多、当前是否需要无法提前判断的事实,通过 lookup_memory() 工具实现。

3.2. 安全设计

Prompt 负责表达规则,Harness 负责强制规则。

3.2.1. 关键动作,模型不能直接提交

比如广告的下单,Agent 最好从根本上不要有这个工具,而是让用户点击按钮来调用后端接口。

3.2.2. 通过 harness 来维护一个可访问资源

Harness 维护一个本会话允许访问的 ID 集合:

allowed_product_ids
allowed_order_ids
allowed_campaign_ids
allowed_change_ids

写操作和展示操作只接受这些 ID。

3.2.3. UI 展示也只接收 ID

展示工具不应该让模型直接传完整的商品或订单对象,因为可能会有幻觉。

bad case:
{
  "name": "某商品",
  "price": "1 元",
  "availability": "现货"
}

good case:
{
  "product_ids": ["p_123", "p_456"]
}

然后服务器自行补全。

3.2.4. 第三方信息消毒

如果要用到外部信息(评论、弹幕、商品描述、竞品网页等),需要对内容进行消毒(Sanitize),防止提示词注入攻击:

移除控制字符;
移除双向文本控制字符;
破坏伪造的消息角色和 Tool Call 格式;
防止伪造系统所使用的内容边界标记;
限制最大长度;
使用固定标签和 fence 包裹。

3.3. 评估

3.3.1. 主要评估结果,不要过度锁死调用路径

因为多个路径都可能得到正确结果。严格限制路径会导致:

  • 测试非常脆弱。
  • 模型升级后无意义失败。
  • 阻止更高效的新策略。
  • 团队开始为了通过测试而过度提示模型。

3.3.2. 不推荐用模拟用户作为主要度量

Anthropic 认为主要有几个原因:

  • 用户模型是随机的。
  • 被测 Agent 也是随机的。
  • Judge 仍然是随机的。
  • 需要更大样本才能稳定。
  • 失败时不容易定位是谁造成的。
  • 成本高、运行慢。

它适合:

  • 探索未知失败。
  • 发现 Eval 覆盖盲区。
  • 做总体体验检查。

3.3.3. 正例 + 负例

Anthropic 认为,每个 should serve 都有 should refuse,每个 should ask 都有 should just do it,否则 Agent 很容易通过一种“过度保守策略”取得虚假的高分:遇到任何情况都追问或拒绝。

positive:
用户要求退款,符合条件 → 应该暂存退款

negative:
不符合条件 → 应该拒绝
缺少订单 → 应该追问
已有足够信息 → 不应该多余追问

4. 组织协作

业务 Agent 通常会涉及多个团队一起开发,每个团队都有可能改其中的组件,Agent 没有传统微服务那么强的模块隔离。所有内容最终进入同一个上下文窗口,影响同一个模型决策。Anthropic 不建议做 subagent 来隔离,原因如上。所以通过以下方式来解决。

4.1. 所有权跟随业务系统

每个 Tool 和 Skill 必须有唯一 owner,例如:

定价团队:
pricing-promotions Skill
promotion tools

客服团队:
customer-care Skill
order/return tools

库存团队:
inventory-operations Skill
inventory tools

共享 System Prompt 则分层管理:

  • 通用部分由 Agent 平台团队统一拥有。
  • 领域段落由对应领域团队负责。
  • 最终仍要有一个平台级 owner 对整体负责。

重点是避免:

  • 多个团队都能随意修改同一个 Skill。
  • Tool 出问题时找不到负责人。
  • Prompt 成为没有所有者的公共文档。
  • 每个团队只对局部分数负责,不对整体 Agent 负责。

4.2. 每个变更必须带 Eval Case

团队提交新的 Skill 或 Tool 时,不能只交付实现,还要交付:正例、负例、边界案例、交叉案例……

本质是要写好可执行测试。

4.3. Eval 每次只跑影响范围

完整的很慢很贵、有随机性。只跑部分案例,例如:

  1. 修改 Skill:Skill 自身案例 + 相邻 Skill 的交叉案例。
  2. 修改 Tool:所有会调用该 Tool 的案例。
  3. 修改展示组件:相关 UI 和引用位置案例。
  4. 修改共享 System Prompt:完整 Eval。
  5. 修改安全框架:全部安全、写入、权限、注入案例。

5. 总结

四部分如何形成闭环:

用户请求
│
主 Agent 进行判断
│
┌───────────────┼────────────────┐
│               │                │
Memory 提供     Tools 连接业务    Skills 提供流程
跨会话上下文     系统能力          知识
│               │                │
└───────────────┼────────────────┘
                │
Harness 强制执行
权限、ID、限额、审批、串行化
│
产生最终业务状态
│
Evals 验证结果和边界
│
CI、Canary、开关控制发布
│
生产事故沉淀为新 Eval

每层解决不同问题:

负责什么 不应该负责什么
模型 理解、判断、规划、选择 最终授权和强制安全
Memory 保存可复用的用户事实 无限制保存所有聊天
Skill 提供领域流程和程序性知识 绕过后端规则
Tool 连接现有业务能力 重新实现整个业务系统
Harness 权限、校验、审批、不变量 依赖模型自觉遵守
Eval 检测行为和业务结果 只测调用路径
发布流程 控制变更影响面 把 Prompt 当普通文案上线