先说一个最近的经历。我让一个Agent批量处理几十份客户报表,第一步数据清洗、第二步字段映射、第三步汇总计算,看起来流程很顺。结果它在一个日期格式转换上出了错,后续所有汇总全部错位,我直到第二天跑完下游任务才发现。这种场景,做过Agent相关工作的朋友应该不陌生:Agent在单步任务上越来越可靠,一进入长链路、多工具、多步骤的场景,就像个容易走神的新人——平时挺机灵,偶尔捅个大篓子,而且你没法24小时盯住它。
AgentForesight这个项目,就是冲着这个问题去的。我们用NeurIPS 2026投稿的口径,做了一个7B规模的过程审计模型,让它在Agent执行任务的同时在线盯盘,实时评估每一步有没有跑偏,在错误被写入最终结果之前先抓出来。这篇内容我会把整个方案的动机、设计、训练数据构造、部署接入和踩坑记录全部拆开讲,适合正在做Agent应用落地、或者在搞Agent安全与可控性方向的朋友参考。
1. 这事为什么非管不可:自主Agent的“慢动作翻车”
1.1 长链路任务里的错误雪崩
Agent和普通程序最大的区别在于,程序的每一条分支都是人预先写好的,而Agent的行为是模型根据当前观测实时生成的。短任务里这个特性是优势,长任务里就成了风险源。
一个典型的多步骤任务,比如“帮我查一下三家供应商的报价,对比后生成一份推荐报告,并发送邮件给项目组”。这个任务拆解开至少有七八个关键步骤:确认报价表格的列含义、判断哪些产品规格对齐、做价格归一化、生成对比结论、写邮件正文、选收件人。任何一个步骤出现理解偏差,后面的步骤都会基于错误前提继续推进,而且Agent在生成后续内容时并不会主动去校验前面步骤的对错。
这就是我常说的“错误雪崩”。单步错误率如果是2%,两步叠加就是4%,十步关键路径叠加下来接近20%。在实际项目里,这个数字只会更高,因为Agent的中间推理通常没有显式校验,错了也是顺着往下写。很多时候任务最后的结果看起来完整、格式正确,但里面的数值、引用、结论全是基于一个早期错误状态推出来的。这种失败最阴险的地方在于:它不是直接报错,而是把错误包装成了看起来没问题的结果。
1.2 现在常见的监督手段,三个都不太够
我先说说市面上已有的监督思路,这样你才能理解AgentForesight的定位。
- 人工抽查:让人定期查看Agent的日志和中间结果。问题是速度完全跟不上Agent的执行节奏,而且人看日志天然倾向于“只关注最终结果”,中间步骤里那种“看似合理但方向偏了”的状态很难被及时发现。
- 确定性规则校验:比如规定日期格式必须是YYYY-MM-DD、数值必须在某个阈值范围内。规则能抓住机械性错误,但抓不住语义性错误。比如Agent把“A供应商报价含税、B供应商报价不含税”直接拿去做大小比较,规则匹配不到这种场景。
- 用更大的通用模型做审查:让强模型在Agent执行后重跑一遍或打分。问题在于延迟高、成本高,而且通常只能在任务结束后给一个总体判断,做不到“边执行边纠偏”。
三个方案的核心缺口是同一个:缺少一个轻量、实时、低成本的过程监督层。Agent在执行过程中需要一个“在旁边看着的同事”,而不是“事后写报告的质检员”。AgentForesight就是把这个缺口的解决方案做成一个可落地的7B模型。
2. 为什么让一个7B小模型当审计员
2.1 大模型审计员的成本算一笔账
有朋友一上来就质疑:要抓Agent的错误,直接用当前最强的通用大模型来审计不就行了?话是没错,但你实际跑一下就知道了。
假设一个Agent任务有20个中间步骤,每步推理大约消耗1200个token,如果审计模型每次都读入完整历史再评分,单次调用的上下文可能超过8000到10000 token。用商用大模型API的话,一次调用的成本在几厘到几分钱,看起来不多,但你要乘上重复调用次数和并发量。一个一天处理2000个Agent任务的中等场景,光审计费用就是一笔不小的运营开销,而且审计过程给Agent链路增加的一次往返延迟至少在3到5秒。
这不是成本敏感与否的问题,而是架构合理性。让一个几十B甚至上百B参数的模型在每个Agent步骤后面都跑一次,相当于给每个环节配了一个重型审核组,流水线根本转不快。
2.2 7B的效率边界在哪
7B这个规模不是拍脑袋定的,我大致算过这么一笔账:在量化到INT8之后,7B模型在单张中端显卡上的推理延迟可以控制在几十毫秒到一百毫秒出头,配合流式批处理,完全能跟上Agent的实时执行节奏。
更重要的是,审计任务本质上是一个“判别式”任务,它不需要像生成式Agent那样具备开放式创造能力。审计员要做的是判断当前轨迹是不是异常,而不是自己规划下一步怎么做。判别式任务的信息密度需求远低于生成式任务,打个比方:改作文的老师不一定自己作文写得比学生好,但他能准确说出哪里跑题了。一个7B模型在大量错误轨迹样本上做判别微调之后,完全有潜力在审计这个窄任务上达到甚至超过大模型的事后审查效果。
2.3 审计目标怎么定义:过程评分而不是结果评分
这块是方案设计里最关键的取舍。最初的版本我们尝试过让审计员直接对最终结果打一个“正确/错误”标签,但很快发现这有几个问题:第一,结果正确不代表过程正确,中间步骤可能用了错误假设但最后凑巧输出对了;第二,结果错误时你根本定位不到是哪个环节出了问题;第三,Agent执行过程中根本还没有最终结果,你要做到在线抓错,就必须评估“进行到一半的轨迹”。
所以AgentForesight的审计目标是过程评分:对每一步给定当前观测、历史动作、中间推理,输出一个异常概率分数和错误类型标签。这样做的直接好处是,审计员可以在错误刚出现时产生信号,而不是等错误发酵成灾难。
3. AgentForesight的核心设计:在线抓错是怎么做到的
3.1 输入信号:从观测空间到推理轨迹
所谓在线抓错,第一件事是确定审计员的输入应该长什么样。我们在实际项目里发现,只给审计员看Agent的策略记录是不够的,因为策略记录只包含它做了什么,不包含它看到了什么、在想什么。
AgentForesight的输入格式包含三个部分:
- 环境观测摘要:当前轮次Agent收到的工具返回、数据库查询结果、或页面解析内容。这部分是关键,因为很多错误其实是对观测内容的错误解读。
- 动作与工具调用记录:Agent刚刚执行了什么操作,调用哪个工具,传了什么参数。
- Agent的中间推理:也就是Agent自己的思考链。这个信号非常重要,错误往往在推理阶段就已经出现,比如Agent在推理里写“我认为这两个价格可以直接比较”,但实际两个价格的口径不一致。
在实现上,我们把这三部分按时间顺序拼成一个结构化的审计条目,滑动窗口覆盖最近的若干步,既保证了上下文相关,又控制了输入长度。
3.2 错误预测机制:过程评分+置信度
审计模型会对当前轨迹窗口输出三样东西:异常概率、错误类型分布、预测稳定性。异常概率不是简单二分类,而是连续分数,这样下游可以根据风险偏好调阈值。错误类型则帮助后续决策——这个错误是工具调用参数传错了,是观测解读偏了,是推理步骤逻辑跳了,还是行动跟推理不一致。
置信度这里我想多说两句。即使是一个专门调过的审计模型,也不可能对每条轨迹都有十足把握。AgentForesight训练时用到了MC Dropout采样,推理时对同一个输入做多次前向计算,用输出分布的方差作为置信度参考。如果异常概率接近阈值但置信度很低,审计端会选择“暂不干预,继续观察”,避免误伤正常轨迹。这个机制在实际运行中极大减少了非必要的中断。
3.3 干预接口:中止、回滚、提示修正
在线抓错不能只是“吹哨”,抓完你得有干预手段。我们设计的干预策略分三档,按错误严重程度自动选择:
- 低频告警:异常概率超过60%但不足80%时,只记录日志并在任务结束后汇总给开发者,不打断Agent流程。
- 单步回滚:异常概率超过80%时,Agent回到上一步的检查点,审计模型把错误类型转成提示信息,让Agent重新推理和行动。
- 终止执行:异常概率超过95%时,属于典型的方向性错误,继续跑只会浪费时间和产生坏数据,系统直接终止任务并触发人工复核。
这种分级干预设计给了系统一个降级路径:不是所有错误都用最重的手段处理,也不是所有错误都能放过。实操下来,单步回滚是最有价值的一档,因为它相当于给Agent装了一个“做错了就重来”的机制。
下面这个检测循环是系统的主干逻辑,简化后大概是这样的:
async def audit_loop(agent_session): while not agent_session.finished(): step = await agent_session.next_step() audit_input = build_audit_input(step.observation, step.actions, step.reasoning) anomaly_score, error_type, confidence = auditor_model.predict(audit_input) if confidence < 0.3: continue # 置信度不足,继续观察 if anomaly_score >= 0.95: await agent_session.terminate("方向性错误", error_type) elif anomaly_score >= 0.80: await agent_session.rollback_and_correct(error_type) elif anomaly_score >= 0.60: audit_logger.warn(step, anomaly_score, error_type)4. 训练数据与模型实现:没有现成数据集怎么办
4.1 合成错误注入
做审计模型最大的拦路虎是数据。你找不到一个现成的、带“错误轨迹标注”的数据集,因为Agent的轨迹本身已经很难采集,再给每条轨迹的人工标注错误位置,成本直接起飞。
我们采用的是合成错误注入策略。思路是:先跑出大量正常的Agent轨迹,然后在轨迹的随机位置人为制造错误,生成对应的负样本。
错误注入分成四个层面,对应真实场景里最常见的四类失败模式:
| 错误类型 | 注入方式 | 训练目标 |
|---|---|---|
| 工具参数错误 | 篡改工具调用的某个参数,如把日期参数从3月改成4月 | 识别参数与原始观测的不一致 |
| 观测解读错误 | 修改观测摘要里的某个数字或字段,让Agent后续基于错误信息推理 | 识别推理与观测之间的矛盾 |
| 逻辑跳步 | 删掉某一步推理,让Agent直接跳到结论 | 识别推理链的断裂 |
| 动作与意图不一致 | 保留Agent推理内容,但替换它的最终动作 | 识别意图与行动之间的偏差 |
每一条注入轨迹我们都记录注入位置、类型和原始真实值。这样训练标签就是现成的:审计模型要预测当前位置是否存在错误,以及是哪个类型的错误。
4.2 轨迹采样与标签构造
正常轨迹怎么采?我们搭了一套真实任务环境,包含了表格处理、信息抽取、多步API调用、报告生成这几类任务。每一类任务设计了几十种不同参数组合,让Agent在多种输入下各跑多轮,收集成功轨迹和失败轨迹。失败轨迹不是直接丢掉的,它们对训练很有价值——失败轨迹里往往藏着真实的错误模式。
训练样本的长度和数量也很重要。一开始我们试图把整条轨迹都塞给模型,结果上下文爆炸,训练出来效果也不好。后来改成滑动窗口采样,每条样本只包含最近5到8步的审计条目。窗口内的正常前缀就能给模型提供对照基线,错误点作为预测目标。这样样本的数量从“任务数”变为“步数”,数据量一下子翻了几十倍。
4.3 微调与部署的实操参数
基座模型我们选了一个7B参数量的开源模型,没有选择更大的版本,主要是想在单卡部署和效果之间找平衡。微调用LoRA,配置如下:
- 秩:64,低于这个值审计效果掉得比较明显,高了没有太多收益反而增加显存。
- 学习率:1e-4,配合cosine退火。
- 训练数据:约八万条轨迹窗口样本,正负样本比例大约1比1.2。负样本略多是故意的,因为审计任务本质上是在异常少发的场景里找异常,多一点负样本能让模型对错误特征更敏感。
- 训练轮数:2轮。超过2轮开始过拟合,在未见过的任务类型上漏报率回升。
部署上我们用vLLM做INT8量化推理,单卡每秒处理约350条审计条目,批处理下单条审计时延约60毫秒。这个延迟对Agent执行链路基本没有感知,审计可以做成异步低优先级任务,不影响主流程的响应速度。
5. 实测复盘与常见问题
5.1 误报率与漏报率的权衡
实测中最大的调试点是阈值。一开始我们咬死95%才算终止,90%才算回滚,结果漏报率很高,因为不少真实错误在早期表现得很隐蔽,异常概率也就85%上下。后来我们把回滚阈值放到80%,终止阈值维持95%,但配合置信度过滤,误报率并没有明显上升。
阈值调节的时候要画一下混淆矩阵,我自己的经验是先保住漏报率。漏报一个错误可能导致整条任务最终的产出完全不可用,损失比“多回滚一步”大得多。误报最多浪费一次重试,漏报是对下游的持续污染。
5.2 Agent会“躲着”审计员吗
这是个特别有意思的问题,实际跑下来确实存在。当Agent的提示词里明确写了“你的每一步会被审计模型检查”之后,部分Agent的行为会变得更保守——多问几句、把简单动作拆成好几步、不敢批量处理。看起来好像更安全了,实际上效率下降,而且有些步骤为了“显得合理”反而产生了更多冗余推理。
处理这个问题不能靠藏。藏审计信号只会让Agent回到原来的行为模式,密谋错误重新出现。我们最后的方法是:提示词里不写审计的存在,但保留单步回滚的接口,由沙箱层直接重放Agent的上一步。对模型来说就像环境抖动了一下,对任务来说错误被纠正了。这套隐形纠错机制目前看效果比较稳定。
5.3 上下文窗口不够长怎么办
AgentForesight的审计条目本身包含了历史窗口,如果Agent任务特别长,历史摘要会逐渐占据大量上下文。我们做了两层处理:
- 窗口内压缩:超过8步只保留最近的4步完整条目,更早的内容用生成式摘要替代。
- 阶段级审计摘要:每个子任务完成时,审计模型单独输出一段“该阶段异常摘要”,这个摘要跟随全局上下文,供后续阶段参考。
实际效果上,压缩对审计准确率的影响控制在2%以内,但上下文token开销下降了近四成。如果你在自己的场景里复现,建议先从“只保留最近4步”开始测,不要一上来就压缩,这样可以先建立基线再做对比。
5.4 排查速查表
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 审计时延高 | 批处理未开启、量化精度过高导致吞吐下降 | 开启动态批处理,INT8量化,必要时用投机采样加速 |
| 误报集中在某类任务 | 该类任务在训练数据中比例偏低 | 补充同类任务的正常轨迹样本 |
| 漏报严重 | 终止阈值过高或置信度过滤过于保守 | 降低回滚阈值至80%,观察置信度分布 |
| 干预后Agent重复犯同一个错 | 回滚没有清除错误状态,比如缓存或工具状态残留 | 检查检查点机制,确保回滚时清干净影响状态 |
| 审计结果飘忽不定 | MC Dropout采样次数太少 | 采样次数提到5到8次,或训练时提高Dropout率 |
最后分享一个我自己的体会
调试审计器阈值那几天,我最大的感受是:不要把它当成一个打分器,要把它当成一个“有经验的盯盘同事”。7B模型在单步判别上确实很能打,但它不会告诉你“这次建议你为什么这么给”。所以部署审计器的时候,日志一定要把异常类型、窗口摘要、干预动作放在一起打出来,方便后面人看。只要你能解释清楚每一次干预是因为什么触发的,这整套系统就能从“玄学监控”变成真正可控的Agent安全层。以后我们在项目里又陆续接入了对工具调用返回值的校验器,但论性价比,还是AgentForesight这个在线审计思路最值得先做。