2.1 把模型请下对话台:决策循环与提示契约


2.1 把模型请下对话台:决策循环与提示契约

本节摘要:工具调用的第一步不是写代码,而是立规矩——让模型在系统提示词里知道"你是谁、你有哪些工具、你必须以什么格式说话、什么时候停"。这份提示契约的质量,直接决定后面整套循环的稳定性。本节给出一份可直接套用的契约模板与它的设计依据。

承接第 1 章的结论:模型的输出本质是"文本形式的意图",循环程序只是意图的执行者。那么意图的表达质量就成了整个系统的第一块短板——模型不知道工具的存在就不会用,理解歪了工具的用途就会乱用,没被规定输出格式程序就解析不了。这三件事全部要在对话开始前的系统提示词里锁死。

契约的四要素

一份能用的提示契约,至少包含四个部分。缺任何一块,故障模式都可以预判:

角色与目标边界。告诉模型它是什么岗位、服务谁、什么该做、什么坚决不做。这不是客套,是给模型划定"决策搜索空间"——客服智能体看到退款要求不该自己拍板,因为契约里写了"退款需人工审核"。

工具清单与使用时机。每个工具的名字、一句话职责、参数含义、什么时候该用它、什么时候不该用。模型对工具的理解完全来自这段文字,工具描述写得含糊,选错工具的概率直线上升——这相当于给新员工的岗位说明书。

输出格式。模型每轮必须输出机器可解析的结构:想做什么、调用哪个工具、参数是什么。格式一旦摇摆,解析器就崩。

终止条件与兜底行为。什么时候可以宣布任务完成、什么情况下必须承认做不到、连续失败多少次要上报人工。没有终止契约的循环,最常见的死法是在两个工具之间来回打转,把预算烧光。

一份可直接套用的契约模板

你是「报销助手」,服务公司内部员工。你的职责是处理报销单的查询、 填写辅助与进度跟踪。涉及审批决定时,你只能说明流程,不能代审批。 # 可用工具 1. query_expense(expense_id: string) 查询报销单状态与明细。当用户提到具体单号时使用。 不用于:创建新报销单。 2. create_expense(amount: number, category: string, receipts: string[]) 创建报销草稿。金额必须为正数,category 取值:差旅/办公/招待。 不用于:修改已提交的单据。 3. finish(summary: string) 任务完成或无法完成时调用,summary 里给用户可读的结论。 # 行为规则 - 每轮只执行一个工具调用。 - 参数值只能来自用户提供的信息或工具返回结果,禁止编造。 - 同一工具连续失败两次后,改用 finish 说明原因,不要重试第三次。 - 用户身份信息、支付密码类请求一律拒绝并提示走人工渠道。 # 输出格式(严格 JSON,不要额外文字) {"thought": "一句话说明下一步及理由", "action": {"name": "工具名", "args": {...}}}

这份模板里有三处容易忽略的设计值得点出:每个工具都写了**"不用于"**(负面清单比正面描述更能防误用);禁止编造参数直接瞄准了模型编造这一顽疾;连续失败两次就上报,把无限重试扼杀在第三次之前。

契约如何落进循环

契约写好后,循环侧的职责是校验与兜底。模型输出违反契约(JSON 解析失败、调用了不存在的工具、参数类型不对)时的标准处理不是崩溃,而是把错误作为观察喂回去,让模型自己修正——它和人类程序员收到报错后的行为一模一样:

def step(messages, tools): reply = llm.complete(messages) try: parsed = json.loads(reply) action = parsed["action"] if action["name"] not in tools: raise ValueError(f"未注册的工具: {action['name']}") return parsed except (json.JSONDecodeError, KeyError, ValueError) as e: # 违约不崩溃:把违约事实写回上下文,给模型一次自我修正的机会 messages.append(role("user", f"你的上一次输出违反了输出契约:{e}。" f"请严格按 JSON 格式重新输出。")) return None # 本轮作废,下一轮重试

⚠️ 常见坑:在契约里写"请务必准确"这类恳求式语言。模型对可执行规则(格式、清单、次数上限)的服从度远高于对态度要求的服从度。契约要像接口文档,不要像劝学信。

契约演化的实例:从翻车到修复

背景:报销助手上线后,运维发现大量会话出现同一怪象——用户问"我的报销到哪了",模型却调用了 create_expense,试图给用户"创建"一张新单。

操作:回放轨迹发现两个诱因:工具清单里 query_expense 的描述只有一句"查询报销单",模型在"查询"与"创建"之间犹豫时缺乏锚点;契约没有写"用户提到已有单据时禁止创建"。

结果:修复只改了两行——query_expense 补上"不用于:创建新报销单",行为规则追加"用户引用了单号时只允许查询类工具"。误创建率从日均几十次降到零。

解读:提示契约不是写完就完的静态文档,它是这套系统里迭代最频繁的部件。每一次线上故障,第一步都该问:这是契约没写清,还是工具设计不合理,还是模型能力不足?三者对应三种不同的修复路径,混着修只会越修越乱。

变式:工具超过十个之后,把全部清单塞进系统提示词会挤占窗口并稀释注意力,这时需要"工具检索"——先按任务挑出相关的几个工具再进契约。这是第 3 章记忆与检索机制的另一个应用场景。

本节要点回顾

  • 契约四要素:角色边界、工具清单(含负面清单)、输出格式、终止与兜底——缺一块就有一种可预判的故障。
  • 违约处理原则:解析失败不崩溃,把违约事实作为观察喂回去,让模型自我修正。
  • 契约是活文档:线上故障先三分归因(契约 / 工具设计 / 模型能力),再对症修复。
  • 可执行规则优先:格式、清单、次数上限的服从度远高于态度性要求。

下一节进入机制的内核:Function Calling 协议下,一轮工具调用从定义、发起到结果回填的完整时序。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U