从30个文件到2个文件——我如何把Agent强制系统瘦身90%

「如果我需要记住去跑引擎,那这个引擎就不该存在。」 前文(第7篇)我们搭完了4条AI流水线,构建了从内容生成到异常监控的完整链路。架构跑起来了,但代码量也上来了。 在搭建了持久状态、质量体系和运维监控之后,我的Agent工程化体系自然而然地膨胀了。倒不是代码写得差——是功能越多,文件越多。三个月后,这套体系膨胀到了30+个文件——各种引擎脚本、注册表、校验脚本、配置映射文件……它们互相引用、互相依赖,改一个就要联调五个。 不再「轻量」了。不再「物理」了。 所以上个月我做了一个决定:全部重写。把五道闸的30+个文件删掉28个,保留2个文件+2个脚本。 这篇文章就是这次瘦身的完整复盘——不是删减,是重构。 一、问题:30个文件的强制系统,本身就是个包袱 在搭建了持久状态、质量体系、运维监控之后,我自然地想到一个更深层的问题:如何确保Agent每次都按照规矩执行? 回答这个问题的最初方案是"三道锁"——入口锁、会话隔离、前置检查:

拦截点做什么
EntryGate入口复杂任务不分解,拒绝执行
会话隔离路径多会话互不覆盖
前置检查质量真实读文件,状态比对

后来加了第4道闸(终态检查)和第5道闸(异常告警+持久化),变成五道闸。 五道闸体系工作得很好——违规率降到0,异常自动告警,跨会话持久化。但它有一个致命问题:它需要Agent记得去跑它。 五道闸的实现是一套独立的 Python 引擎——loop_engine.py。Agent 要在每次执行前加载引擎、注册规则、初始化状态、跑 step gate、跑 terminal check。如果 Agent 忘了加载引擎——引擎根本没启动过——那五道闸就是一纸空文。 更糟糕的是,这套引擎本身有30+个文件。当时的大致结构是这样的: hermes-harness/├──loop_engine.py#主引擎(200行)├──skill_registry.json#技能注册表├──violations.json#违规持久化├──gates/#6个门控文件├──scripts/#7个校验脚本├──config/#4个映射配置文件└──STATE.md#状态文件 30+个文件相互引用。改一个脚本,影响5个gate。每次重构都要翻一遍整个目录。 五道闸解决了一个问题,但创造了另一个问题。 二、核心洞察:物理强制不在代码里,在prompt里 重构前我问了自己一个关键问题:五道闸的本质是什么? 它是一堆 if 和 raise ——在代码层拦截 Agent 的非法行为。但代码拦截有一个前提:Agent 必须处于代码执行的环境中。 如果 Agent 换了会话、换了模型、或者根本没有调用 loop_engine.py,那所有物理强制全部失效。 真正的物理强制不在代码里,在prompt里。因为prompt是每次对话自动注入的,不需要Agent主动加载。Agent 可以忘记跑引擎,但不能忘记看prompt——prompt里的指令在第一轮就用上了。 这个洞察带来了整个新体系的设计: 旧体系:提示词 → 规则 → Agent 记得加载引擎 → 代码执行强制 ↓ 如果 Agent 忘了 → 强制失效 新体系:SOUL.md 铁律(prompt注入) → 规则在Agent眼前 → 自动生效 ↓ 不需要Agent记住任何事 所以新体系只有2个文件和2个脚本。不需要引擎。 三、新体系:2文件 + 2脚本 文件1:SOUL.md(系统级铁律,243行) SOUL.md 是 Hermes Agent 每次会话自动注入的系统级prompt。它包含17条铁律,从"永远不要虚构数据"到"必须在第一轮执行任务"。 关键不是铁律的数量,而是它怎么被加载——不是 Agent 主动去读的,是 Hermes 的会话初始化机制自动注入的。Agent 每次开口之前,SOUL.md 已经躺在 context 里了。 SOUL.md 的加载方式——不需要Agent记得做任何事# Hermes 每次新会话自动读取并注入 prompt $cat~/.hermes/SOUL.md|head-10 # SOUL.md — System Operating Universal Law# 本文件是 Hermes Agent 的系统级铁律。# 每次新会话自动注入,不可跳过,不可覆盖。# 违反任意一条 = 系统拒绝执行。## 铁律 1: 事实优先# 永远不要虚构任何数据、代码、执行结果、API响应。## 铁律 2: 没有步骤门控# 直接执行任务,不要等待「步骤确认」。 旧体系用30个文件来强制的规则,现在写进prompt里——更轻量、更物理、Agent 无法绕过。 文件2:.hermes.md(项目级SOP,127行) SOUL.md 管全系统,.hermes.md 管单个项目的 SOP。 .hermes.md 示例(项目级约束)rules:-name:maker-checker-separationrule:"同一个Agent不能同时做Maker和Checker"severity:BLOCKER-name:commit-protectionrule:"永远不直接push到main分支"severity:ERROR SOUL.md + .hermes.md 替换了旧体系里的5个文件: - skill_registry.json(10种技能映射) - allowed_transitions.json + forbidden_transitions.json(步骤白名单/黑名单) - role_configurations.json(角色配置) - 3 个 check_*.py 前置校验脚本 5个文件被2个文件替代。 脚本1:check_completion.py(终态检查) 这是唯一保留的第4道闸——终态检查器。但我把它从 Python class(需要engine实例化)改成了3个 CLI 命令: 创建一个新任务 $check_completion.pycreatetask-42 ✅任务task-42已创建 # 查看任务状态 $check_completion.pystatustask-42 任务:task-42 状态:running 执行成功:None 推送状态:None # 确认任务完成——三个物理条件缺一不可 $check_completion.pydonetask-42 ❌终态检查不通过: -push_status不是PUSHED -push_receipt为空 核心逻辑只有三个判断: defcmd_done(task_id): 检查三个条件:# 1. 任务确实执行成功# 2. 代码已提交推送# 3. 有推送凭证ifnottask.get("execution_success"):violations.append("execution_success 不是 True")iftask.get("push_status")notin("PUSHED","PUSHED_WITH_CHANGES"):violations.append("push_status 不是 PUSHED")ifnottask.get("push_receipt"):violations.append("push_receipt 为空")ifviolations:# 打印失败原因,返回非零退出码sys.exit(1)# 全部通过 → 标记完成task["status"]="completed" 旧体系的 TerminalStateChecker 是一个需要实例化的 class,靠 engine 来调用。新体系是 3 个纯 CLI 命令——从任何终端都能跑,不需要 import engine,不需要加载环境。 脚本2:send_alert.py(异常告警) 旧体系的第5道闸是一个包含5条规则的异常引擎,需要在后台跑进程、定时扫描。新体系是 2 个 CLI 命令: 当任务卡住或状态异常时触发 $send_alert.pychecktask-42 [WARNING]任务task-42已运行25分钟,超过超时阈值 [ERROR]任务task-42执行成功但checker未派发 # 批量扫描所有活跃任务 $send_alert.pyscan 扫描3个活跃任务:发现1个异常 -task-42:超时(25m>20mlimit) 从定时后台进程 → 按需触发的 CLI 命令。不是能力变弱了,是去掉了复杂度——Agent 在任务结束时主动调 send_alert.py check,不比后台轮询差,但少了一个常驻进程。 四、前后对比

