☰
AI Agent落地:意图、边界、价值与责任的工程化实践
2026/11/4 20:40:27 网站建设 项目流程

做 Agent 落地这几年,我越来越有一种奇怪的体感:真正把我卡住的,往往不是模型能力不够、不是工具接口调不通、也不是上下文塞不下,而是那些没人能给出标准答案的问题——“用户这句话到底是什么意思”“这件事它该不该自己拍板”“这次算做好了还是没做好”“出了事到底算谁的”。这些问题听起来像哲学,做起来却是纯工程:它们会决定你的系统能不能上线、上线之后敢不敢放开手、放开手之后半夜会不会被电话叫醒。我见过太多团队把八成精力砸在“让 Agent 能跑通”上,最后卡在“让它敢跑第二遍”这一步。这篇就聊聊我怎么把这几类哲学问题拆成可以写进需求文档、可以进代码、可以进回归测试的工程动作,适合已经动手做过 Agent 项目、或者正准备把 Demo 推到真实业务里的人看。

1. 为什么 Agent 项目总会拐进哲学岔路口

1.1 从“能跑通”到“敢上线”中间隔着一层定义

Demo 阶段的验收标准极其宽松:我给它一句话,它返回了一个看起来像那么回事的结果,这就叫成功。一次演示成功,整个团队士气高涨,觉得再包个界面就能交付了。但从那一刻起到真正上线,中间隔着的不是工程优化,而是一整套“定义工作”——什么叫完成、什么叫正确、什么情况下它应该停下来问人。

这层定义之所以难,是因为传统软件里这部分根本不存在。写一个导出报表的函数,输入校验、输出格式、异常分支,全都是确定性的,产品经理写清楚,工程师照着做,测试照着验。而 Agent 的输入是自然语言,输出是自然语言加一串动作,中间还夹着模型自己的判断。于是所有原本被“需求文档”挡住的模糊地带,全部涌进了系统内部,变成了运行时的不确定性。你在需求评审会上没吵清楚的东西,模型会在生产环境里替你做决定,而且是不打招呼地做。

我一般会在这个阶段拉一次“定义对齐会”,不聊技术方案,只聊三个问题:这个 Agent 的活儿干到什么程度算交付;它有哪些事绝对不许自己干;出错之后第一责任人在哪个环节。这三个问题看着虚,但把它们吵明白了,后面 80% 的返工都能省掉。

1.2 四个绕不开的命题:意图、边界、价值、责任

把那些让人头大的问题归个类,其实就那么四堆。意图问题:用户说的话和他真正想要的东西不是一回事,Agent 该按字面执行还是按推测执行。边界问题:它的权限该开到多大,哪些动作必须经过人。价值问题:多个目标打架的时候听谁的,“做得好”到底怎么衡量。责任问题:结果不对,是模型的锅、提示词的锅、还是流程设计的锅,怎么追溯、怎么回滚。

这四件事有个共同的麻烦:它们没有唯一正解,只有“在当前场景下可接受的解”。所以你不能指望一次设计就定死,得把它当成一个持续收敛的过程。我自己的做法是给每个命题配一套“默认策略 + 升级通道”:默认策略保证绝大多数情况能自动往前走,升级通道保证遇到争议能落回人手里。这套东西不写进文档就等于没做,因为模型不会猜你的价值观。

下面几节,我按这四堆问题分别拆,每一堆都给具体可抄的做法。

2. 意图哲学:用户说的和用户要的从来不是一回事

2.1 指令歧义其实只有三种结构

刚做 Agent 的时候我以为歧义是无穷无尽的,做久了发现基本能归到三类。指代歧义:用户说“把这个整理一下”,这个指的是当前打开的文件、上一条消息里提到的文件,还是他脑子里以为你能看到的那份。范围歧义:“帮我列个提纲”,是三级标题还是五级,是一页纸还是十页纸。标准歧义:“写得专业一点”“语气别太硬”,这类描述在人类之间靠默契传递,在 Agent 这里就是黑洞。

