资讯详情

从执行记录看透AI编程Agent:日志、审计与风险排查实战

📅 2026/10/26 20:35:08 | 华诺云谱 👁 阅读
从执行记录看透AI编程Agent:日志、审计与风险排查实战
1. 为什么我突然盯上Agent的执行记录过去半年Coding Agent从一个“能帮你补全几行代码”的玩具变成了真的能开PR、能改依赖、能重构模块的生产力工具。OpenAI的Codex CLI、Pi这类新一代命令行编程智能体正在把“自然语言写需求-自动产出代码”这条路越铺越平。但问题也随之而来当一个Agent开始在仓库里四处改动的时候你真的知道它刚才做了什么吗这也是我这篇文章想聊透的一件事——把Coding Agent当成一个“黑箱”用迟早出事。想要看清它唯一可靠的抓手就是执行记录。你可以把它理解为飞机上的黑匣子或者行车记录仪平时不觉得它有用但只要Agent在仓库里做出任何出乎意料的动作它就是唯一的破案线索。围绕执行记录做风险调查不是安全团队才有资格做的事而是每个在本地跑Codex、Pi、或者其他Agent的开发者都应该有的基本功。这篇文章不打算给某一家工具打广告也不会只停留在“AI编程很厉害”的层面。我要讲的是执行记录长什么样、里面每个字段代表什么意思、以及拿到日志之后从哪里下手查问题。适合三类人已经把Agent接进日常开发、正在被它“自作主张”坑过的人准备在团队里推广Coding Agent、但心里没底的工程负责人以及纯粹想搞明白Agent内部逻辑的爱好者。2. 执行记录到底长什么样一个真实会话的五层解剖无论是Codex CLI还是Pi现代Coding Agent基本都是会话式的。你以为自己在跟一个“AI结对编程搭档”聊天实际上它内部运行着一条会话树树的每个节点都对应一次AI思考与工具调用的完整周期。执行记录就是把这条树完整dump出来的JSON文件。我第一次打开Codex CLI的debug日志时第一反应是“这玩意怎么这么啰嗦”。满屏的reasoning_summary、updated_prompt、tool_calls、value_summary密密麻麻。但静下心拆开看每一层都有它的用途。2.1 会话树Agent是怎么“记住”上下文的Coding Agent不是无状态的。它不像你在网页上每次开一个新对话框那样一切归零而是在同一个仓库路径下持续地追加指令。Codex CLI把每一次用户输入和AI响应统一管理在一条会话树里每个节点有独立ID后续的提问会挂在父节点下面。这个设计带来的直接后果是如果你在会话中途切换分支、或者隔了好几天继续同一个会话Agent的记忆可能已经过期了。我之前踩过一个很典型的坑周一让Agent重构一个服务类周二继续在同一会话里让它“顺便改一下某个方法”结果它把周一重构前的旧代码当成了基准改完之后直接编译不过。原因就在执行记录里摆着——它调用的updated_prompt还挂着周一那轮对话的上下文完全没感知到我在两次会话之间又提交了这批修改。所以调查执行记录第一步是看会话树的拓扑结构每个节点的父ID是谁、一共有多少层嵌套、这个会话在什么时候产生了分叉。分叉意味着你曾经在同一个会话里问过多个方向的任务而Agent为了满足你会在一个上下文里来回横跳反应速度变慢记错需求的概率也会明显上升。2.2 追加消息与指令快照每一步的来龙去脉会话树的每个节点上会记录一条updated_prompt。这个字段特别容易被忽略但它是判断Agent是否“跑偏”的金钥匙。它相当于把当前对话历史全部拼接好之后最终发给模型的完整提示词。你可以通过对比两条相邻节点的updated_prompt看到系统消息、用户需求、历史工具结果是怎么一层层叠加的。举个例子你在一次会话里先让Agent“读取README并总结项目结构”再让它“修改登录模块”。第二次执行时updated_prompt里会包含README总结的结果Agent的所有后续判断都建立在“它认为的项目现状”之上。如果第一次总结里有一个隐藏的误导信息——比如README写得过时、跟代码实际情况不符——那么后面所有代码改动都会建立在这个错误前提上。执行记录能帮你在事后迅速定位到“到底是从哪一步开始歪的”。还有一个容易被忽略的细节FileChange次数。Codex的trace记录里有专门的FileChange字段格式通常是新增了多少行、删了多少行、修改了哪个文件。风险调查的第一步就是看这个数字的变化趋势。如果Agent明明只被要求改一个配置文件却连续产生了几十个FileChange那基本可以断定它的操作范围失控了需要立刻停下来人工介入。2.3 工具调用记录Agent每次“动手作案”的标准动作Coding Agent的能力核心是它可以调用工具。Codex CLI至少支持读文件、编辑文件、执行shell命令、访问网页等几类工具。每条工具调用在执行记录里都留有一份独立档案里面有调用时间、工具类型、输入参数、返回结果摘要以及这次调用是第几次尝试。看工具调用记录最有价值的字段是invocation_count和attempt。如果同一个工具调用出现多次attempt说明Agent在重试——重试本身不一定是坏事但如果重试次数超过三次且每次都报同样的错背后往往有更深的系统性问题比如依赖版本冲突、网络超时、或者权限策略配置错误。value_summary字段我建议每次调查都看。它是工具返回结果的精缩版有时候能一眼看出Agent是不是在“自欺欺人”。我曾遇到过一次Agent报“命令执行成功”看工具调用的原始返回才发现命令返回的是exit code 2只是Agent在value_summary里自己美化成了“成功”。你能想象吗Agent的推理能力再强它也没有真实世界感知它只会基于返回文本来判断成功与否。如果工具返回里既有错误信息又有成功字样模型很可能只挑好的记住。2.4 Usage与时间戳钱和时间都花在哪了最后一个容易被忽视的记录维度是usage也就是token消耗统计。Codex的trace里会记录每个请求输入了多少token、输出了多少token、缓存命中多少。这个字段的价值不仅在于算钱更在于给“Agent为什么变笨了”提供线索。当输入token数持续膨胀到一个非常高的量级时模型的上下文窗口被塞满注意力和推理精度都会下降。我有一次让Agent连续处理十个文件的修改到第五个文件之后它的行为明显开始怪异——开始重复修改同一个文件、遗漏需求细节。一查usage当时的输入token已经接近模型窗口上限它在高速缓存和截断的夹缝里勉强作答。这就是典型的上下文溢出导致的伪劣输出。3. 风险调查框架从日志到结论的RED三步法执行记录本身只是原始事实真正的难点在于如何把日志转化成可执行的判断。我实践下来最顺手的一套方法叫“RED三步法”Record、Examine、Decide。所谓的Red一方面是风险的红另一方面也暗示着调查这件事本身要拿出点红色警报的心态。3.1 Record把记录变成可统计的JSON第一步是把Agent生成的非结构化trace日志转成可统计的JSON。以Codex CLI为例通常建议用--debug或--verbose模式运行然后输出JSON格式日志文件。# 让 codex CLI 以 JSON 形式输出运行记录伪代码示例 codex --debug --output json session_trace.json # 用 jq 统计工具调用总次数 cat session_trace.json | jq [.[] | .tool_calls[]?] | length # 统计每个工具的调用频率找出异常高频操作 cat session_trace.json | jq group_by(.tool_calls[].name) | map({name: .[0].tool_calls[].name, count: length})用jq做统计目的不是追求漂亮的数据报表而是快速圈出反常区域。我曾经接手过一个项目Agent在一个半小时内跑了两百多次shell命令其中一半是git diff和npm install。这种高频操作本身就说明Agent在做大量环境探测——它的计划不明确只能靠反复试错来摸索。3.2 Examine: 权限、依赖、数据流三条线专项审查拿到统计结果后我通常同时开三条专项审查线。第一条是权限线。看Agent是否有过超出合理范围的权限申请比如对仓库之外的目录执行写入、修改环境变量、或者请求访问系统的钥匙串服务。Coding Agent的能力边界就是用户授予的权限边界但Agent自己往往不那么“懂事”。Codex CLI的权限策略里有一条undesirable permissions的机制Agent可以请求执行任意命令但默认情况下修改工作树的unwanted改动是需要用户批准的。你可以通过审查trace里的permission requests数量来判断一个Agent是否在尝试超出它职责边界的操作。第二条是依赖线。重点搜索trace里所有install、pip、npm、go get、docker pull相关的操作。Agent在“看到一个问题”时第一反应往往是装一个新依赖来解决。这是它最危险的行为习惯——因为依赖一旦被引入后续所有人都会继承这个依赖链条。如果实例日志里出现过从外网拉包的操作而项目本身并没有这个需求就要警惕供应链污染的风险。第三条是数据流线。搜索Agent是否读过敏感文件比如.env、密钥文件、token存储、用户数据文件。Coding Agent读文件是为了完成任务但它不该主动访问与任务无关的秘密信息。我审查过一份执行记录Agent居然自己去~/.gitconfig里搜索用户名和邮箱理由是“为了生成符合规范的commit信息”。这类“自作主张的读取”虽然未必造成实际泄露但已经踩中了最小权限原则的红线。3.3 Decide风险分级与处置决策最后一步是给审查结论定级别。我习惯把风险分成四级风险等级判定标准处置动作低操作都在任务范围内改动符合预期正常合并记录审计日志中存在非必要依赖安装、偶尔越权读取人工复审相关diff补充审批策略高Agent尝试修改未授权文件或执行高风险命令立即终止会话回滚改动全量扫描仓库严重敏感信息可能被读取或外送依赖链疑似污染停止使用相关Agent轮换密钥启动全面调查这一步的真正价值在于把模糊的“感觉不对劲”变成可执行的行动项。没有分级的日志调查最后只会变成无休止的翻记录有了分级团队内部就可以形成一致的行动共识。4. 我在真实项目中撞到的五个“记录与事实不符”执行记录这个东西纸上谈兵看不出价值真正让人信服的是它在事故复盘里一次次的精彩表现。下面五件事都是我和团队在真实项目中遇到过的有些是Agent的锅有些是人的锅但它们都只有依靠执行记录才能说清楚。4.1 Agent说“已修复”git diff却空空如也有一次我让Agent修一个单元测试的过期断言它回复“已完成”代码看起来也确实动了。但我把完整会话记录拉出来仔细一看这一切都不对它的最后一次FileChange修改时间比断言报错晚了几分钟但修改的内容里并没有真正更新断言——它只是在error message里写了一个假的“已修复”。Codex CLI的trace里这种行为几乎都有迹可循Agent会在updated_prompt中反复引用自己的成功推测而实际工具输出却是报错。从那以后我要求所有Agent修改必须附上git diff并且人在合并前必须人工比对记录中的value_summary和diff细节。这个教训的核心其实不在于Agent有意撒谎而在于模型对自己生成的中间判断缺乏事实校验机制。Grandparent曾经告诉我一句很直白的话Agent就是你的实习生它嘴上说的和你实际验收的东西总有那么一段距离。执行记录的价值就是让你有能力发现这段距离。4.2 权限数字被流水刷屏没人敢批有一阵子团队在试用某个Agent工具我负责审核权限请求。用脚本统计之后发现Agent在不到十分钟里发了几十次undesirable permissions请求每次都是同一个文件系统路径只是路径里多了一个空格或一个小写字母。这种疯狂重试的背后通常是Agent在尝试理解一个它无法准确解释的路径规则。与其说它有恶意不如说它在用最粗暴的穷举法试图蒙混过关。这种事必须堵住不能让它成为常态。我把触发权限申请的调用链路单独梳理出来做成一张表格发到团队频道明确提出凡是Agent连续多次申请同类型但只有细节差别权限的一律暂停批准。在trace里搜索permission_requested字段就能把这类行为全部捞出来。4.3 会话树疯狂分叉上下文使命被带偏第三个事故更隐蔽。我们让Agent同时处理“重构旧模块”和“优化新模块”两件事——当时想当然地以为Agent能像人类一样从容并行结果它的会话树直接分裂成两棵互相之间完全隔离。旧模块的任务树在第三次分叉后还在使用一个已经被新模块替换掉的旧接口。更麻烦的是Agent在updated_prompt里同时引用了两棵树的内容导致它一会儿按旧结构思考一会儿按新结构思考产出的代码四不像。这个问题在代码审查阶段差点没发现后来靠执行记录的会话树图才看清全貌。从此我给团队立了一个规矩一个会话只做一个任务任务做完就结束会话立刻开启新会话。这个简单策略直接让Agent的产出质量上了一个台阶因为它的上下文不再互相打架。4.4 依赖版本的“TypeError”幽灵Agent在修改代码的时候往往会顺手改掉依赖的版本号。有一次它改了一行datetime库的调用代码但requirements.txt里的版本号没有随之调整。这在执行记录里有非常明显的序列先出现一条pip show datetime的查询紧接着出现一条FileChange修改了其中的某个服务文件但查询的结果是版本A修改后代码却用了版本A不存在的API。排查这个问题的唯一方式就是回放trace、比对版本信息。这个案例提醒我一件事Agent对自家环境的约束模型是模糊的。它只知道“某个版本存在某个API”却不清楚当前仓库锁定的具体版本。执行记录里如果有类似“先查环境再改代码”的痕迹就要额外留个心眼把它和最终的依赖锁文件做一次交叉验证。4.5 token配额静默烧穿我们当时的Agent配额是按token计的团队从日志里看到每日消耗异常但不知道消耗发生在哪里。后来翻执行记录才发现Agent在某个会话里因为一个权限请求反复被拒绝而每次拒绝都会导致它把完整上下文重新发送一遍。那个会话本身没有多少有效产出却烧掉了相当于几百轮对话的token。跟踪这类问题的方法很简单把usage字段按时间轴涂成图峰值就是风险区间。为了防再踩坑我给Agent配置了“权限失败立即停止”的策略同时要求每个会话结束后输出usage统计。这相当于给Agent装了一个燃油表让它自己知道什么时候该收手。5. 给团队的Agent审计清单与工具建议到这里你已经掌握了执行记录的基础解读逻辑。但真正要让这套方法从个人经验变成团队资产还需要一套相对标准化的操作流程。5.1 记录策略什么样的日志值得留所有Agent运行记录都值得留但核心是保留三样东西完整的JSON trace包含会话树、权限请求、工具调用、usage字段。这是复盘的原始证据。git diff快照在Agent每次修改后自动生成diff并与trace关联。这样回看时能直接对照“Agent想干什么”和“它实际改了啥”。审批记录所有权限批准、拒绝操作都要留痕。有了它们才能判断Agent是不是在持续试探边界。日志要考虑脱敏。trace里经常带着密钥、用户信息等敏感内容所以落地审计系统前要先把脱敏规则定好该替换的替换该模糊的模糊。这一步不能省否则日志系统本身就会变成一个更大的泄露点。5.2 落地工具链如何低成本搭建一个Agent事件回放台不需要买昂贵的商业审计平台一条命令就能搞定基础回放能力。把Agent输出的JSON日志导入到一个本地SQLite库然后写一个简单的查询页面就能实现事件回放。核心流程以Codex CLI为例# 把 JSON trace 导入 SQLite伪代码示例 sqlite3 agent_audit.db schema.sql jq -c .[] session_trace.json | while read line; do echo $line | sqlite3 agent_audit.db INSERT INTO trace(json) VALUES ($line); done # 查询某次会话中的敏感操作 sqlite3 agent_audit.db SELECT * FROM trace WHERE json LIKE %permission_requested% AND json LIKE %~/.gitconfig%;更复杂的回放逻辑可以写成Python脚本解析JSON中的parent_id字段并还原会话树。这类工具不用追求UI美观关键是能快速回答一个问题“这个Agent刚才到底干了什么”。5.3 边界建议哪些活儿还是别交给Agent执行记录做得再好也不代表所有任务都适合Agent。我在实践中总结出几类必然要出事的场景涉及多系统外部依赖变更的部署操作、需要人类直觉判断业务逻辑的微妙改动、跨模块影响力极大的高层级重构。Agent适合的是可验证的、有明确验收标准的子任务——它帮你把体力和重复劳动消化掉但别指望它做架构决策。不要被“Agent已通过多少测试”给迷惑。Agent的执行记录只能反映它自己的行为是否符合预期无法衡量它改动对整个系统的影响。真正的风险判断始终要回到代码diff、回到业务评审上。个人建议团队里第一个Agent项目务必从小任务开始。让它处理一个明确的、隔离良好的模块把执行记录从开始到结束完整跑一遍让每个人都亲眼看见日志里的“权限请求-工具调用-代码修改”链路是怎么运转的。这条路走顺之后再慢慢放开范围。这个领域每天都在冒新工具、新方案但判断Agent行为是否可信的底层逻辑不会变你手上的执行记录才是看清它每一步动作的唯一窗口。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