课程大纲 › 领域 1:Agent 架构与编排
1.4 用强制与交接模式实现多步骤工作流
タスクステートメント1.4:強制とハンドオフのパターンを用いて複数ステップのワークフローを実装する
官方大纲原文(日文):知识 3 条 · 技能 3 条
需要掌握的知识
- ワークフローの順序付けにおける、プログラムによる強制(フック、前提条件ゲート)とプロンプトベースのガイダンスの違い
- 決定論的な遵守が求められる場合(例:金銭に関わる操作の前の本人確認)、プロンプトの指示だけでは失敗率がゼロにならないこと
- プロセス途中でのエスカレーションのための、顧客の詳細、根本原因の分析、推奨アクションを含む構造化されたハンドオフプロトコル
需要能做到的事
- 前提となるステップが完了するまで下流のツール呼び出しをブロックする、プログラムによる前提条件を実装する(例:get_customerが検証済みの顧客IDを返すまでprocess_refundをブロックする)
- 複数の懸案を含む顧客リクエストを個別の項目に分解し、共有コンテキストを使ってそれぞれを並列に調査したうえで、統一された解決策にまとめる
- 会話の記録にアクセスできない人間の担当者にエスカレーションする際に、構造化されたハンドオフサマリー(顧客ID、根本原因、返金額、推奨アクション)を作成する
课程讲解 · AI 草稿,未经人工审核 以官方文档为准
这一条考什么
考你能否区分"用程序强制"和"用提示引导"两种控制工作流顺序的方式,并在需要确定性合规的场景(例如涉及资金的操作前必须完成身份验证)选择程序强制。还考两个配套能力:把包含多个诉求的客户请求拆开并行处理再合并;以及在中途升级给人工时,生成一份结构化、可直接决策的交接摘要。
核心概念
程序强制 vs. 提示引导
控制"先做 A 再做 B"有两类手段:
- 提示引导:在系统提示里写"退款前必须先调用 get_customer 验证身份"。模型大多数时候会遵守,但这是概率性的,无法做到 100%。
- 程序强制:在代码层面设置前置条件门(prerequisite gate)或 Hook,当前置步骤未完成时直接拒绝下游工具调用。不论模型怎么推理,违规调用都不会被执行。
二者并不互斥:提示负责让模型"知道该怎么做"、减少被拦截的次数;程序强制负责兜底,保证"绝不会发生"。
为什么提示无法把失败率降到零
LLM 的行为是概率性的。即使提示写得再强调(全大写的 CRITICAL、NEVER),再加 few-shot 示例,在长对话、上下文冲突、用户诱导等情况下依然会偶发违规。对于"给未验证身份的人退款"这类事故,哪怕千分之一的失败率也不可接受。所以判断标准很简单:如果业务要求确定性遵守,就必须在代码里强制。
前置条件门的实现思路
在执行工具的那一层维护会话状态:
get_customer成功返回且验证通过时,记录verified_customer_id。- 收到
process_refund调用时,先检查状态:没有已验证的客户 ID,或调用参数中的客户与已验证的不一致,就不执行,而是返回一个is_error: true的tool_result,说明"需要先完成身份验证"。 - 模型收到这个错误后会自行补上验证步骤。
这种门可以写在你的工具分发函数里,也可以用 Agent SDK 的 PreToolUse Hook 实现(见 1.5)。
多诉求请求的分解与合并
客户一次说了三件事:"上周的订单少发了一件、这个月被重复扣费、顺便改一下收货地址"。较好的处理方式:
- 先识别并列出独立的诉求项。
- 基于共享上下文(同一个已验证客户、同一组订单数据)分别调查每一项;彼此独立的调查可以在同一轮里并行发出多个工具调用。
- 汇总所有调查结果,给出一个统一的回复和解决方案,而不是让客户分三次来回沟通。
结构化交接协议
当流程进行到一半需要升级给人工(例如金额超出授权、需要政策例外),接手的人看不到对话记录。交接内容应当是"可直接决策"的状态,而不是原始素材。推荐字段:
{
"customer_id": "C-20931",
"verified": true,
"issue_summary": "促销价未生效导致多收费",
"root_cause": "订单 A-7781 下单时促销码校验失败,按原价结算",
"order_refs": ["A-7781"],
"refund_amount": 680.00,
"actions_taken": ["已核实身份", "已确认促销在有效期内", "退款因超过 500 美元授权上限被拦截"],
"recommended_action": "批准 680.00 美元退款并补发促销确认邮件",
"customer_sentiment": "不满,已第二次来电"
}只传用户原话不够(人工得从头调查);把整段对话和工具输出全部存库再交接也不好(信息量大、需要人工重新提炼);先尝试执行越权操作、失败了再升级更是错误。
正确做法与反模式
- 正确:在工具执行层设置前置条件,
get_customer返回已验证 ID 之前阻断process_refund。反模式:只在系统提示里强调"必须先验证"。 - 正确:被阻断时返回清晰的错误说明,引导模型补齐前置步骤。反模式:静默丢弃调用或直接抛异常结束会话。
- 正确:把多诉求请求拆成独立项,基于共享上下文分别(可并行)调查,最后统一答复。反模式:只处理第一个诉求,或让客户分多次提出。
- 正确:升级时生成包含客户 ID、根因、金额、已做操作、建议动作的结构化摘要。反模式:只转发用户原始消息,或把完整对话日志丢给人工。
- 正确:提示与程序强制配合使用。反模式:认为加了 few-shot 示例就等于有了保证。
常见陷阱
- "用更强烈的措辞强化系统提示(CRITICAL / NEVER)"——仍是概率性遵守,题目若强调"必须""确定性""合规",就选程序强制。
- "添加 few-shot 示例展示不同金额下的正确行为"——能提升遵守率,但不能归零失败率。
- "让工具在超额时返回错误信息'请升级'"——比纯提示好,但真正的拦截点与重定向应在调用发出前(前置条件 / PreToolUse Hook),题目常把 Hook 作为最佳答案。
- "调用 escalate_to_human 时只附上客户原话"或"先把整段对话存库再升级"——接手的人需要的是提炼好的、可决策的结构化信息。
- "先尝试处理,系统拒绝了再升级"——在明知越权时先尝试是错误流程。
实操练习
目标:在 anthropic SDK 的 Agent 循环中实现一个前置条件门,验证"未验证身份时退款被阻断"。
- 复用 1.1 的循环结构,把工具分发换成下面的
dispatch。 - 用户消息使用"我是 C-1,订单 A-1 请退款 50 元"。
- 观察第一次
process_refund(如果模型跳过验证)是否被门拦截,以及模型随后是否补调get_customer。
import json
state = {"verified_customer_id": None}
def dispatch(name, args):
"""返回 (content, is_error)"""
if name == "get_customer":
# 假设校验通过
state["verified_customer_id"] = args["customer_id"]
return json.dumps({"customer_id": args["customer_id"], "verified": True}), False
if name == "process_refund":
vid = state["verified_customer_id"]
if vid is None:
return ("PRECONDITION_FAILED: 尚未验证客户身份。"
"请先调用 get_customer 并获得 verified=true。"), True
if args.get("customer_id") != vid:
return "PRECONDITION_FAILED: 退款客户与已验证客户不一致。", True
return json.dumps({"refund_id": "R-1", "amount": args["amount"]}), False
return f"未知工具 {name}", True
# 在循环中:
# content, is_err = dispatch(block.name, block.input)
# results.append({"type": "tool_result", "tool_use_id": block.id,
# "content": content, "is_error": is_err})工具定义中 get_customer 需要 customer_id,process_refund 需要 customer_id、order_id、amount。检查结果:无论系统提示怎么写,process_refund 只有在 get_customer 成功后才会真正执行;把系统提示里"先验证"的说明删掉再跑几次,门依然有效。
自测清单
- 程序强制与提示引导分别提供怎样的保证?各自适合什么场景?
- 为什么即使有 few-shot 和强调措辞,提示也无法让违规率归零?
- 设计一个前置条件门:它需要记录什么状态?被拦截时应该返回什么?
- 客户一次提出三个诉求时,你的分解、调查、合并流程是怎样的?
- 交接给看不到对话记录的人工时,摘要至少应包含哪些字段?
对应题目(2)
题目归类由 AI 判断,仅供参考。
练习这 2 道题