吴师兄学大模型公众号文章

面试官问:“Agent 项目,怎么证明任务真的完成了?”我:“它说完成了。”他:“你这是验收,还是听它汇报?”

吴师兄学大模型

公众号 · 10 篇文章

用户给 Agent 一个任务:“查一下这项技术的主要方案,整理成飞书文档,发给我。”

几分钟后,聊天窗口里出现了链接,最后一句是“文档已创建,可以查看”。如果把这个项目写进简历,接下来有个问题很值得准备:你凭什么判断它完成了?

链接能打开,正文可能只写进去一半;正文完整,引用可能对应错了;服务账号能读,接收者可能没有权限。每一步都返回过成功,用户仍然可能拿不到想要的东西。

做 Agent 项目时,我会先把“完成”拆开。模型结束回复、工具执行结束、用户目标满足,分别需要证据。把这三件事讲清,工具调用、异常恢复和评测才有共同的落点。

一个文档链接,背后有几次独立操作


先顺着这个研究助手走一遍。模型决定查什么,搜索工具返回候选,网页工具取回正文。模型整理材料,然后请求文档工具,把标题和内容交过去。

文档工具通常还要继续做几件事:创建文档对象,把内容转换成平台接受的块,分批追加正文,再给指定接收者配置访问权限。最后,它才能拼出一个链接,交回 Agent。

这条链路里,前一步成功不会自动保证后一步成功。 创建接口拿到了文档 ID,只能说明一个文档对象已经存在。后面的正文写入和权限设置,仍然各有自己的结果。

例如,正文被拆成几批,第一批写入成功,第二批报错。此时远端可能留下半篇文章。若错误处理中只剩一句“文档创建失败”,恢复程序连该接着写哪份文档都不知道;若只根据最早拿到的 ID 报成功,又会把半成品交给用户。

面试里说“我接了搜索和飞书 API”,还没有解释这段交付过程。能补上哪些操作可能部分成功、每一步留下什么状态,项目就开始有了可检查的细节。

创建、写入、分享各有自己的结果

创建、写入、分享各有自己的结果

success 字段,究竟在替谁作保证


很多工具接口会返回 success、data、error。这套结构很方便,但需要问一句:谁设置了 success,它检查过什么?

有的执行器在函数没有抛异常时,就把 success 设为 true。它证明函数顺利返回。至于返回值里有没有业务错误、是否只受理了异步任务、数据是否满足当前目标,还需要继续判断。

可以把成功分成三个层次。调用层检查工具名和参数是否合法,执行层检查服务有没有按接口契约处理,任务层检查得到的结果能否兑现用户要求。

放回文档例子:参数中的标题和正文通过校验,属于调用层;创建和追加接口返回符合契约的结果,属于执行层;正文齐全、引用对应、接收者能访问,才进入任务验收。

工具输出里的数字也要看来源。比如 blocks_created,如果它只是转换后准备发送的块数,便不能拿来证明远端已经保存了相同数量。这个字段记录的是本地计划,不包含独立读取的证据。

因此我会把返回结构改得更明确:保留文档 ID、每个批次的状态、权限处理结果,以及后续验收结果。一个总 success 可以留给上层使用,但它的计算规则必须清楚,不能在几个不同层次之间漂移。

调用通过、执行通过、任务完成需要不同证据

调用通过、执行通过、任务完成需要不同证据

验收条件,要在写入之前定下来


等模型说“好了”再让另一个模型打分,很容易把验收变成读后感。它可能喜欢文章的表达,却看不到远端缺了最后一节。

对于这个任务,可以先约定几条具体条件:文档标题对应当前任务;正文包含要求的方案比较和结论;关键引用能回到支持它的资料;指定接收者获得约定的访问权限。用户要求表格、代码块或图片时,再增加相应格式条件。

这些条件各有检查方法,不必全部交给模型。

写完后,用已经保存的文档 ID 读取远端正文。对本次生成并确认的内容,先做必要的规范化,再核对章节、关键段落和顺序。平台可能调整换行和空白,直接比较原始 Markdown 的字节哈希,容易把正常转换判成失败;只检查“正文不为空”,又会放过大量缺漏。

纯文本读回能发现内容缺失,却看不到所有格式。若任务要求保留表格或代码块,就需要读取块结构,核对对应类型和内容。读取接口有分页时,还要遍历全部结果,不能把第一页当成整篇。

引用则需要另一项检查:来源存在,只能证明链接可访问;那条材料是否支持正文里的判断,还要核对相关内容。模型适合参与语义检查,但检查输入应是实际取回的资料和正文,不能只看自己写的总结。

权限也要单列。应用凭自己的 token 读到了文档,说明应用能读。接收者是否能访问,需要按目标用户和约定权限核对;条件允许时,再从接收者身份验证。不能把服务账号的能力直接算到用户头上。

这样,验收的开销可以随着交付要求变化。简单备忘录重点查内容和访问权限;带结构化表格的报告增加格式检查;需要据此作判断的研究文档,还要检查关键结论的证据。检查范围来自任务要求。

