不把 Agent 写死,从一套规则到一套判断方法#
最初整理这个仓库时,我想做的其实很简单.给自己的 Agent 写一份更完整的 AGENTS.md,让它在开发,委派,浏览器操作,媒体处理,Git 恢复和验证方面少犯一些低级错误.
但规则越写越多之后,问题逐渐变得明显.一份看起来严谨的规则,很容易变成另一种形式的僵化.它可能要求每个线程都重新回答一遍偏好,可能把某台机器上的习惯当成所有人的默认配置,也可能为了满足某条流程而机械地创建子代理.
所以这个仓库后来真正关心的,不再是如何堆出一份更长的 Agent 规则,而是如何让 Agent 在不同用户,不同环境和不同任务之间做出合适的判断.这篇文章算是对《GPT5.6时期 Codex App 的一些使用心得》里 AGENTS.md 和开发笔记部分的补齐,同时也来单独介绍一下仓库的相关内容.
规则不应该脱离真实环境#
Agent 的运行环境并不是抽象的.
它可能运行在 Windows,macOS,Linux,远程容器或者 WSL 中.它可能使用 PowerShell,Git Bash,zsh,某个 IDE 内置终端或者一个权限受限的沙箱.它可能有 Git,也可能没有 Git.它可能能够调用浏览器,也可能只能访问 API 和本地文件.
因此,一条规则不能只写成,始终使用某个 Shell,始终使用某个模型,始终委派给某种代理,始终先执行某个流程.
更合理的方式是先区分三种东西.
第一种是当前环境事实.例如当前运行的是 PowerShell 7,仓库位于某个目录,当前分支有未提交修改.
第二种是用户偏好.例如用户希望以后优先使用 PowerShell,希望保留中文回复,或者不希望 Agent 自动安装 Git.
第三种是当前任务决策.例如这一次命令使用 PowerShell,是因为当前会话就是 PowerShell.这一次建立 Git 检查点,是因为修改涉及多个文件,恢复成本较高.
如果把这三种东西混在一起,规则就会逐渐从适配环境变成改造环境.一个原本只是建议使用的工具,最后可能变成强制依赖.一个只对某台机器有效的路径,最后可能被误认为通用配置.
所以仓库里的核心原则是,Agent 应该先检查真实环境,再根据用户偏好和任务风险决定怎么做.检测事实不等于获得修改环境的授权.推荐工具也不等于强制安装工具.
先询问,再推荐,最后仍由用户选择#
这套设计里,询问不是每个线程都要执行的固定仪式.
普通线程应该直接复用已经确认过的偏好.用户已经明确说过的事情,不需要下一次重新询问.没有 AGENTS.md,也不代表必须立刻开启一轮完整访谈.用户只是要求审阅文件,也不代表要进入安装和配置流程.
询问更适合出现在首次采用,有意升级或者需要做详细配置的时候.
但询问也不能变成机械问卷.它真正的作用是弄清楚用户当前的目标,环境,权限,工具和偏好.在这些信息基础上,Agent 才能提出候选方案.
例如,模型选择不能只按模型名称或营销等级来判断.如果要配置吞吐层,可以关注发布时间,实际暴露的模型 ID,供应商,速度,成本,工具能力和可靠性.通常可以优先考虑近期,快速,低成本且能力足够的候选.但这只是推荐方向,不是强制规则.
如果任务是复杂的界面操作,便宜模型不一定适合.如果高级模型能够显著减少错误和交互轮数,即使它单次成本更高,完整任务成本也可能更低.最终使用哪个模型,是否设置 fallback,如何分配角色,仍然应该由用户决定.
同样,Windows 用户可能会从 PowerShell 7 和 Git 中获得更好的编码行为,状态检查和恢复能力.但推荐不代表强制安装.用户可以继续使用旧 Shell 或非 Git 工作流,Agent 应该适配现状,并使用其他可靠的备份方式.
这也是仓库想保留的一条边界.
询问是为了减少猜测,推荐是为了帮助决策,而不是为了把用户引导到 Agent 预设的答案上.
Computer Use 的矛盾#
Computer Use 和浏览器操作是整个设计中最纠结的一部分.
这类工具有明显的优势.它们可以处理网页,桌面软件,弹窗,登录状态和必须经过图形界面的流程.有些高级模型对于视觉状态和界面操作的理解能力非常强,甚至明显领先于普通模型.
但它们也带来几种现实成本.
第一是上下文成本.每次操作都可能伴随截图,页面状态和工具返回.多轮交互会迅速占用上下文,并增加长期线程的负担.
第二是速度成本.任务时长不只取决于模型能力,还取决于首字延迟,每轮响应速度,页面等待和交互轮数.一个每轮更快但需要反复试错的模型,不一定比一个单轮更慢但路径更稳定的模型更快.
第三是媒体和存储成本.截图可能包含大量像素数据,甚至以很大的 payload 返回.如果检索 4K 视频画面,单张截图可能达到十几 MB.多张原图同时上传,更容易造成网络压力或触发上游大小限制.即使把任务交给子代理,这些传输和存储成本也不会自动消失.
所以,问题不能简化成,主代理禁止浏览器,或者所有浏览器操作都必须交给子代理.
更准确的判断方式是拆开几个维度.
谁负责最终判断.
哪个模型真正具备任务所需的视觉和工具能力.
哪个执行上下文能够承受工具返回.
主代理和执行代理之间的交接成本有多高.
这次任务的授权范围是什么.
媒体传输,上下文输入和持久化历史分别会产生什么成本.
长流程,高输出和需要大量截图的任务,通常适合放进独立执行上下文.但独立执行不等于必须使用弱模型.执行代理可以使用与主代理同级甚至更强的模型,只要权限,视觉输入,工具和会话状态都真实可用.
反过来,如果只是一个很短的操作,交接成本明显高于操作本身,主代理在既有授权内直接完成可能更合理.
这不是一句简单的禁止或允许,而是一种任务级决策.
不要为了规则而创建子代理#
委派本身不是目标.
子代理真正有价值的地方,通常是吞吐,隔离,工具访问或者独立审查.如果一个任务很简单,主代理可以轻松完成,那么为了满足某条抽象规则而创建子代理,反而会增加沟通,交接和验证成本.
这条原则看起来很普通,但它很重要.
如果只是读取一个小文件,检查一处配置,修改一个明确的拼写错误,或者运行一个短命令,没有必要把任务拆给另一个代理.如果任务涉及大范围检索,长日志压缩,独立反方审查或者需要不同工具访问,委派才可能产生实际收益.
委派之后,主代理也不能完全相信子代理的结论.子代理提供的是证据和建议,不是自动成立的事实.主代理应该根据风险检查关键证据,但不需要重新播放每一次点击,也不需要把所有原始输出重新塞回自己的上下文.
这带来另一个边界.
主代理不能无限等待一个方向已经明显偏移的代理,也不应该长期逐步辅导一个能力不足的代理.默认可以进行一次有针对性的重试.如果没有明显提升,就应该接管,更换方法,报告阻碍或者请求用户决定.
更换模型也不能重置失败阶段的预算.换一个代理,不代表前面已经消耗的时间,步骤和资源不存在.
环境形成阻力时,停下来重新判断#
Agent 很容易陷入一种机械循环.
命令失败了,再重跑一次.还是失败,换一种参数.继续失败,再试几次.最后花费了大量时间,却没有获得新的信息.
仓库后来把环境阻力单独作为一个重要主题.
当 Shell,终端,依赖,网络,权限或工具形成明显阻力时,Agent 应该先区分问题类型.
这是临时故障,还是语义错误.
是模型没有理解,还是工具没有提供必要能力.
是依赖缺失,还是当前环境禁止安装.
是权限不够,还是方法本身超出了用户授权.
只有确定替代方案确实针对当前阻碍,才值得切换方法.如果需要安装工具,修改全局配置,切换环境或者扩大权限,就应该停下来说明成本,范围,风险和恢复方式,再询问用户.
这并不是降低自主性.恰恰相反,它要求 Agent 对自己的行为边界有更清楚的认识.
真正成熟的 Agent,不是任何事情都硬做到底,而是能够识别什么时候继续尝试已经不再产生有效进展.
媒体处理不只是清晰度问题#
处理图片和视频时,很多人只关心模型能不能看清.
但对于 Agent 系统来说,媒体至少同时涉及三个不同的预算.
模型输入和上下文预算.
网络请求的 payload 大小.
会话历史和宿主存储压力.
这三个预算不能混成一个概念.
对于 4K 视频检索,更合理的流程通常是先在本地定位时间点,再抽取代表性画面,裁剪真正需要检查的区域,在不影响证据的情况下生成审查副本,最后只上传回答问题所需的最小集合.
原视频和全分辨率画面继续保留在本地.如果画面中有细小文字,透明通道或者需要像素级判断,就应该使用无损裁剪,而不是盲目压缩.
同时,审查用缩略图不一定等于操作坐标空间.如果任务还涉及点击坐标,就必须保留裁剪偏移和缩放关系.
这些规则背后的重点不是,永远上传小图.而是让传输决策和证据需求对应起来.
编写视角的问题#
仓库后期最重要的发现之一,来自 README 和 PR 文本本身.
模型在写交付物时,很容易把编写过程中的上下文带进最终正文.例如,它可能写出:
按你的要求,我已经把规则拆成了六个模块.
这句话在对话里可能没有问题.但如果它出现在 README 中,读者并不知道谁提出了要求,也不知道六个模块具体是什么.
更隐蔽的问题是,模型可能写出看似完整的句子,但它依赖了对话中才存在的前提.
例如:
六个模块将运行时行为与采用配置分开.
这句话的问题不只是有一点 AI 味.它假设读者知道六个模块是什么,假设读者知道什么叫运行时行为和采用配置,还假设读者会自动把这句话和文档前面的结构联系起来.
可是人类阅读文档时,并不是把整篇文档一次性装进脑中,然后建立所有词语之间的全局注意力.
读者可能从目录直接进入一个章节.
可能只看到一个截图中的局部.
可能通过链接跳到某个示例.
可能已经忘记了前面出现过的定义.
这意味着,文档内容存在于全文中,不等于读者在当前段落已经拥有了足够的局部上下文.
因此,编写正文时需要区分三件事.
作者在写作过程中知道什么.
文档实际写入了什么.
读者读到当前位置时能够理解什么.
这不是要求每段都重复全部定义,也不是禁止第一人称,更不是禁止一切元话语.邮件可以使用第一人称,开发记录可以记录过程,PR 可以说明真实的变更和测试,必要的署名和 AI 协助披露也可以保留.
真正需要避免的是,把只对请求者有意义的对话背景,伪装成面向读者的正文.
三个小例子#
第一个例子是发布说明.
不合适的写法是:
按你的要求,我已经加好了导出功能.
合适的写法是:
新增 CSV 导出功能.
后一句直接告诉使用者版本发生了什么变化.它不要求读者知道谁提出过要求,也不要求读者知道这段文字是由助手生成的.
第二个例子是操作提示.
假设某文件工具有一个名为“保留原件”的选项,它会把修改后的内容另存为副本.保存窗口本身没有显示使用手册里的选项列表.
不合适的写法是:
选择前面介绍的第一种方式保存.
合适的写法是:
保存时选择“保留原件”,将修改另存为副本.
第二句话在当前位置给出了选项名称和行为结果.读者不需要回到其他章节寻找“第一种方式”到底是什么.
第三个例子是 PR 摘要.
假设一个 PR 修复了空报表导出时的崩溃,三项相关回归测试已经通过,完整测试套件尚未运行.
不合适的写法是:
在这里说明修复内容,测试结果和剩余风险.
这不是正文,只是写作任务.
合适的写法是:
修复空报表导出时的崩溃.三项相关回归测试通过,完整测试套件尚未运行.
这段文字提供了真实内容,同时没有把三项测试夸大成全部测试通过.
规则覆盖广,但不追求无限增长#
仓库里后来出现了很多模块和条例,但它们并不是为了追求规则数量.
真正需要覆盖的是那些经常发生,代价较高,容易误判或者一旦发生就难以恢复的场景.
例如:
用户偏好如何被复用.
首次采用和普通线程如何区分.
主代理和子代理如何分工.
浏览器和 Computer Use 什么时候值得使用.
高能力模型应该放在什么执行上下文.
媒体如何控制上传负载.
环境阻力什么时候应该停止硬重试.
Git 检查点到底覆盖了什么.
子代理结论如何独立验证.
正文如何脱离编写对话而面向真实读者.
这些条例之间也不能互相打架.
如果一条规则强调独立执行,另一条规则又默认主代理不能使用任何高能力模型,就会形成错误的强制关系.
如果一条规则强调恢复,却要求每一行修改都建立新提交,也会制造不必要的流程负担.
如果一条规则要求正文避免对话痕迹,却把“不要写助手视角”写成大量面向模型的防御性说明,它本身又可能成为一种新的编写视角.
所以,好的 Agent 规则不是越长越好,而是要把责任,权限,偏好,事实,成本,风险和证据分开.
最后的经验#
这套仓库最后沉淀下来的,并不是一份所有人都应该照抄的标准答案.
它更像是一套判断框架.
先观察环境,不要假设环境.
先理解用户偏好,不要把维护者偏好冒充默认值.
先询问尚未确定的重要决定,不要每个线程都重复问卷.
先提供有依据的推荐,不要静默替用户做选择.
先比较完整任务的成本和可靠性,不要只看单次点击或模型价格.
先设定边界,再进行有限重试,不要无限等待和反复辅导.
先保护原件和恢复能力,再追求速度和自动化.
先面向实际读者写正文,再考虑模型在编写过程中知道什么.
Agent 的价值不在于它是否拥有最多的规则,而在于它能否在真实环境中理解这些规则的边界,并在必要时做出恰当的取舍.
这也是我现在更愿意保留的方向.
不是把 Agent 训练成一个只会遵守固定句式的执行器,而是让它在用户真实环境中,围绕用户真实偏好,用足够广的案例和足够清楚的边界,完成可靠而可解释的工作.