对应地,解法也不一样。指代歧义靠“显式化上下文”解决:把当前会话里所有可能被指代的对象列成清单,让模型必须从中选一个,选不出来就问。范围歧义靠“给默认值并声明”:没说的话按默认范围走,同时在输出里注明“按 X 范围生成,需要调整告诉我”。标准歧义最麻烦,靠“正负样例”解决,给两三个“这样算专业、那样不算”的对照,比写十行形容词都管用。

我踩过最典型的一个坑是标准歧义。早期做一个会议纪要整理的功能,我在提示词里写了“简洁但不遗漏关键信息”,测试阶段大家都觉得没问题,上线后收到的第一批反馈是“太啰嗦”和“漏了重点”各占一半。后来我把“简洁”翻译成了硬指标:每条决议不超过两句话、待办必须带负责人和时间、讨论过程只保留分歧点。指标一落地,争议立刻少了一大半。模糊形容词是 Agent 的天敌,能翻译成数量或结构约束的,一律翻译。

2.2 把“理解”变成一份可以核对的结构化产物

光在心里理解没用,得让理解变成看得见的东西。我的做法是强制 Agent 在执行前先输出一份“意图确认卡”,字段固定,内容填不满就不许往下走。这份卡不一定要给用户看,但一定要被系统记录下来,后面出问题第一个怀疑对象就是它。

# 意图确认卡:执行前必须填满的结构化产物 task_goal: "把 Q3 的销售复盘整理成汇报用的提纲" # 一句话目标,禁止超过30字 input_assets: # 明确列出要用哪些物料 - id: "file_2024_q3_sales" type: "spreadsheet" assumed_content: "含月度销售额、区域拆分、同比数据" output_form: "markdown_outline" # 产出形态,必须是枚举值 scope_default: # 没说清楚的地方,写默认值 depth: "二级标题" length: "8-12条" include_data: false acceptance: # 验收标准,可判定 - "覆盖三个区域,缺一不可" - "每条提纲下至少一个数据支撑点" forbidden: # 红线,绝对不能碰 - "不得修改原始数据文件" - "不得对外发送任何内容" confidence: 0.72 # 模型自评,低于阈值就转澄清

这份卡有两个作用。一是强迫模型把“我以为”写出来,很多错误在填卡阶段就暴露了,比如它以为输入是表格,实际是一堆截图。二是给后续排查留下证据链,出问题时你能精确知道是理解错了还是执行错了。confidence字段我建议一定要留,虽然模型的自评分数不太准,但作为“要不要多问一句”的触发器,它比固定阈值好用得多。

2.3 什么时候该追问,什么时候该先猜

新手常犯的错是过度追问:什么都问一遍,用户点三次确认就烦了,直接关掉不用。另一个极端是什么都不问,猜错了让用户重来一遍,体验更差。这中间有个可以算的平衡点。

我的经验公式很土但够用:追问价值 = 猜错的概率 × 猜错的返工成本 − 打断用户的成本。返工成本按“用户要重新描述一遍 + 等待一次完整执行”折算,打断成本按“多一次交互”折算。概率可以从历史数据里估:某类指令过去一百次里有几次被用户纠正过。算出来的值低于阈值就闷头猜,高于阈值就问。

落到产品上就是分级:高风险动作(不可逆、涉及外部发送、涉及金额)必须问;低风险且可撤销的动作大胆猜,但要在输出里显式声明“我按 X 理解做的,不对你直接说”;中等风险的动作给一个“我先做草案,你确认后我再落地”的中间态。这个中间态是我最喜欢的设计,它把一次可能很贵的错误变成了一次很便宜的修正。我做过一个内容生成的场景,加了草案确认这一步之后,最终产出的一次通过率从六成出头涨到了九成,用户反而觉得更省事了,因为他不用再反复解释。

3. 边界哲学:它该走多远才算尽责

3.1 自主度四档:先定档,再谈能力