验收还要绑定当前版本。模型曾经生成过一份完整正文,不能证明最后提交的就是那一份;第一次读回通过,也不能替后续改写作保证。可以在任务记录里保存本次预期内容的摘要标识、目标文档和读回时间。正文变化后,只复查受影响的内容与格式,避免拿旧检查结果给新版本盖章。

中间超时,先找回已经发生的事


现在把例子改一下:创建文档已经成功,追加正文时网络超时。下一步该怎么办?

直接从头调用“创建并写入”很危险。第二次可能再建一份文档;如果第一次追加请求实际上已经执行,只是回执没到,重放还可能把同一段正文写两遍。

超时说明调用方没等到结果,不能据此断定远端什么都没做。 恢复时需要面对“结果未知”这个状态。

任务开始时,先为本次业务意图建立稳定标识,并记录它与文档 ID 的关系。这个标识应覆盖所属用户或租户及具体任务;用户明确要求另建一份时,是新的业务意图,不能错误地复用旧文档。

拿到文档 ID 后,及时保存每批写入的内容标识和进度。恢复程序优先读取这份文档,确认哪些内容已经存在,再决定续写、等待还是交给人工处理。不能只凭本地“准备发送了”就把批次记成完成。

这里还有一个容易答漏的竞争条件:第一次请求可能仍在执行。此时读到某段尚不存在,也不必然意味着可以立即再追加。需要结合下游的幂等能力、操作状态,或可确认完成的对账方式,控制重放;缺少这些条件时,应暂停自动写入,避免制造重复内容。

入口消息去重只能解决其中一部分。进程内缓存记住某条消息处理过,不代表重启后仍记得,也不覆盖模型主动再次选择同一个写工具。业务动作的去重和恢复,需要落到持久状态与下游操作语义上。

超时后先对账,再决定续写或暂停

超时后先对账,再决定续写或暂停

Agent 停下来,也要交代停在什么状态


为了防止无限循环,给工具轮次设上限很常见。但上限只回答“最多执行多少轮”,并不回答“事情有没有做成”。

若最后一轮刚好耗尽,文档仍缺一节,系统应把它记为未完成,并保存缺口和恢复入口。若正文完整但权限配置失败,则是内容完成、交付受阻。只有必需条件都满足,才汇总为任务成功。

最终回复也应该从这些状态生成。正文已保存、分享失败,就说文档已保存但访问权限尚未配置完成;写入结果未知,就说明正在核对,别提前承诺已经交付。

模型仍然负责组织语言和调整任务路径。只是“已完成”这几个字,需要以执行记录和验收结果为依据。运行结束时,可以留下一份简短记录:目标文档、已完成步骤、待处理项、验收证据,以及本次结束原因。

这份记录对排查很有用。用户说少了一节时,可以直接确认远端版本、写入批次和读回内容,无须先猜是哪句提示词写得不好。后续评测也能区分内容质量问题与交付问题。

用故障样本证明你真的管住了交付


如果要把这套设计讲成项目经验,我更想看异常输入下的结果,而不只是一次顺利演示。

可以先做一个小型故障注入:把文档客户端替换成可控的假服务,让创建成功、正文追加超时。观察下一次恢复是否复用原文档、是否先核对远端内容,再模拟“正文已经写入,但回执丢失”,检查会不会重复追加。

接着测试正文完整但分享失败,确认总状态没有被误记为成功;让模型持续调用同一个工具直到轮次耗尽,确认系统保留未完成原因;再让远端返回空正文或缺少最后一批,确认验收能够拦住。

每个样本都要看实际状态和远端副作用。测试进程正常退出、模型最后写了一段解释,都不能替代这些观察。假服务能把故障时序做得可重复,接入真实平台后,还需要在受控文档上验证分页、权限和格式转换。

做评测时,把“运行结束率”和“任务验收通过率”分开记录。前者反映系统能不能给出结束状态,后者反映交付是否满足要求。再把未完成按内容缺漏、权限受阻、结果未知和预算耗尽分组,才能决定下一步该修写入链路、恢复策略还是模型规划。只报一个总成功率,这些问题很容易混在一起。

验收要能拦住部分写入、权限失败和轮次耗尽

验收要能拦住部分写入、权限失败和轮次耗尽

讲到这里,面试回答就可以落得很具体:

我把文档交付拆成创建、内容写入、权限配置和验收。工具返回链接后,按同一文档 ID 读取远端内容,核对任务要求;格式和接收者权限分别检查。写入超时先进入结果未知,结合持久进度和下游状态对账,避免从头重建或重复追加。工具轮次耗尽记为未完成,成功状态由验收条件汇总。

这段话里的每个判断,都应该能回到你自己的实现和测试。先挑一个会产生远端变化的工具,画清它的部分成功状态,再补一个“请求做了,回执丢了”的故障样本,比继续往 Agent 里堆工具更能帮助你理解整个项目。

2026大模型/Agent 1v1求职陪跑营

前往微信阅读全文

内容来自公众号,可前往微信查看原文。

查看作者的更多文章 →订阅更新、RSS 与阅读指南 →