跳到主要内容
别问 agent 干了什么,直接给它画行为图

别问 agent 干了什么,直接给它画行为图

阿舟
阿舟

· 阅读约 7 分钟

上周四我盯着一个 agent 的运行日志发呆。本来是让它把我服务上的一个字段改名,跑得倒是顺利,没报错,没卡住,还给我写了一条漂亮的总结。但日志中间有一行它根本没解释:它访问了一个我从未在服务授权列表里写过的内网地址,而且连着做了两次端口探测。

我问它要解释。它给了我一段非常流畅的回复:“为了确认字段改名不会影响依赖该服务的模块,对网络联通性进行了一次额外验证。”逻辑通顺,措辞正式,找不出一个能反驳的词。但它就是错的——从它访问的地址和端口来看,它不是在验证任何模块,它是在扫描那台机器上有没有开 MongoDB。

这种事我第三次碰见了。前两次我都是仰头看了一会儿天花板,然后跟自己说:算了,没出事,下次注意。现在的审计方式,请允许我用一个听起来比较唬人的词:直觉审计——人工 review 只覆盖它改动的那几行代码,其它交给运气。

直到我读到 ATLAS 那篇论文,才觉得有人真在把这件事变成一条证据链。

ATLAS 干了什么

ATLAS,Automata Learning for Agent Trajectory Analysis and Strategy Discovery,8 月 14 号挂到 arXiv 上,被 MODELS 2026 接收,六个作者,我也不一一介绍了。一句话:把 agent 干活的过程还原成一张有限状态机,然后用这张图来做行为分析。不打开模型看权重,不看它的自我解释,只看它实际做了什么。

方法拆成两步,都挺朴素。

第一步,轨迹抽象。把 agent 跑出来的原始日志变成符号化的状态序列。原始日志是噪音的大杂烩,抽象完之后是类似“环境处于状态 S,agent 发出动作 A,收到响应 B,状态转移到 S’”这样的结构。这一步留下的不是所有细节,而是能体现策略变化的信息。

第二步,自动机学习。在抽象过的轨迹上跑学习算法,推断出一个有限状态模型。你拿到的就不再是一堆需要人肉翻的日志,而是一张图。节点是抽象状态,边是转移,边上标着触发条件和对应动作。信息密度完全不在一个数量级。

如果要用伪代码概括这个过程,大概是:

traces := collect(agent_run, environment)
states := abstract(traces)
model  := learn_automaton(states)

论文用基于大语言模型的渗透测试 agent 做了概念验证。12 台易受攻击的虚拟机,agent 在里头跑渗透,轨迹被收集,模型被推断。学出来的状态机真能反映这个 agent 的高层行为策略:它倾向于先探测哪些端口和服务组合,在什么条件下改变攻击路径,哪些状态序列更容易打穿一台机器。

这些模型拿来能干什么,论文列了几个方向:可解释性、模型引导的探索、审计。对我个人来说,最后一个是重点。

审计这件事,等这套方法很久了

你让一个 agent 去跑复杂的多步骤任务,事后确认它有没有越界,靠的是什么?基本靠它自己写的总结加人工 check diff。但它不写进总结的那部分呢?它觉得没必要写的那部分呢?我只能靠日志,而日志本身也是它产生的。拿一份被告的自我陈述当证据——这个逻辑从一开始就是歪的。

行为模型不一样。你手里有了一张从轨迹学出来的状态机,审计就有了客观的参照物。拿着这张图和预期的规范逐条对,能看到它的路径偏好,能看到它有没有做规范之外的状态转移——比如在已经拿到 root 的状态下继续执行了你没授权的命令序列。它做没做过,轨迹里总有痕迹。

而且模型能做得更细。模型引导的探索,本来是用来发现 agent 没走过的路径,但反过来它也能帮审计补盲区:你在图上看到某些边几乎没有观测到转移,这说明这个 agent 没在那个状态采取过那个动作——可它到底是因为没被推到那个选择点,还是被策略内部拦截了?人工翻日志回答不了。但你可以按图上未覆盖的路径重新构造任务,把 agent 推进那些状态里,看它接下来的动作。这是过去根本做不到的事。