边界这件事最忌讳笼统地说“让 Agent 自主一点”或者“保守一点”。我习惯把它拆成四个明确的档位,每个档位对应一组可执行的规则,选档位是产品决策,不是技术决策。

档位行为描述适用场景人的介入方式
L0 只读建议只能读取信息、给出建议,不能产生任何外部副作用早期验证、高风险业务人看完自己动手
L1 草案待确认可以生成完整产物,但必须经人确认才能生效内容生产、方案设计一键确认或修改
L2 可逆自动、不可逆确认可撤销的动作自己做,不可撤销的必须停下大部分日常业务只在关键节点打断
L3 全自主加事后审计全流程自动,事后抽样检查高频、低风险、可回滚定期抽检与异常告警

选档位的依据我一般看三个维度:动作可撤销吗、错误代价有多大、发生频率有多高。高频低代价的事情,即使偶尔出错,人工兜底的成本也远低于每次都确认的成本,那就往 L2、L3 走。低频高代价的事情,哪怕模型准确率有 95%,那 5% 也足以毁掉整个项目的信任,老老实实待在 L1。

这里有个特别容易被忽略的点:档位可以按动作类型混搭,不必按整个 Agent 统一设定。同一个 Agent,读取数据可以放到 L3,生成文案放 L1,对外发送必须 L0 加人工确认。我见过团队为了“统一体验”把所有动作定成同一档,结果要么整体太保守没人用,要么整体太激进老出事。

3.2 不可逆操作的闸门要建在工具层,不是提示词里

这是我最想强调的一条。很多团队把“不要删除文件”“不要直接发邮件”写在系统提示词里,然后祈祷模型听话。这等于把安全阀交给了一个概率模型,迟早出事。正确的做法是在工具调用层做硬拦截,提示词只是第一道软约束。

具体做法分三层。第一层是工具白名单:Agent 能调用的工具是有限的、明确定义的,没有“通用执行任意命令”这种口子。第二层是参数校验:即使调用了允许的工具,参数也要过一遍规则引擎,比如删除操作的目标路径必须在某个沙箱目录内,金额参数不得超过某个上限。第三层是执行前预演:不可逆动作先跑一次 dry-run,把“将要发生什么”打印成人能读懂的描述,让人确认。

# 工具层闸门示意:不可逆动作强制走预演 + 确认 IRREVERSIBLE = {"delete_file", "send_message", "submit_form", "make_payment"} def guarded_call(tool_name, params, ctx): if tool_name in IRREVERSIBLE: preview = build_preview(tool_name, params) # 生成人类可读的影响描述 if not ctx.human_confirmed: return { "status": "pending_confirmation", "preview": preview, "risk_level": assess_risk(tool_name, params), } # 二次校验:即使人确认了,硬约束依然生效 assert check_hard_limits(tool_name, params), "参数越过硬边界" return execute(tool_name, params)

闸门的位置决定了它的可靠性。放在提示词里,模型换个说法就绕过去了;放在工具层,模型再聪明也只能撞墙。我现在的默认原则是:凡是不可逆的动作,一律假设模型会犯错,按最坏情况设计拦截。

3.3 越权和失职是一枚硬币的两面

过度保守的 Agent 有个隐蔽的代价:用户会慢慢不用它。什么事都要问一句,用起来比自己干还累,用户三次之后就不点了。这种情况在数据上表现为“调用量高但完成率低”,看着热闹,实际没解决问题。过度激进则相反,完成率很高,但错误率也在悄悄爬升,直到某天出一个大事故。

判断自己偏向哪一边,我有个很土的办法:去翻最近一百条交互记录,数一数里面有多少条是“Agent 问了一个其实能自己判断的问题”,有多少条是“Agent 自作主张做了本该问一句的事”。前者超过两成,说明太保守;后者超过半成,说明太激进。这个比例比任何指标都直观。

调的方向也很明确。太保守就把可逆动作大胆放权,在输出里加一句“我按默认方式处理了,需要改直接说”;太激进就把不可逆动作收紧,同时给可逆动作加一个显式的撤销入口。撤销入口这个设计我特别推荐,它相当于给用户一个后悔药,用户的容忍度会明显上升,因为他知道自己随时能退回去。

