做AI辅助编程的人,最近基本都在聊同一件事:模型能力是上来了,但真把一段需求交给Codex、Claude Code去落地,还是经常出现“答得很好、做得偏离”的问题。不是模型不会写代码,而是它缺少一套可执行的思考流程——什么先做、什么后做、做到哪里算完、发现偏差怎么回头。这类问题靠一条system prompt解决不了,得靠工作流来管。
我花了几周时间整理了一个叫AI-Infra-Auto-Driven-SKILLS的小框架,版本号刚推到v0.1.5,定位就是给Codex / Claude Code这类编程智能体用的推理框架工作流。它不是提示词合集,也不是代码库,而是一套把“感知、推理、执行、反馈”串起来的技能编排体系。这篇文章把它拆开讲:包括它解决什么问题、核心模块怎么设计、实际怎么接入这两个工具,以及我在使用过程中踩过的坑和现在的做法。如果你也在被“AI改完代码不敢用”折磨,这篇应该能给你一些可直接抄作业的思路。
1. 编程智能体最缺的不是模型,而是“流程感”
1.1 为什么单个提示词管不住复杂任务
我先说一个比较普遍的现象:给Codex一个任务,比如“给某个服务模块加一个带失败重试的HTTP客户端”。它通常第一件事就是直接开始写代码,写完一个版本就跑测试,跑挂了再改。前几次迭代看着都挺顺利,但过一会儿你会发现它陷入了自己的局部最优——一直在同一个文件里打补丁,没有回头重新审视最初的接口设计。
这个问题的根源不是模型笨,而是任务没有分层。人在开发的时候会下意识地先确认需求边界、再看现有代码结构、再定方案、再动手,最后验证。AI如果被一次性灌入所有背景和期望输出,它缺少的就是这个“先规划再执行”的中间过程。推理框架工作流要做的,就是把这层流程从模型脑内搬到代码里,显式地、可控地跑一遍。
1.2 工作流 vs 提示词:差在“状态管理”
普通提示词是静态的。你写一大段说明,模型读完直接输出。问题在于:模型并不会在这一大段话之间做状态管理,它靠的是上下文注意力。一旦对话轮次多了,早期约束会被冲淡。
工作流不一样,它的核心价值在于把任务切分成多个带检查点的阶段,每个阶段有独立的输入输出和校验规则。比如在“理解需求”阶段结束时,要求AI必须输出一份需求确认文档,并经过用户确认后才进入下一步。这个检查点相当于给流程加了闸门,防止模型一路狂奔到错误方向。
打个比方:提示词是给导游口头交代“带团别迟到”,工作流则是规定“每个景点停留多久、几点集合、超时怎么罚”。后者才是能落地的管理制度。
1.3 这套框架适合谁用
先说结论:不是所有场景都需要上这套东西。
如果你是拿Codex或Claude Code改个脚本、写个一次性demo,那直接用对话式提问效率反而更高。但如果你遇到下面这些情况,就值得认真考虑引入一个轻量级的推理框架工作流:
- 项目已经有一定规模,AI经常改了A模块忘了B模块;
- 同一个仓库里多人都在用AI辅助开发,需要统一行为标准;
- 你希望AI的产出不只是代码,还包括设计说明、测试计划、变更记录;
- 你在做重复性的代码迁移、架构梳理、测试补齐,希望把过程沉淀为可复用资产。
我自己的实践是:个人小项目用得比较少,一旦进入团队协作或跨模块改造,就一定会切到这套流程上。它能带来一个比较明显的变化——AI的返工次数明显下降,因为它在动手前至少先讲清楚了自己打算怎么做。
2. 设计拆解:SKILLS v0.1.5的核心模块与运作方式
2.1 先把这个名字拆开读
AI-Infra-Auto-Driven-SKILLS,这个命名确实有点长,但拆开看其实很直白:
- AI-Infra:指AI应用下的基础设施层。在编码智能体的场景里,提示词、技能包、工作流脚本、上下文管理策略,都属于这一层。它们不直接产生业务代码,但决定了模型产出代码的质量上限。
- Auto-Driven:强调自动化驱动,也就是不需要人在每个步骤之间做中转。理想状态下,工作流自己根据当前状态决定下一步调哪个技能、让哪个模型执行。
- SKILLS:技能包,它是这套系统里最核心的资产组织单位。
- v0.1.5:版本号,说明还处于早期迭代阶段,但已经有实际可用的协议和实例。
2.2 四层核心模块
我在v0.1.5里把整个推理框架分成四层,每层职责明确:
| 层级 | 职责 | 输入 | 输出 |
|---|---|---|---|
| 感知层 | 读取任务描述、仓库结构、文件状态 | 用户需求、仓库快照 | 结构化的任务上下文 |
| 推理层 | 选择技能、编排步骤、制定计划 | 任务上下文、技能索引 | 可执行的行动计划 |
| 动作层 | 调用Codex / Claude Code执行具体的编码动作 | 行动计划 | 代码改动、测试结果 |
| 反馈层 | 收集执行结果、错误信息、质量指标 | 执行日志、测试报告 | 结构化复盘记录 |
这四层不是流水线式的“走一遍就完”,执行过程中会有循环。比如反馈层发现测试挂了,会把失败信息重新送回推理层,由推理层决定是修bug、换方案还是回到感知层重新理解需求。
2.3 为什么用“技能”来组织,而不是“指令”
我在早期版本里用的是指令集——一堆规则和checklist,强制AI按顺序读。效果勉强,但问题很多:规则之间容易冲突、复用性差、每次新任务都要重新编写一遍。
后来改成技能化组织就顺了很多。每个技能是一个自包含的目录,基本结构是:
skills/ ├── repo-scout/ │ ├── SKILL.md # 技能说明,写清适用场景和启用条件 │ ├── prompt.md # 进入该技能时给模型的提示词模板 │ ├── checklist.md # 执行过程中的自查清单 │ └── examples/ # 典型输入输出示例,供模型in-context参考SKILL.md是入口,写得像一份工具的README:这个技能干什么、什么时候用、依赖什么前置条件、产出的格式是什么。模型在推理层看到的是一个技能索引(每个技能一份摘要),真正需要执行时才把对应的完整prompt.md加载进上下文。
这种设计的好处是: 第一,技能之间天然隔离,不会互相污染。 第二,技能可以被版本管理,每次调整都有traceable的变更记录。 第三,可以组合。比如“仓库摸底”技能 + “依赖分析”技能 + “风险报告”技能,组合起来就是一个跨模块改造的专属工作流。
2.4 v0.1.5相比之前版本改了什么
简单列一下这个版本的主要变化:
- 增加“技能优先级”字段:解决多个技能匹配同一场景时的选择冲突问题;
- 引入“会话状态文件”:任务执行过程中的中间状态不再丢在对话上下文里,而是落到工作区文件;
- 工作流脚本支持“分支回退”:当验证失败时,可以根据失败类型跳到指定步骤,而不是从头跑;
- 对Codex和Claude Code的指令格式做了适配层,统一了技能内部模板,不再分别维护两份。
这些改动都是前面实际使用中碰到的痛点倒推出来的。v0.1.5远远谈不上成熟,但已经是一个能稳定跑完“中等规模迁移任务”的版本。
3. 实操指南:把这套工作流接入Codex / Claude Code
3.1 搭目录:一份可以直接参考的文件结构
我建议这样组织工作区:
ai-infra/ ├── config.yml # 全局配置 ├── agent.md # 给智能体的总入口,描述工作流使用方式 ├── workflows/ │ ├── plan.md # 规划阶段流程 │ ├── implement.md # 实现阶段流程 │ └── review.md # 复核阶段流程 └── skills/ ├── repo-scout/ ├── dependency-audit/ ├── refactor/ ├── test-runner/ └── commit-writer/config.yml里记录了模型接口参数、默认上下文长度上限、技能搜索路径。agent.md是所有会话的公共开场,它告诉Codex / Claude Code:你手上的项目使用了SKILLS工作流,必须先看workflow目录找到当前处于哪个阶段,再决定调用什么技能。
3.2 一次完整任务长什么样
我拿一个实际做的“给某个Python服务补CSV导出接口”来走一遍流程。这个任务不大不小,但很能说明问题。
第一步,感知层。智能体先运行repo-scout技能,扫描项目里与数据导出相关的文件,输出一份清单:包括数据模型文件、路由定义、现有导出格式。这个阶段的输出被写入session_state.json,记录当前上下文快照。
第二步,推理层。智能体读取plan.md,明确“先看导出格式约定,再定接口方案,最后动手”。同时它加载一个叫feature-plan的技能,生成一段结构化实施计划:新增哪个文件、改哪几行、测试覆盖哪些case。这个计划会展示给我确认,我点头之后才进入下一步。
第三步,动作层。智能体调用Codex开始实现,按计划逐个文件修改。我比较习惯在动作层让Codex负责代码生成,让Claude Code负责交叉审阅(也就是四眼原则),两边的输出都记录到动作日志。这一步最容易失控——模型写着写着就顺手改了无关代码,所以我在implement.md里明确了一条规则:“每次打开一个新文件前,必须先用grep检查该文件是否在计划清单中”。
第四步,反馈层。写完代码后自动跑pytest,收集失败用例。如果失败,把失败信息反馈给推理层,让它判断是测试用例问题还是实现问题;如果是实现问题,生成修复计划,然后重新进入动作层。全部通过后,把diff摘要和测试报告写入review.md,等待我最终确认。
整个过程看起来不长,但实际上每个阶段都有独立的输出物,我可以随时查看中间产物,而不只是看AI在对话里说什么。
3.3 配置参数:真正影响行为的那几个
我整理了几个对最终效果影响最大的参数:
- max_steps:单次任务的步骤上限。设得太大,模型容易在一些无关紧要的优化上无限耗时;设得太小,复杂任务又走不完。我一般按任务复杂度分为三档:简单任务10,中等25,大型迁移50。
- skill_order:技能优先级列表。在config.yml里显式写明“当出现场景重叠时按列表顺序选择技能”。这个参数很重要,因为模型面对多个匹配技能时,默认行为往往是随机选一个,这对结果一致性是很大的破坏。
- context_strategy:上下文策略,重点是“技能体不进上下文”。所有技能完整内容都放在工作区,对话中只保留技能索引,真正执行时按路径读取。这样能让长会话不爆窗口。
- fail_action:验证失败的处理方式,可选值有re-plan、retry、stop。我建议默认re-plan,也就是回到推理层重新规划,而不是傻乎乎地原地重试同一个方案。
- confirm_gate:哪些步骤需要人工确认。通常设置“计划生成后”、“大规模重写前”两道闸。这个看个人习惯,团队协作时建议开启,单人使用时可以关掉。
3.4 让Codex和Claude Code用同一套技能模板
这两个工具的定位不完全一样:一个更偏“代码生成器”,一个更偏“对话式编程助手”。如果分别维护两份提示词,工作量和漂移风险都不可控。
我的做法是做一个适配层:
- 技能内部模板使用纯Markdown写,不依赖任何工具的专属语法;
- 在agent.md里声明与工具对应的入口规则,例如Codex环境下多强调“先写计划后写代码”,Claude Code环境下多强调“每完成一个文件汇报一次进度”;
- 工具差异只出现在入口配置,技能本体保持中立。
这样换工具时不需要改技能包,只改适配层,迁移成本低很多。
4. 踩坑记录:v0.1.5使用中的常见问题与排查实录
4.1 模型跳过推理阶段,直接给结果
这是我最开始遇到频率最高的问题。现象是:明明agent.md里写了“先调用plan.md进行规划”,但模型读完全部内容后直接输出了实现代码。
排查后发现原因有两个。第一,流程说明在prompt中和任务描述挤在一起,模型把它当成了背景介绍而不是强制约束。第二,部分模型的工具调用模式是“先响应再工具调用”,它认为直接写代码就是响应的一部分。
解法我试过几个,最后稳定下来的组合是:一,把流程约束放到agent.md的顶部,并用“必须”句式声明,而不是“建议”;二,在第一步就让模型调用一个名为workflow-select的最简单技能,通过强制触发工具调用,把它的行为拉进流程轨道里。只要第一步进了技能执行,后面基本不容易跳流程。
4.2 技能文件互相冲突,模型选择了错误的技能
有一次我同时维护了“依赖审计”和“安全检查”两个技能,很多场景下双方都匹配。模型有一次给一个涉及第三方依赖的任务选了“安全检查”,结果输出了一堆权限建议,完全没有做依赖版本分析。
这个是典型的技能匹配优先级问题。我的修复分两步:第一,在SKILL.md中增加triggers字段,明确列出命中关键词,降低无关技能被唤起概率;第二,在config.yml里启用skill_order,对已知高频任务路径硬编码技能顺序。改完以后,技能选择的一致性明显提升。
4.3 技能加载太多,上下文窗口被塞满
刚开始我图省事,让agent在会话启动时把全部技能说明都读一遍,想着“反正都是文字,应该不占多少token”。结果跑到第15轮之后,响应开始明显变慢,而且模型开始丢失早期约定,经常出现“前后规则不一致”的情况。这就是上下文被无关内容污染了。
正确做法是分层加载:只把技能索引(每个技能3-5行摘要)放到上下文,技能使用说明放到外部文件里,等真正要执行该技能时再通过工具读取完整内容。这个改动的效果非常直接,长任务的稳定性能维持到几十轮以上。
4.4 两套工具间的行为差异导致工作流断裂
Codex和Claude Code对同样一段Markdown指令的响应方式并不完全一致。比如某个技能模板里我写了“请输出STRICT格式的结果”,在Codex环境下它规规矩矩地照做,到了Claude Code环境下则容易出现松散的自然语言输出,导致下游解析步骤失败。
排查思路是把工具差异显式化,而不是在模板里打补丁。我在agent.md里增加了一个tool_profile字段,每个工具一份配置,写明该工具下技能输出需要采用的解析格式。简单说,模板只负责内容的组织,工具相关的适配全部交给入口配置。
4.5 测试通过但功能不符合预期
还有一种比较隐蔽的问题:测试全绿,但代码行为和需求不一致。原因通常是推理阶段的理解就不对,后面每一步都是在“正确执行一个错误计划”。
我现在会在流程开头强制加一个“需求确认”步骤,让模型用自己的话复述需求,并列出验收标准。如果复述和需求文档有偏差,直接就发现了,不会再白跑一趟。
5. 一些个人经验与后续打算
写到这儿,分享三条比较私人但很重要的经验。
第一,别急着建技能库。一开始很容易陷入“这个场景也做个技能、那个场景也做个技能”的冲动。技能越多,匹配冲突和上下文压力都随之上升。从v0.1到v0.1.5,我主动砍掉了一半的技能,留下的都是高频使用、边界清晰的场景。技能库就像工具箱,常用工具放在伸手够得到的地方,冷门工具收进储物间,而不是全摊在桌面上。目前v0.1.5稳定维护的技能我控制在8个左右,基本覆盖代码梳理、规划、实现、测试、提交这几个环节。
第二,工作流本身也要纳入版本管理。每次调整prompt模板、技能目录或配置参数,都走一次commit。现在回头看,很多调整的动机当时觉得合理,后来才发现是误判。没有历史记录,就会在一个方向上反复横跳。有了commit历史之后,我还会在提交信息里写明“这次修改是因为哪个失败案例”,过几个月再看,整个工作流演进逻辑是非常清晰的。
第三,给模型看你的计划不求快。我开始总是想办法让流程跑得更快,比如合并步骤、缩短确认环节。后来发现,AI辅助编码的成本分布本来就和人类编码不同,省下策划时间往往会在调试和返工时间上加倍还回来。与其催它“直接开始做”,不如让它先写一个像样的实施计划。这个计划就是你最好的review抓手。
至于后续,我打算把v0.1.5的这套目录结构和技能模板整理成一份可直接用的模板仓库。目前代码量不算大,核心就是config、workflows、skills三个目录加一个agent.md,整体维护成本很低。如果你也在折腾Codex或Claude Code的干活效率,强烈建议从一个最小的“规划-确认-实现-验证”闭环开始,把流程跑通再去扩充技能,不要一上来就把摊子铺大。先让智能体在一条笔直的赛道上跑起来,后面再考虑给它加转弯的能力。