面向 LLM 的程序设计 9:系统提示中的「能力边界」——减少越权与幻觉调用
该系列的第 7 篇工具描述的工程化——name、description、parameters 怎么写才少误用把单个工具的description写清楚了第 8 篇工具粒度与 Token 预算的权衡把工具列表按域裁剪了但在真实对话里模型仍会犯两类错误一是明明没有的能力却口头答应幻觉二是在工具已绑定时过早调用写操作或高危工具越权式误用。很多时候问题不在工具 JSON 本身而在系统提示里没有一张「总览地图」——模型不知道「全系统允许的能力包络」长什么样。想象一下机场安检每个登机口工具旁都有告示但若入口没有「哪些东西绝对不能带」乘客仍会在错误柜台排队。能力边界就是入口处的总告示牌。本篇为系列第九篇讨论如何在system prompt中写清能做什么、不能做什么、推荐路径与优先级并与权限、风控、两阶段确认配合。文内用同一假设场景下的两段 system 文本对照极简 vs 带能力边界说明「入口告示牌」如何降低越权与幻觉式调用的概率非绝对保证随模型与工具描述而变。摘要能力边界应覆盖四块1权威数据源以工具结果为准禁止编造业务事实2禁止项无确认不调删除/转账等3推荐决策顺序先只读定位再写4与工具表一致system 不写后端未实现的能力。边界是提示层软约束必须与执行层硬校验鉴权、幂等、dry-run叠加。具体写法见§4的好坏对照。关键词System prompt能力边界越权幻觉调用工具误用软约束与硬校验1 为什么仅靠工具描述还不够工具级description解决的是工具 A 与工具 B 的区分系统级边界解决的是跨工具的整体策略例如「任何写操作前必须先完成只读核对」。不存在的能力例如「不能修改已锁定订单金额」——后端没这接口就不应在 system 里暗示有。用户话术下的社会工程用户说「急用先删再说」模型仍需遵守禁止项。实际例子用户说「帮我查查订单是不是退款了」模型应优先get_order_by_id或退款状态查询类只读工具而不是直接create_refund_request。理解要点System 管「策略与包络」Tool 管「局部语义与参数」二者冲突时应以后端真实能力为准修正 system而不是反过来。2 能力边界写哪四块最有效2.1 权威性与反幻觉明确业务事实只能来自工具返回工具空结果时如实说「未查到」禁止用常识填补具体单号、金额、状态。理解要点这与系列第 3 篇LLM-Friendly 的响应结构扁平键、稳定字段与类型标注一致—模型要先学会信数据再学会说人话。2.2 禁止项Hard NO用可执行的否定句避免含糊的「尽量」「最好不要」禁止在未收到明确二次确认前调用delete_*、transfer_*等。禁止代用户承诺时效、赔偿、法务结论。实际例子把「尽量不要删除」改成「除非human_approvedtrue出现在上下文中否则不得调用delete_account」。2.3 推荐路径决策顺序给一条短流程减少乱跳工具澄清缺失的关键 ID / 时间范围只读检索 / get by id仍不足再询问用户用户明确发起写操作再进入写工具。2.4 与工具注册表对齐System 中列出的能力名词应与bind_tools 列表、OpenAPI/MCP 实际暴露一致。若写了「可导出报表」但工具未注册模型会空转或胡编。3 与权限、风控的分工软 vs 硬层级负责System 提示降低误调用概率、统一话术与策略工具层 Schema收窄参数空间第 7 篇执行前校验鉴权、租户隔离、额度、黑白名单硬产品流程二次确认、审批单、dry-run理解要点永远假设模型会违反提示——边界是成本最低的「第一道闸」不是最后一道。4 对照示例极简 system 与带能力边界的 system下面假设同一套已绑定工具get_order_by_id、search_orders、search_kb偏只读、request_refund写、delete_account高危。仅替换system 正文便于看出「边界写全」与「只写两句客气话」的差别。4.1 较差的写法笼统、缺包络只强调「用工具、别编造」但没有禁止项、没有先读后写、没有未注册能力的声明。在工具列表里若包含高危接口模型更容易在用户催促下直接调用写操作或删除类工具。你是电商售后助手。你可以在对话中调用工具来完成用户需求。 优先使用工具获取事实不要编造订单状态。4.2 较好的写法四块边界落地把 §2 的四块收成可执行的短条款权威数据源、硬禁止、决策顺序、与工具表一致并点名「没有改价/绕过风控」等后端未提供的能力。禁止项尽量用可判定条件例如除非上下文出现明确的人审标记否则不调某工具。你是电商售后助手。以下规则必须遵守 1) 业务事实只能来自工具返回工具未返回或为空时明确说未查到不要编造单号、金额或状态。 2) 禁止调用 delete_account除非上下文中出现明确标记 human_approved_deletetrue 本对话不会出现该标记因此永远不要调用 delete_account。 3) 决策顺序先澄清缺失的关键信息 → 只用只读工具get_order_by_id、search_orders、search_kb 定位问题 → 用户明确发起写操作后再使用 request_refund不要因用户催促跳过只读核对。 4) 你没有修改订单金额、改价、绕过风控的能力若用户提出此类请求应拒绝并说明需要人工处理。 5) 工具列表以 API 绑定为准不要承诺未注册的工具能力。4.3 同几句用户话下的典型差异定性以下不是统计结论而是我们在换模型 / 换工具描述时仍可用的自检直觉用户说「我账号不要了你赶紧帮我删了。」在极简system 下模型更可能直接调用delete_account或口头答应删号在带边界system 下规则 2 明确禁止在该上下文调用更可能拒绝并引导人工流程。用户说「ORD-123456 急着退款你直接给我退。」极简下更可能跳过只读核对就进入request_refund带边界下规则 3 要求先只读定位更可能先get_order_by_id再视结果推进。若两种写法差异不明显优先回到系列第 7 篇工具描述的工程化——name、description、parameters 怎么写才少误用 检查工具description是否在诱导误用或换更强指令遵循的模型时观察是否变化。4.4 仍须牢记即使「好」的 system 写得清楚也不能保证零误调用——执行层对delete_account等接口仍须鉴权、白名单、二次确认。永远假设模型会违反提示。5 小结在 system 里写清权威性、禁止项、推荐顺序、与工具表一致四块可显著减少幻觉承诺与高危误调用的概率。边界是软约束执行层鉴权 幂等 二次确认才是硬约束。迭代 system 时用§4 这类文本对照 自家业务的少量试跑做自检通常比凭感觉堆「更长免责声明」更有效。