4. 价值哲学:到底什么算“做对了”

4.1 目标函数里总有一块写不出来

“帮我写个周报”这句话,你可以定义格式、字数、必须包含的模块,但“写得好不好”这部分永远定义不完。它包含语气是否得体、重点是否突出、有没有把不该写的写进去。这些在人类之间靠组织文化和默契传递,Agent 没有这个背景。

我的处理方式是不追求定义完整,而是追求“可判定”。把任务拆成两部分:硬性可判定的部分用规则校验,比如格式、必填项、字数区间、是否包含某个字段;软性不可判定的部分用对照样例引导,比如给三条“这样写符合我们风格”和两条“这样写不行”的样例,让模型去对齐模式,而不是去理解形容词。

样例的力量远超多数人的预期。我做过一个对比:同一批任务,一组用形容词描述风格(“专业但不生硬,简洁但有信息量”),另一组用四个正负样例代替这段描述,后者的人工评分明显更高,而且不同批次之间的风格一致性也更好。原因很简单,形容词需要模型自己去解释,样例只需要它去模仿。

4.2 用评价量表替代“对/错”的二元判断

做 Agent 最容易掉的坑是把验收搞成二元的:好或者不好。一旦二元,所有中间状态都被抹平,你既不知道它离达标差多远,也没法判断一次改动是变好了还是只是变了个样。

我习惯用一张五维量表,每个维度 1 到 5 分,按场景给不同权重,最后算加权分。这张表的价值不在于分数本身,而在于它逼着团队把“好”拆成几条可以独立观察的维度。

维度1 分表现5 分表现典型权重
事实正确性有明显事实错误全部可核对且无误0.35
任务完整性漏掉主要要求要求全部覆盖且有增益0.25
结构规范性格式混乱无法直接用格式严整直接可交付0.15
语气得体度与场景明显不符与场景高度匹配0.15
可执行性看完不知道下一步做什么一看就知道怎么落地0.10

权重不是拍脑袋定的,是按“这个维度出错会造成多大损失”排的。事实出错可能要重做,权重就高;语气不太对用户自己改一句话就好,权重就低。上线之后用这张表做定期抽检,每次抽五十到一百条,两个人独立打分,分歧大的样本单独拿出来讨论。这些分歧点往往就是下一轮要补进提示词或样例里的东西。

4.3 多个目标打架时的优先级排序法

真实业务里目标几乎必然冲突:既要快又要准,既要覆盖全又要不出错,既要满足用户当下的要求又要考虑长期一致性。Agent 每次执行其实都在替你做取舍,你不排好序,它就随机选一个。

我的排序方法分三层。第一层是硬约束,不可违反,比如不得篡改原始数据、不得对外发送未确认内容,这一层直接写进闸门,不参与权衡。第二层是场景优先级,在具体任务里排,比如客服场景里“不承诺做不到的事”优先于“让用户满意”,写作场景里“事实准确”优先于“文采”。第三层是偏好,前两层都满足的情况下,按默认偏好走,比如默认简洁、默认给结构化输出。

排完顺序要写成显式规则,而不是留在脑子里。我通常在系统提示里用编号列表写清楚,并且给一条“当规则冲突时,编号小的优先”的兜底说明。实测下来,这一条简单的声明能显著减少模型在冲突情境下的摇摆。

5. 责任哲学:出错之后谁来兜底

5.1 可追溯性:让每一步都能被还原

出了问题最怕的是查不出来。模型输出错了,你得能回答:它当时看到了什么上下文、调用了哪个工具、传了什么参数、中间有没有人干预过、用的是哪个版本的提示词。这些信息缺一样,复盘就变成猜谜。

我的日志字段是固定的一套,不分场景,宁可冗余也不缺失:

{ "trace_id": "唯一链路标识", "session_id": "会话标识", "step": 3, "input_context_hash": "上下文指纹,用于判断是否同一份输入", "prompt_version": "v2.3.1", "model_id": "内部编号,不写具体名称", "tool_calls": [ {"name": "read_file", "params": {"id": "xxx"}, "result_code": "ok", "elapsed_ms": 120} ], "output": "本次产出摘要", "human_intervention": null, "confidence": 0.68, "token_cost": 1840 }

prompt_version这个字段特别重要,很多人只记录模型版本,不记录提示词版本,结果改了一句话就再也复现不了当时的行为。我现在的做法是提示词进版本管理,每次改动都打标签,日志里带标签,出问题能精确回滚到那个版本重跑。

5.2 人机交接的时机要写成明确条件

“必要时转人工”这句话等于没写,因为“必要时”由模型判断,而模型判断不了。必须写成条件。我常用的触发条件有四类:置信度低于阈值、涉及不可逆动作、涉及金额或权限超过上限、用户明确要求转人工。前三个是系统判断,第四个是用户主动。

触发之后的交接质量同样重要。交接不是简单丢一句“已转人工”,而是要把上下文打包好,包括用户原始诉求、Agent 已经做到哪一步、卡在什么地方、建议怎么处理。我见过最差的实现是转人工后客服要重新问一遍用户,用户体验直接崩盘。好的实现是客服一上来就能接着往下说,用户感觉是同一个服务在继续。

5.3 灰度和回滚:给“哲学决策”留后路

前面那些关于自主度、边界、优先级的判断,本质都是猜测。既然是猜测,就得允许猜错,并且猜错的代价要可控。灰度发布是最便宜的保险:新版本先放一小部分流量,看完成率、错误率、人工介入率有没有异常,没问题再逐步放大。

回滚机制要提前建好,不是出事之后再想。至少要能回答:怎么把提示词退回上一版、怎么把工具权限收回、怎么把已经产生的外部副作用撤销。最后一条最难,所以我在设计阶段就尽量让动作可撤销,比如发送类动作先发到内部草稿箱、外部提交类动作留一个撤回窗口。做不到可撤销的动作,就老老实实放到 L0 或者 L1 档位,不给它自动执行的机会。

6. 落地实操:把哲学问题写成工程清单

6.1 需求澄清阶段的检查表

每次开新项目,我会拿这张表过一遍,过不去的先别写代码。它的作用是逼着你在动手前把模糊地带挑明,而不是等上线后被用户教做人。

检查项要回答的问题不通过的后果
交付定义什么状态下算任务完成,谁来判定完成率指标不可信
红线清单哪些动作绝对禁止,由哪一层拦截提示词一绕过就出事
不可逆动作有哪些,各自怎么确认、怎么撤销一次事故毁掉信任
歧义处理三类歧义各自的默认值与追问策略大量返工与用户流失
验收标准硬性规则是什么,软性怎么抽样评好坏全凭感觉
责任链路出事后谁第一时间接手、看哪些日志复盘变成猜谜

6.2 边界约束在提示词和代码里的分工

提示词负责“引导”,代码负责“拦截”,两者边界要清楚。提示词里写清楚角色、目标、优先级编号、红线、输出格式;代码里做参数校验、权限判断、动作分级。职责混了就会两头不靠,提示词写得再细也挡不住模型换个说法,代码写得再严也管不了表达方式。

# 系统提示片段:只用编号规则,不用形容词 1. 你只能使用已授权的工具,不得尝试其他方式获取信息。 2. 涉及删除、发送、提交、付款的动作必须先给出预览并等待确认。 3. 不得修改任何输入源文件的原始内容。 4. 当规则冲突时,编号小的优先。 5. 无法判断用户意图时,先输出你的理解并请用户确认,不要自行假设。

这套写法看着朴素,但比一大段“请务必谨慎”“请注意安全”有效得多。编号规则的好处是模型能引用,日志里也能看出来它当时遵循了哪一条或者违反了哪一条。

6.3 评测集怎么造:把争议变成可回归的用例

