最近读完 Anthropic 的《A guide to the anatomy of effective commerce agents》。
这 24 条基本可以当成一份设计检查表。
一、架构:先把 Agent 设计简单
01|让 Agent 专注于决策,不是执行
Agent 的核心价值在于理解目标、权衡信息和做判断,而不是替业务系统重新实现搜索、库存、支付、退款或营销引擎。
确定性的执行交给工具和已有系统,模型负责决定什么时候调用、调用什么,以及如何解释结果。
Agent = 大脑,不是手脚。
02|明确边界,拒绝万能 Agent
一个 Agent 不应该假装自己什么都能处理。它需要清楚知道自己能做什么、不能做什么,以及什么情况必须停止、询问或交给别的系统。
边界越明确,行为越容易评估,出了问题也越容易定位。
03|所有动作都要可追溯
只要 Agent 能影响真实业务,就应该留下结构化证据:调用了哪个工具、使用了什么参数、返回了什么状态、谁批准了最终动作。
不要把关键行为藏在一段自然语言里。能审计,才有资格进入生产环境。
04|默认先用一个主 Agent,不要先上意图路由
真实对话通常跨越多个意图。用户可能先比较商品,再问库存,再调整购物车,最后讨论配送。
如果一开始就把对话拆给不同领域 Agent,每次交接都会损失上下文,还会增加延迟和 Token 消耗。一个拥有完整会话上下文的主 Agent,往往更稳定。
05|长尾能力优先用 Skills,而不是 Subagents
Skills 能给同一个主 Agent 按需加载领域流程,同时保留完整对话状态。
这比“一个领域一个 Subagent”更适合高度耦合的任务。模块化要解决的是知识和流程组织问题,不一定要靠多 Agent 才能实现。
06|高频规则放 Prompt,低频流程放 Skill
几乎每次请求都会用到的规则,应该常驻 System Prompt;低频、长尾、可按需加载的流程放进 Skill。
安全、法律、品牌约束以及关键用户事实属于高优先级规则,不应该为了省上下文而藏进一个可能没有加载的 Skill。能够由页面、入口或业务信号提前判断的 Skill,也可以由 Harness 在第一次模型调用前直接预加载。
07|Subagent 只留给真正独立的深任务
Subagent 不是不能用,而是要用在边界清楚、自包含、值得单独占一个上下文窗口的工作上,例如深度研究、代码分析,或者一个本来就有独立合规边界的专业 Agent。
如果 Subagent 需要在同一轮里频繁进进出出、不断和主 Agent 同步状态,通常说明这个任务并没有真正被拆开。
二、Tools:AI 不应该重新发明你的业务
08|Tools 建在已有业务系统之上
公司已经有搜索排序、库存、购物车、会员、价格、促销、分析等系统,这些系统包含多年积累的确定性逻辑和实时信号。
Agent Tool 应该调用这些系统,而不是在模型里再造一个低配版本。
09|Tool 边界要把“确定性逻辑”和“模型判断”分开
例如商品搜索结果应该先由搜索系统完成召回和排序,再交给 Agent 判断哪些结果更符合当前目标、展示多少、怎么解释。
规则、约束、权限和计算留在系统侧;选择、组合、表达留给模型。
10|Tool 返回的是上下文,不是 API 垃圾桶
工具返回的每一个字段都会进入模型上下文。模型根本不会推理的字段,不应该因为“API 本来就有”而全部塞进去。
先裁剪,再整形。让 Tool 输出最少但足够完成判断的信息。
11|错误结果也要告诉模型下一步
一个 403、400 或内部错误码,对 Agent 几乎没有行动价值。
好的 Tool Error 应该告诉模型问题是什么、缺什么参数、下一步应该怎么修正。错误信息本身也是 Agent 的操作界面。
12|UI 组件本身也可以是 Tool
当 Agent 需要展示商品卡片、行程、套餐比较、图表时,与其让模型输出自定义 HTML 标签,不如把这些展示组件定义成带类型的 Presentation Tool。
模型只生成结构化参数,服务端负责校验和补全,客户端负责渲染。这样历史消息、Schema、校验和 UI 都能保持统一。
三、体验与成本:不要只盯 Token 单价
13|先算清楚任务延迟到底来自哪里
Agent 的总耗时,不只是模型生成速度,而是多轮模型调用、Tool 执行和网络等待的总和。
真正有效的优化通常来自三个方向:减少不必要的回合、让 Tool 更快、让输出更快到达用户。
14|能流式出现的结果,就不要等全部完成
如果 Agent 最终要生成几百个 Token 的结构化界面,等全部生成完再一次性显示,只会制造一个长时间 Spinner。
参数一旦形成就可以逐步发送给客户端,让页面边生成边出现。
15|把“正在做什么”展示给用户
Agent 查数据、搜索、比较时,可以把已有 Tool 参数转成简短的人类可读进度,例如“正在查找临水酒店”。
总耗时可能没有变化,但感知延迟会明显下降。用户看到的是工作在推进,而不是系统卡住。
16|Prompt Cache 是最先该吃到的成本红利
System Prompt、工具定义和长期稳定的共享上下文具有很高的复用率,天然适合缓存。
先把稳定段和会话段设计清楚,让缓存命中,再讨论为了省钱是否需要牺牲模型能力。
17|模型选择看任务完成质量,不只看单次 Token 价格
低价模型如果带来更多回合、更多失败重试和更差的完成率,整个任务反而可能更贵。
真正该比较的是端到端任务质量、完成时间和总成本,而不是模型价目表上的单个数字。
四、生产:模型可以判断,但不能拥有最终权力
18|Memory 应该存在你的系统里,不是模型里
长期记忆是产品能力,不是“希望模型记住”。用户偏好、约束和长期事实应该进入你能控制、能删除、能审计的存储系统。
模型只是读取和使用 Memory 的消费者。
19|Memory 要分层读取,不要每轮全量塞
少量高频事实可以一直放在上下文;和当前请求明显相关的事实可以每轮预取;其余信息留在查询 Tool 后面按需读取。
把所有历史记忆每轮全部塞给模型,只会浪费上下文,还会增加错误关联。
20|安全规则必须由 Harness 执行
Prompt 可以告诉模型“不要做什么”,但真正的安全边界不能只依赖模型遵守一句话。
涉及钱、价格、退款、订单、活动预算、权限等不可逆操作时,限制必须写进代码,并且所有 Runtime 共用同一套执行规则。
21|模型只负责 Stage,真正 Apply 交给人或策略
模型可以提出“我要做这项变更”,生成一个待执行的 staged change;真正写入业务系统之前,由用户按钮、审批界面或确定性策略完成批准。
对高风险操作来说,模型最危险的权限应该只是“提出建议”,而不是“直接生效”。
22|限额要检查“写完之后的状态”,并串行化关键写入
只检查单次请求是不够的。Agent 会重试、换一种说法,甚至并行调用工具,多个合法请求叠加后可能突破限制。
因此限购、折扣深度、价格变化、预算等约束,都应该针对写入后的最终状态重新检查;同一会话里的关键写操作还需要串行化。
23|第三方内容进入模型前先净化
商品描述、卖家消息、评论、外部政策和用户生成内容都属于不可信输入。
统一经过 Sanitizer,去掉控制字符、伪造对话角色、伪造 Tool Call、超长内容等风险,再用明确边界包起来,并告诉模型:这些内容只能被理解和引用,不能被当成指令执行。
24|Evals 必须同时覆盖正例、反例和真实事故
每一个“应该做”的测试,都需要对应一个“应该拒绝”或“应该询问”的反例。测试集还要覆盖上下文继承、Memory、工具失败、边界条件和安全场景。
最好的 Eval 往往来自线上真实事故和一线团队。每个 Tool、Skill 和 Prompt 变更都应该带着自己的 Case 进入 CI;高风险规则跑核心回归,完整套件定期跑,发布先 Canary,并保留快速关闭单个能力的开关。