维度旧五道闸新体系变化
文件数30+2文件+2脚本−90%
引擎200行核心完全删除
规则注册JSON注册表SOUL.md铁律合并
步骤门控代码+配置文件不需要删除
终态检查class实例化CLI命令简化
异常告警后台进程CLI命令简化
持久化2个文件1个文件合并
启动Agent记得加载自动注入零操作

关键数字:28个文件被删掉,0个功能丢失。 不是删功能,是转译——把写在代码里的规则写回prompt里,把需要engine实例化的class变成纯CLI命令。 整个工作流简化为3步: 旧五道闸体系,30+文件相互依赖。正是这套复杂度催生了本文的极限瘦身。 第1步:启动——确认时间 + 读STATE.md $date&&catSTATE.md 第2步:执行任务——规则在SOUL.md和.hermes.md里# (Agent 按铁律执行,不需要加载任何引擎) 第3步:结束——终态检查 $check_completion.pydonetask-42 五、踩过的坑 坑1:不要迷恋「自动化」 旧体系的异常引擎每5分钟扫描一次,听起来很智能。但三个月运行下来,只有23%的异常是被轮询发现的——剩下的77%,Agent 在执行完任务自己调用 send_alert.py check 时就已经发现了。 后台轮询带来的复杂度超过了它解决的问题。删掉轮询,保留手动触发。 坑2:CLI命令比class更好 旧体系的 TerminalStateChecker 用 class 封装: checker=TerminalStateChecker()result=checker.verify(task_file) 看起来优雅,但 Agent 必须知道 TerminalStateChecker 的存在才能实例化它。如果 Agent 忘了 import,检查就跑不起来。 换成 CLI 命令: check_completion.pydonetask-42 Agent 只需要记住命令名称,不需要理解 Python class。命令失败会直接打印错误,不存在「忘了加载」的问题。 坑3:不要相信 Agent 自己声称的「规则记着呢」 我犯过一个经典错误——把规则写在 SOUL.md 的第一条,以为 Agent 每轮都会遵守。结果在第5轮对话中,Agent 开始自己编规则:「根据之前的讨论……」「上一步已确认……」,绕过了prompt里的铁律。 解决方案:物理校验必须存在。SOUL.md 定义规则,check_completion.py done 做物理校验。两条线:规则在prompt里,校验在代码里。prompt可以被「遗忘」,但CLI命令的输出不会被Agent篡改。 六、结尾:轻,才是物理 回想我给 Agent 造过的所有「系统」——从最初的物理强制三层到后来的30个文件到现在的2文件+2脚本——最强的那次反而是最简单的。 不是因为我变懒了。是我终于想明白了一件事:物理强制的核心不是代码的复杂度,而是Agent无法跳过的最小路径。 30个文件的引擎,Agent 可以忘了跑。2个文件+2个脚本,Agent 想忘都忘不了——SOUL.md 自动注入进 prompt,check_completion.py 在 shell 里随时可以调。 你猜这两个体系中,哪一个才是真正的「物理强制」? 系列导航:前6篇文章覆盖了从持久状态到质量体系到运维监控到流水线架构的完整路径。本篇从30个文件瘦身到2文件+2脚本体系。下一篇预告:写完代码还不够——Agent自检验才是最狠的测试——新体系上线后我做了一轮自检验测试,5种检验方式全部模拟了一遍,结果发现了一个意料之外的突破点…… 作者:魏无记,AI 和数智化实践者。专注 Agent 工程化与 Loop Engineering 研究以及数智化转型。公众号「模力AGI」持续更新——每篇都是保姆级教程,照做就行。

posted @ 2026-08-05 11:42  魏无记  阅读(1)  评论(0)    收藏  举报