资讯动态

AI编码工程化:用Agentic Harness Workflow实现受控代码变更

发布时间:2026/10/20 7:35:00 来源:尧图企业网站定制
1. 从一屋子“失控代码”说起为什么我要造这套工作流先说个真实场景。上个月我让某AI编码工具去改一个微服务接口它前后动了十几个文件每次对话我都说“继续”四个小时之后它把测试覆盖率从78%干到了34%顺手把另一个模块的配置给改了。那段经历给我留下的不是代码是三个非常具体的痛点过程不可见、变更不可控、结果不可复现。当时市面上各种AI编码工具已经很多了补全、对话生成、批量重构样样都行但它们都存在同一个共同问题——它们是“工具”不是“流程”。你告诉它做什么它给你结果中间的过程像黑盒一样改坏了你不知道是哪一步改的改好了你也不知道下次换个模型换套提示词还能不能复制出来。这就像请了个效率奇高但完全不听指挥的临时工你不盯着它就把墙拆了。我当时的想法很简单能不能把AI Coding这件事从“对话→生成→人工确认”这种作坊模式改成一套像流水线一样的工程化流程每一步都有输入输出、都有校验节点、都有回退机制AI只是其中一个执行单元而不是整个生产链条的主宰。于是我从零开始搭了一套东西名字就叫Agentic Harness Workflow姑且翻译成“智能体编排工作流框架”。它不是某个具体的AI模型也不是某个IDE插件而是一层介于“AI能力”和“业务代码”之间的编排控制层。这篇文章我想把整套思路和落地细节完整写出来包含这套框架的核心理念、实际代码结构、我在搭建过程中踩过的坑、以及它在我这边的两个真实项目里的效果反馈。如果你也在用AI写代码并且已经开始对“AI直接改代码”感到不踏实那这篇文章应该能帮你把这条路走正。2. Harness层到底负责什么先搞清它和普通提示词工程的区别很多人一听“Harness”第一反应是“这不就是把Prompt包一层吗”。还真不是。如果只是提示词工程你解决的问题是“怎么让AI回答得更准”而Harness层解决的问题是“怎么让AI在生产代码这件事上变得可被管理、可被追踪、可被终止”。这是两个完全不同量级的问题。2.1 编排层Orchestrator流程的总控我最开始设计的时候就确定了一件事Harness层的核心不是一个API而是一个有限状态机。AI不是被“召唤”出来的而是被“步骤”驱动的。我定义了几种基础状态PENDING计划已提交等待执行EXECUTINGAI正在生成变更VALIDATING自动检查阶段包括语法、测试、类型检查REVIEWING等待人工或者规则审批MERGED变更已入库ROLLED_BACK变更被自动回退这套状态机是整个框架的地基。AI生成一个对话回复其实只是一个“动作”而一个状态机才代表着“流程”。你每一次响应用户的请求都是在这个状态机里走一圈。顺着这个思路我写了一个核心的Orchestrator类它的职责就是读输入任务 → 拆解成多步计划 → 调用AI执行每一步 → 把每步产出交给校验器 → 决定下一步是继续、重试还是回滚。# orchestrator.py (核心调度示意) class HarnessOrchestrator: def __init__(self, llm_adapter, validator_registry, state_store): self.llm llm_adapter self.validators validator_registry self.store state_store def run(self, task: Task): plan self.plan(task) # 先让AI生成执行计划 for step in plan.steps: self.store.transition(step.id, EXECUTING) result self.llm.execute(step) status self.validate(step, result) if status FAILED: self.store.transition(step.id, ROLLED_BACK) return self.recover(step, result) self.store.transition(step.id, MERGED) return self.finalize(task)你可能已经注意到这个流程里有一个明确的分工AI负责“执行”Harness负责“决策”。这是我在无数个“AI自作主张”的瞬间之后总结出来的铁律。AI擅长的是把一句话变成代码而不是判断这句代码该不该进主干。2.2 策略层Policy Engine给AI装上“护栏”没有策略的流程等于没有交通规则的高速公路。我在Harness层叠加了一套策略引擎它不是简单的一堆if-else而是一组可以声明式配置的约束条件。例如在某个企业内部项目里我配置了三条硬性策略不允许AI跨模块改动文件。一次任务只能作用于指定目录树内如果AI生成的diff超出了范围直接拒绝。不允许AI删除测试用例。凡是diff里包含- test_开头的行校验器直接打回。不允许AI修改CI配置。这类文件的变更必须走人工评审通道。这里的实现也不复杂本质上就是对diff进行规则匹配。但关键在于把“经验”变成了“约束”。以前你需要在code review的时候人肉盯住AI的每一次输出现在这个约束被前置到了AI产出代码之后、合入主干之前而且是自动执行的。# policy_engine.py (示例) POLICIES [ { name: module_scope, type: path_filter, allowed_prefixes: [src/services/order/], action: reject, }, { name: protect_tests, type: diff_rule, pattern: r^-.*def test_, action: reject, }, { name: ci_config_freeze, type: path_filter, blocked_paths: [.github/, .gitlab-ci.yml], action: require_human, }, ]我强烈建议不要把策略写死在代码里而是拆成配置。因为策略这个东西是会演化的——刚开始你可能只限制文件路径后来你会想限制依赖版本更新范围再后来你想禁止AI直接发布生产环境。做成YAML或者JSON配置就能免去大量改代码的负担。2.3 可观测层Observability没有日志一切都是玄学AI编码最烦人的一点是不可复现。同一个任务同一套Prompt今天跑能过明天跑就挂。如果框架不记录整个过程你连复现问题的机会都没有。所以我的Harness层在每次任务运行时都会把以下几类信息完整落盘输入的Task描述和完整参数AI生成的调用记录包括模型名称、温度、上下文长度每一步的代码变更diff快照校验器的执行结果和耗时人工操作记录审批意见、回退原因这些数据平时看不出太大价值但一旦线上出了性能问题或者安全事故你能够回溯到“是哪一次AI变更引入了病根”这比在PR记录里翻了半天最后只能“回退重试碰运气”要强一百倍。3. 从零实现一次“受控AI编码”一个虚构订单微服务的中期改造理论说多了容易飘接下来直接用我真实的落地场景来拆解。我这里以一个虚构的订单微服务作为案例——它不大不小六十多个文件涉及接口、仓储、消息队列和生产任务非常适合用来做这套工作流的验证。3.1 第一步让AI先交“作业计划”而不是直接交“作业”我踩过最深的一个坑也是最反直觉的一项设计让AI先写计划别让它直接动手。大多数AI编码工具的默认行为是你提需求它直接改代码。这看起来效率极高但问题在于——你没有机会在它动手之前纠正方向。在这套框架中我设计了一个“计划生成”状态。AI收到任务后第一步输出的是对代码库的分析理解、执行步骤列表、涉及文件的清单以及每一步的预期影响面。只有当计划通过校验包括文件路径范围、改动规模、是否触及敏感模块之后才会进入实际执行阶段。用一个生活化的类比以前的AI编码像是你直接请了一位装修师傅进家里动工你只说了句“把客厅改好”师傅就开始砸墙了而计划模式等于师傅先把设计图纸和工期表交给你审你签字了他才动工。代价是慢一点但收益是可纠偏。我在项目中实际配置的Plan格式如下task_id: task_order_svc_20240115 goal: 为订单服务新增按时间范围查询订单的接口 impacted_files: - src/controllers/order_controller.py - src/services/order_query_service.py - src/repositories/order_repo.py - tests/test_order_query.py estimated_diff: 180 -45 execution_steps: - 在repository层新增query_by_time_range方法 - 在service层封装分页和权限过滤逻辑 - 在controller层暴露GET /api/v1/orders/query - 补充集成测试用例 sensitive_modules: []这个计划文件会被写入状态记录后续每一步执行都会对照这份计划来判断“AI有没有跑偏”。我实测下来这个设计让代码返工率下降了至少50%因为它把错误拦截在产生错误之前。3.2 第二步执行器不是“一个模型走天下”而是“多种模式混合编排”很多人做AI编码Agent时会试图用一个模型完成所有工作——理解需求、改代码、写测试、修bug、做解释。这就像让一个人同时又当建筑师、又当泥瓦匠、又当监理效果往往一般。我的Harness框架用了职责分模型的做法子任务类型推荐的模型配置理由代码理解与重构上下文窗口大、推理强的模型需要读取多文件并建立全局关系常规CRUD生成速度快、成本低的模型任务简单重复快速搞定即可测试用例生成擅长边界条件分析的模型测试用例的价值在于发现边缘场景代码审查与安全检测严格、偏保守的模型审查任务宁可误报不能漏报这一块稍微有一点成本概念“全能型”模型处理所有子任务总成本并不便宜而且会因为全能而“端架子”。在做框架的时候我给每一个子任务类型的调用都加了独立的温度参数。生成代码时温度设为0.2追求确定性生成测试用例时温度设为0.6让它发散一点更容易想出我们没考虑的边界条件。3.3 第三步校验器不是“跑一遍测试”这么简单测试通过不代表这个变更就是安全的。我在校验环节分成了四层语法与类型检查几千毫秒之内完成直接过滤低级错误。单元测试与集成测试这是最基础的保障但不能过度依赖——测试文件本身也可能被AI“适应性地”改坏了。静态变更审计扫描diff检查有没有硬编码密钥、不安全的日志打印、危险函数调用、依赖锁定文件突变等。契约检查如果被改动的模块是对外提供API的需要做接口签名双向对比。这块可能是最容易被忽略的——AI改了service层但是没有同步更新对应的API文档也没更新调用方。举个例子我在某个项目的改造中发现AI把用户状态字段从整数改成了字符串枚举这本身没问题但它没有同步修改调用方的序列化逻辑导致线上接口直接返回了错误状态值。要是没有契约检查这种问题在人肉review阶段基本看不出来要到联调的时候才会爆炸。3.4 第四步失败回退要用“软回退”而不是“硬回退”不是所有变更失败都要直接回滚到旧版本。很多时候新代码只是局部出问题直接全量回滚损失太大。我在框架里实现了三种恢复模式局部回退自动定位到失败的那个步骤只撤销这一步涉及的diff。补偿执行不是回退而是给AI一个上一步失败的上下文让它重新生成修复方案。人工接管当自动恢复连续失败两次之后框架不再自己尝试而是把当前状态和候选方案一起转给维护者。这个设计借鉴了分布式事务里“补偿”的思想。AI编码流程本质上也是一个状态流转过程它必须有能力处理“部分成功、部分失败”的中间态。如果你把整个流程设计成“要么全好、要么全烂”那你就失去了对复杂任务的控制力。4. 两套方案实现细节对比纯Agent方案 vs Harness方案我猜有人会问“你说的这套东西跟直接用现成的Agent框架有什么区别为什么不直接用开源工具”这是个很好的问题我当时也对比过。为了不误导大家我专门记录了两种方案的差异和我的体会对比维度传统Agent方案Harness方案开启方式一个Prompt直接开始自动执行先过Plan审批再逐步执行变更边界AI自己判断改哪些文件由策略层硬限制失败处理对话里翻来覆去“让它重新生成”状态机自动定位失败点并恢复可审计性聊天记录结构化任务日志diff快照决策记录人工参与点无/全程手动干预关键节点审批日常自动典型场景原型验证、思路探索生产代码库的受控变更我并不是说传统Agent方案一无是处它在快速验证想法、写一次性脚本、做研究性探索时是很高效的。但如果你要的是生产环境里长期运行的业务代码变更管理纯Agent方案就是开着没有刹车的车上高速没人拦得住它往山沟里冲。4.1 Harness方案的直接收益我这边三个月的数据我在这段时间里选择了一个内部订单服务的改造项目作为验证对象单独统计了改造前后的数据。先摆一下数字变更请求的平均交付周期从原来的2.5天缩短到了8小时其中约1小时为人工审批等待时间。线上缺陷回退率从之前的平均每两周1次降到了两个月内0次。代码Review工作量人工逐行审查的总时长下降了大约35%但不代表我们丢掉了责任——我们只是把精力从“看每一行长得对不对”转移到了“看流程节点是否合理”。AI生成代码的合入接受率从最初的48%提升到了89%原因是计划阶段先做了落地可行性筛选。这些数据不是这套框架“有多聪明”的证据而是说明一件事当你给AI设定了合理的边界和流程之后它的输出质量会稳定一个档次。AI本身没变厉害而是环境变得适合它发挥。5. 易踩的坑策略粒度、计划幻觉、以及让AI无限自我修复再好的框架落地过程中也一定会踩坑。我把自己吃过的苦头列出来希望大家少走点弯路。5.1 策略粒度太粗AI被束缚成了“废物”第一版策略我写得非常严苛几乎每个动作都要人工审批结果效率不但没有提升反而比人工写代码还慢。教训是策略的意义是拦住灾难不是拦住活力。后来我调整了思路把策略分成了两个级别auto_approve低风险变更比如新增注释、格式化代码、写测试用例。human_review高风险变更比如修改CI、删文件、改对外接口契约、批量重命名。高风险的必要审查一个都不能放低风险的琐碎事情全部自动化。平衡点在哪里我的经验是当自动化审查引起的等待时间占总流程时间超过30%时你的策略一定偏严了该放开一些。5.2 计划阶段AI可能“幻觉”出根本不存在的文件AI在生成计划时最大的问题是它可以一本正经地规划出你代码库中并不存在的文件。我遇到过AI在北京时间的凌晨三点凭空生成了一个src/core/new_engine.py还解释说“为了保持代码整洁我新建了一个独立引擎模块”。事实是这个文件根本不在之前的架构里也完全没有必要新建。我的解决方案是给计划阶段配一个“计划校验器”它会把AI计划中提到的所有文件路径跟代码仓库的真实文件列表做交叉比对缺失的文件直接标红拦截。这个校验器的实现不难但价值极大——它拦截了大约12%的无效任务计划。5.3 别让AI“无限自我修复”——连续失败必须中断有一个隐藏陷阱也是我在初期犯过的错误实现了一个“失败自动重试”逻辑后AI会陷入无限循环“改一下跑一下失败一下再改一下”的死循环。它就像那种超级耐心的学生明明已经走进死胡同了还要一遍遍撞墙。更可怕的是这个循环消耗了大量API调用额度等于白白烧钱。后来我加了一道硬性闸门连续两次执行失败后必须切换策略不再允许AI继续尝试。策略切换只有两种选择——“人工接管”或者“换一个完全不同的思路重新生成计划”。扛住这个开关之后整个流程的健康程度立刻不一样了因为它逼迫流程承认AI不是万能的偶尔需要换人或换方案。6. 这套框架的未来走向从“单Agent命令”走到“多Agent协作”目前这套Harness Workflow还只是处理“单Agent、单任务”的编排。但我已经很清晰地看到了下一个瓶颈当任务足够复杂时一个Agent可能在长上下文中丢失早期信息。未完待续的解法则来自于多Agent协作架构一个Agent负责“全局规划”多Agent并行处理“独立子任务”还有一个“汇总Agent”负责冲突消解。我给这套多Agent版本起了个内部代号叫“车间模型”——每个Agent就像产线上的一位工人各干各的工序但有一个永不疲劳的调度员在检查全局质量。这个调度员就是Harness。也许有读者会问“这个框架会不会取代工程师”我个人的答案很朴素它不会取代工程师但它会改变工程师的日常。工程师的角色从“手写每一行代码”变成“定义流程规范、审查边界条件、处理异常情况”这其实是更高级的生产力释放。就像流水线没有让工人失业但确实让流水线旁的工人从“重复劳动”变成了“监控和提升产线”。最后再分享一个实操小技巧如果你不打算从头实现一整套Harness框架可以先从“计划模式硬性策略”这两个功能做起在现有AI编码工具上包一层简单的状态机然后逐步增加可观测性和回退机制。我当初就是先从这块起步的——凡是可以重复的事情都值得先沉淀成流程再交给自动化。在AI编码这件事上我们缺的从来不是聪明而是可靠的重复。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