这是我花时间最多、回报最高的一件事。做法是:每在评审会上出现一次争议,就把它变成一条用例,连同样例一起存进评测集。争论“这种请求该不该问一句”,就造一条输入,标注期望行为是“追问”;争论“这个量级该不该自动执行”,就造一条,标注期望行为是“停下等确认”。

评测集至少要包含三类样本。正常样本占大头,保证基本能力不退步。边界样本专门打那些“差一点就越界”的情况,比如金额刚好卡在上限、文件路径刚好在沙箱边缘。对抗样本模拟用户绕弯子提要求,比如用委婉说法要求删除、分步诱导越过限制。第三类最有价值,也最容易被忽略,因为它测的不是能力,是纪律。

每改一次提示词或者换一次模型,整套跑一遍,看通过率变化。有了这套东西,“哲学讨论”就变成了“回归测试”,谁也不用争,跑一遍看数据。我现在的习惯是每次改动都记录改动前后的通过率差值,超过一定跌幅的直接回滚,不解释。

7. 常见问题与排查技巧实录

7.1 症状速查表

下面这张表是我这些年攒下来的,遇到问题先对症状,能省不少时间。

症状更可能的原因处理方向
完成率虚高但用户不买账把“生成了内容”当成“完成了任务”重定义交付标准,加人工抽检
用户三次交互后流失追问过多,打断成本太高可逆动作放权,加撤销入口
偶发严重错误,无法复现日志缺上下文指纹或提示词版本补全 trace 字段,提示词进版本管理
换个模型效果断崖下跌之前依赖的是某个模型的隐性偏好把风格要求从形容词改成样例
同一需求两次输出差异极大缺默认值与范围声明补意图确认卡,显式写默认值
模型绕过限制执行了动作约束只写在提示词里把闸门下沉到工具层
评测分数上涨但线上投诉变多评测集与真实分布脱节定期用线上真实样本更新评测集

7.2 几个我踩过的坑

第一个坑是用“聪明”的标准做验收。早期我总希望 Agent 表现得像个资深员工,能自己判断该不该问、该做到什么深度。结果就是行为极不稳定,同一类请求今天问明天不问,用户完全无法形成预期。后来我把标准降到“可预期”:宁可它笨一点,每次都问同一句话,也不要它时聪明时糊涂。用户对可预期的笨容忍度很高,对不可预期的聪明容忍度极低。

第二个坑是把责任推给模型。出了问题第一反应是“模型不行,换个大的”。换了一圈发现同样的问题还在,因为根因在流程设计:没有边界、没有闸门、没有可追溯。换模型只是换了个犯错的姿势。

第三个坑是评测集只在实验室里造。自己造的样本天然偏向自己想得到的情况,线上真实分布永远更野。我现在的做法是每周从线上抽样一批真实交互,脱敏后补进评测集,尤其是那些被用户纠正过的、被中途取消的、人工接管过的,这些才是最有价值的样本。

第四个坑是忽视成本这条边界。Agent 的自主度越高,试错次数越多,调用成本涨得越快。有些看起来“效果很好”的配置,其实是靠多次重试堆出来的,规模一大就撑不住。我在定自主度的时候会把单次任务的平均调用次数也算进去,超过预算的档位即使效果更好也不用。

最后分享一个我一直在用的小技巧:给每个 Agent 配一份“行为说明书”,一页纸,写清楚它能做什么、不能做什么、卡住了会怎么办、出问题看哪里。这份东西不是给用户看的,是给团队新人看的,也是给半年后的自己看的。Agent 这类系统的行为逻辑特别容易随时间漂移——改一句提示词、换一个模型、加一个工具,整体行为就变了,而没人记得当初为什么这么设计。有一页纸在,至少能让你在想改的时候先看一眼原来的边界在哪。

我在实际项目里最深的体会是,Agent 的工程难度不在模型那一层,而在定义那一层。把“什么算完成”“什么算越界”“什么算出错”这三件事写清楚,剩下的才是调优。写不清楚,模型再强也只是把你的混乱执行得更快而已。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询