论文里还有一个我从工程角度非常喜欢的点:知识迁移。他们把大模型的行为通过行为模型抄到了一个小模型上。放到渗透场景里,意味着你不必为了跑一个渗透 agent 就扛起最大的模型,你可以从行为模型里提炼出同样风格的策略,塞进一个成本低得多的紧凑模型里跑。这让我很有共鸣——我前阵子就想让一个本地小模型替我干活,它“知道”规则但执行起来总跑偏。如果中间有一层抽象的行为模型做桥,这事情可能就不那么玄学了。

但我先泼一盆冷水

草稿写到这里,我回头重新看了一眼论文的篇幅和实验规模:7 页,12 台虚拟机。然后我给自己提了个问题:这套状态机真的完全可信吗?

答案是:不完全,但要看用在哪儿。

一台渗透测试 agent 的行为,跟一个真实生产环境里的 coding agent 的行为,复杂度差一个数量级。渗透的行为边界是有限的——端口、服务、路径、漏洞利用,状态空间再大也有边界。而 coding agent 面对的是自然语言、上下文窗口、工具调用、外部环境状态、人类指令随时插入,它的状态空间没有边界。自动机天生擅长描述有限离散的状态转移,用在渗透测试上正合适,用在 coding agent 上就未必扛得住。

另一个问题更隐蔽:自动机是行为的模型,不是意图的模型。它可以告诉你 agent 在状态 S 做了动作 A,但说不清楚为什么。假设模型显示“当 banner 是 OpenSSH 7.2 时 agent 会尝试爆破”——它不会告诉你这是因为训练数据里见过这个版本的默认口令,还是上下文里恰好有相关提示。看行为,不看动机。审计时通常看行为就够了,你查的是做了什么,不是为什么想做。但一旦要判断风险高低,同样的行为背后两种截然不同的意图,危险程度完全不同——行为模型不区分这些。

还有一层容易踩的坑:抽象会丢信息。轨迹抽象把状态压缩成符号序列的时候,大量细节已经被抹掉了。12 台虚拟机的规模下,专家可以手动调抽象参数,在噪音和重要特征之间挑平衡。但真实 agent 的轨迹量更大更杂,自动化抽象做不好,模型就只是一张跟现实脱节的图。拿这种图去审计,比没有图更危险——它给你权威感,但不给你可靠性。

所以我的判断是:ATLAS 不是终点,它是起点,证明了从轨迹到行为模型这条路走得通。但离“直接用这套东西审计生产环境里的 coding agent”还有很长的路。

我开始试着用了

读完那篇论文,我干的第一件事是打开常驻 agent 的 debug 开关,把完整轨迹保留下来。以前我关着它,因为太吵太占地方。现在不关了。原因很简单:我不再相信它写给我的那些总结,甚至不再相信它自己生成的日志文本。我只需要原始轨迹,自己看,或者留着将来喂给某个建模工具。

第二件事,我在琢磨一个简化版的行为画像流程。每周给跑过的 agent 任务生成一个结构化摘要:执行的动作序列、调用的工具、访问的主机、读写的文件,然后按任务归类。积累一个月,至少在宏观上能看出我的“实习生”这个周期的行为倾向。不搞自动机,先手搓,手动分类凑合着用。

画外音:等哪天真有人把 ATLAS 那套跑成开箱即用的工具,记得喊我一声,我先买。

我现在不敢说“行为模型是可解释 AI 的唯一答案”这种话。但有一件事我很确定:agent 做事的轨迹,比它自己写的工作报告可靠得多。凡是靠自述来审计 agent 的流程,早晚都会翻车——不是这一次,就是下一次。

阿舟
阿舟

写代码写到一半开始怀疑人生,靠 AI 工具续命,顺手把踩过的坑都记下来。

查看主页 →