
如何构建面向 AI 编程代理的软件工厂AI 编程代理已经不是新鲜概念了。从自动补全到多文件修改再到能独立完成一个 task 的 agent工具链的进化速度远超大多数团队的流程改造速度。但这里有个矛盾单个 agent 写代码很强几十个 agent 一起写一个大型项目如果没有工厂级的流程约束产出很快就会变成一团乱麻。CI 的红灯、合并冲突、风格漂移、依赖地狱每一件都能把 AI 编程的效率吃掉大半。所以真正的问题不是“哪个模型写代码更准”而是“怎么设计一套软件工厂让 AI 编程代理在受控的流水线上稳定产出”。这篇文章不卖课程直接给一套可落地的构建思路从任务拆解、代码库隔离、质量门禁、批量执行到观测系统和安全边界全部按工程实践来拆。阅读对象正在把 AI 编程代理引入团队协作流的研发负责人、运维开发、平台工程师以及已经在用 Cursor、Claude Code、Devin、OpenHands 等工具但感觉单打独斗和团队协作差距很大的技术同学。1. 核心认知软件工厂和单代理任务的区别1.1 从“代理写代码”到“工厂产代码”单个 AI 编程代理的工作模式是这样的给一个 prompt它读文件、改代码、跑测试、返回 diff。看起来很像一个初级开发者在独立干活。但软件工厂不是这个模型。工厂强调的是流水线、工位、质检、批次和追溯。在工厂里每个 agent 不是全能的它只是一个“工位”上的操作员负责一小段明确工序做完之后交给下一个环节。经典的软件工厂流水线至少包含以下几类工位需求分析师代理把非结构化需求拆成任务清单和验收条件。编码代理基于规格说明实现功能产出 diff 和测试。评审代理检查 diff 是否遵守代码规范、是否存在明显缺陷。测试代理执行单测、集成测试、回归测试并汇总失败用例。文档代理按模板生成接口文档、变更记录、部署说明。发布代理打标签、构建产物、推进发布流程。这样设计的目的很明确任何一个代理的失败都能被下游拦截任何一个产物的质量都能被追溯到具体的工位和任务。1.2 工厂最应该管理的不是模型而是任务规格很多团队把精力花在选模型、调 prompt 上结果发现 agent 的产出依然不可控。原因很简单agent 是概率系统同一个 prompt 给两次结果可能不一样。软件工厂要降低的是这种不确定性手段就是任务规格化。所谓任务规格化就是把“帮我改一下登录模块”这种模糊指令变成如下结构化任务单任务编号TASK-2048所属模块用户认证目标行为支持手机号验证码登录验收条件无验证码或验证码错误时返回 401有效验证码 30 秒内返回 token约束条件不得改动数据库表结构兼容现有前端 SDK测试要求新增 5 个单测用例覆盖成功、失败、过期三种场景只有任务单足够清楚代理的判断空间才足够小产出才足够稳定。这也就是为什么业内常说AI 编程的上限由模型决定下限由任务规格和工程治理决定。2. 软件工厂的整体架构设计2.1 核心组件清单一个面向 AI 编程代理的软件工厂可以拆成四个核心平面。平面组件职责任务平面任务队列、规格仓库、拆单服务管理任务生命周期维护需求到代码的可追溯关系执行平面代理运行时、沙箱环境、代码库快照隔离执行环境控制代理能接触的代码和凭据质量平面静态检查、单元测试、集成测试、AI 评审在合并前自动判定任务是否达标观测平面日志、追踪、指标、审计记录每个代理干了什么、花了多久、消耗了多少 token四个平面不是独立系统而是通过一条事件总线串起来。比如“任务完成”事件会触发“质量门禁”流程质量门禁失败会事件回流到“任务队列”重新排队。2.2 一条任务的完整生命周期从输入到发布典型流程如下需求入库 - 拆单 - 任务入队 - 分配代理 - 拉取代码快照 - 规格落地 - 生成代码 - 本地测试 - 提交 MR - 质量门禁 - 人工抽检 - 合并 - 构建 - 部署到预发 - 发布其中“质量门禁”是工厂的质检关口也是最需要下功夫的环节。门禁不严代理再聪明也是白搭。2.3 厂房如何组织代码库不建议让代理直接在主仓库的 master 分支上工作。更稳妥的方式是“一份代码多份快照”。每次任务开始时从基线分支切出一个独立工作副本代理在这个副本上自由修改任务结束由平台回收和处理。如果团队用的是 Git可以按如下方式组织apps/ auth-service/ order-service/ api-gateway/ libs/ shared-dto/ logging/ auth-sdk/ quality-gates/ checkstyle-rules.xml eslint.config.mjs test-plan-templates/ task-specs/ TASK-2048.md TASK-2049.md任务规格单独放一个目录和代码一起纳入版本管理。这样任何一次代码变更都能查到关联的任务单。3. 任务拆解与规格化的落地方法3.1 拆单原则拆单是软件工厂最关键的工序。拆得好后面所有环节都轻松拆得差代理能力再强也只能在错误的地基上施工。经验法则有几点单个任务改动文件数控制在 3 到 10 个超过 15 个就要考虑拆成子任务。每个任务必须有一个可执行的验收命令例如pytest tests/test_login.py或npm run test:unit -- login。任务描述中要明确禁止改动的文件清单防止代理顺手格式化全仓库。关联的 Jira/飞书/Linear 链接要写进任务单方便追溯。3.2 任务单模板下面是各团队可以直接套用的任务单格式## 基本信息 - 任务编号: TASK-2048 - 需求来源: AUTH-318 - 优先级: P1 - 预计工作量: 0.5 - 1 人日 ## 目标 为 auth-service 增加手机号验证码登录接口。 ## 验收条件 1. POST /api/v1/auth/sms 能发送验证码并写入 Redis有效期 5 分钟 2. POST /api/v1/auth/login 在验证码正确时返回 JWT 3. 验证码错误超过 3 次后该手机号锁定 10 分钟 4. 新增单测覆盖以上场景全部通过 ## 约束 - 不允许修改数据库表结构 - 不允许引入新的 Redis 依赖 - 不允许改动 API 网关配置 ## 禁止改动文件 - apps/auth-service/src/main/resources/application.yml - apps/auth-service/src/main/java/com/example/AuthApplication.java ## 交付物 - 代码 diff - 单元测试用例 - 接口变更说明swagger 注释或 markdown 均可任务单写清楚之后拆单人员的工作就变成两部分更新任务单触发任务入队。代理端只需要读任务单、干活、提交。3.3 任务队列与优先级调度任务队列不建议直接用 Redis List 硬扛最好做成单独的调度服务。调度策略至少要考虑模块依赖关系auth-service 的任务和 order-service 的任务可以并行但修改同一批文件的任务必须串行。变更冲突检测入队前计算任务涉及的文件集合如果和已运行任务的并集有交集则延迟分配。资源限制同时运行的代理数量要有限制否则显卡或者 API 配额会先被耗尽。例如调度服务可以用一个简单的文件级冲突检测def check_conflict(spec, running_tasks): affected_files set(spec[affected_files]) for task in running_tasks: if affected_files set(task[affected_files]): return True, task return False, None冲突检测的成本不高但对避免代理之间的互相覆盖非常有效。4. 代理执行环境的隔离与沙箱设计4.1 为什么必须做环境隔离AI 编程代理和普通开发者一样会执行命令。它可能执行npm install也可能执行python manage.py migrate。如果没有沙箱代理不小心执行了危险命令影响的就是整个开发环境。所以软件工厂里的每个代理都应该运行在独立沙箱里。沙箱至少需要隔离以下内容文件系统只挂载当前任务的代码快照不能读取其他任务的目录。网络按白名单放行例如只允许访问内网包仓库和测试环境 API。凭据不把真实的生产密钥放进环境只注入最小权限的测试凭据。进程能力不允许 Docker 嵌套或者内核模块加载。4.2 以容器为基本执行单元容器是目前最务实的沙箱方案。每个任务启动一个容器挂载代码快照注入任务规格执行完直接销毁。一个最小化的执行环境配置可以这样声明apiVersion: v1 kind: Pod metadata: name: agent-task-2048 spec: restartPolicy: Never containers: - name: coding-agent image: your-registry/ai-coding-agent:latest env: - name: TASK_SPEC_PATH value: /workspace/TASK-2048.md - name: CODECOMPLETE_API_KEY valueFrom: secretKeyRef: name: codecomplete-creds key: apiKey volumeMounts: - name: code-snapshot mountPath: /workspace/repo - name: task-spec mountPath: /workspace volumes: - name: code-snapshot hostPath: path: /data/factory/snapshots/TASK-2048 - name: task-spec hostPath: path: /data/factory/specs/TASK-2048.md这个配置只是一个模板生产环境建议用有持久化能力的卷类型并且把 agent 进程放在非 root 用户下运行。4.3 代理工作目录约定为了减少代理“找不到文件”的试探工作目录结构要尽量统一。每个沙箱内建议固定如下布局/workspace/ repo/ # 代码快照代理在这个目录里改代码 TASK-2048.md # 任务单 scripts/ verify.sh # 验收脚本质量门禁阶段会再次执行 lint.sh # 静态检查脚本 logs/ # 代理的运行日志、命令历史verity.sh 等价于“出厂自检”。代理在执行完任务后最好先自己跑一遍验证脚本再提交结果。5. 质量门禁让 AI 产物可验收5.1 质量门禁的分层设计质量门禁不等于跑一遍 CI。它应该是分层级的每一层拦截不同的问题。门禁层级检查内容工具示例通过标准L0 格式门禁代码风格、文件编码、行尾符prettier、eslint、checkstyle无格式错误L1 静态门禁未使用变量、导入错误、类型错误、安全扫描ruff、tsc、bandit、gosec无 error 级问题L2 单元测试任务相关模块的单元测试pytest、jest、go test全量通过覆盖率不降低L3 集成测试模块间交互、接口契约自定义测试套件全量通过L4 AI 评审逻辑完整性、边界条件、潜在回归大模型评审 规则引擎评审意见全部关闭或人工确认关键点质量门禁必须跑在“干净的基线环境”里而不是代理自己的沙箱里。代理在自己环境里跑过一次只能证明它自己认为通了不能代表仓库基线合并后依然通过。5.2 验收脚本要进仓库前面任务单里提到的verify.sh实际应该和任务单一起提交到仓库让门禁可复现#!/usr/bin/env bash set -euo pipefail echo Linting ./scripts/lint.sh echo Unit tests npm run test:unit echo Contract tests npm run test:contract -- --grep auth把验收脚本纳入版本管理是为了避免代理在执行时临时写一套“看起来是通过了”的验证逻辑。任务单、验收脚本、代码 diff 三者必须一起提交。5.3 AI 评审代理怎么设计让一个 LLM 去评审另一个 LLM 写的代码听起来像是“自己人审自己人”但实际上只要把规则写清楚还是有用的。AI 评审代理的 prompt 应该包含以下要素任务单原文尤其是验收条件和约束。diff 内容。评审规则只关注逻辑漏洞、边界条件、安全风险、与任务的偏差。输出格式必须返回问题列表而不是散文。例如评审输出的规范格式[ { severity: high, file: apps/auth-service/src/main/java/controller/AuthController.java, line: 82, message: 验证码错误次数达到 3 次后未触发手机号锁定逻辑, suggestion: 在错误计数递增后调用 lockPhone 方法 } ]AI 评审的问题列表会再次回到任务调度器。如果存在 high 级别问题任务打回重做如果只有 low 级别格式建议可以合并进下一次任务。6. 批量任务与并行代理调度6.1 什么时候需要批量任务软件工厂不只是给一个 agent 用的它存在的意义就是同时处理大量小任务。比如存量项目升级把项目从 Java 8 升级到 Java 17涉及上千个文件。规范整改统一把日志框架从 log4j 迁移到 logback。安全补丁修复某个通用库的已知漏洞涉及多个服务。接口迁移内部 RPC 接口升级为新协议。这些场景的共同特点是任务数量多、模式近似、存在大量重复的机械改动。非常适合交给代理批量处理。6.2 批量执行的三个坑批量执行最容易踩的坑有三个逐一说明。第一依赖关系。任务 A 改了公共 DTO任务 B 并不知情结果 B 的改动基于旧 DTO。处理方式是把公共模块的改动拆成第一批等这批的代码合并后在新的基线上拆分下一批任务。第二并发写冲突。两个代理同时跑git merge大概率出现冲突。处理方式是在调度器层面做文件锁冲突的任务串行执行。第三token 成本失控。批量任务不是越多越好要控制并发数并给每个代理设置最大调用次数。超过预算的任务自动挂起待人工确认后再继续。6.3 一个批量任务队列的实现思路下面是一个基于文件目录的极简批量任务管理器适合小团队先跑通流程import json import subprocess from pathlib import Path QUEUE_DIR Path(./queue) DONE_DIR Path(./done) RUNNING_DIR Path(./running) def dispatch(task_path: Path): task json.loads(task_path.read_text()) snapshot task[snapshot] spec task[spec] runner subprocess.Popen( [/usr/local/bin/agent-runner, --snapshot, snapshot, --spec, spec], stdoutsubprocess.PIPE, stderrsubprocess.PIPE, ) return runner def main(): for task_file in sorted(QUEUE_DIR.glob(*.json)): if find_conflict(task_file): continue # 有冲突的任务等一下 task_file.rename(RUNNING_DIR / task_file.name) proc dispatch(task_file) returncode, stdout, stderr proc.communicate(timeout1800) if returncode 0: task_file.rename(DONE_DIR / task_file.name) else: print(fTask failed: {stderr}) if __name__ __main__: main()这个例子只是为了说明批量调度可以非常简单生产环境还是要用真正的任务队列比如 Celery、BullMQ 或者 Kafka Streams关键是先理解批量的基本逻辑入队、分配、执行、回写。7. 观测与追溯代理干了什么必须看得见7.1 最小观测清单AI 编程代理的可观测性和传统服务一样重要但观测对象更复杂。不仅要看系统指标还要看它的“行为轨迹”。软件工厂至少要记录以下几类数据数据类型内容用途运行指标每任务耗时、token 消耗、工具调用次数评估成本与效率行为日志代理读取的文件、执行的命令、修改的代码段问题定位和审计决策记录代理针对关键问题的推理过程理解为什么会写出这样的代码产物记录diff、测试结果、评审结果、合并记录质量追溯7.2 实现一个小型的“代理审计日志”一个简单的做法是给代理注入一个 shell 包装器把每次命令执行自动记录到日志文件#!/usr/bin/env bash # ~/.factory/hooks/command_logger.sh echo $(date %Y-%m-%d %H:%M:%S) | $(pwd) | $* /workspace/logs/commands.log eval $让代理默认使用这个包装器执行命令就能知道它跑了哪些命令、在哪个目录下跑。再进一步还可以把每一步的输出摘要也记录下来方便后续判断失败原因。7.3 可追溯性必须落到代码和任务的关系上如果只记录“代理运行了 20 分钟”对定位问题没有意义。真正重要的是 commit、任务单、评审报告的关联。最简单的方式是在每个 commit message 里强制携带任务编号[TASK-2048] feat(auth): add sms login endpoint这样通过git log --grepTASK-2048就能把一次变更对应的所有提交抓出来。配合之前的任务单仓库就形成了完整的追溯链需求单 - 任务单 - commit - 质量门禁报告 - 评审意见 - 发布记录8. 成本控制与性能观察8.1 token 成本的构成AI 编程代理的成本不完全等于模型 API 的费用还有计算和人工介入的成本。一个任务的总成本可以拆成几块模型推理 token这是大头。代理运行容器占用的计算资源。人工处理门禁失败、打回重做的时间。数据存储和日志存储成本。其中最容易失控的是 token 消耗。一个大模型代理可能在“读代码”这个动作上花费大量的上下文 token。几十个任务同时启动时token 账单会非常可观。8.2 控制成本的几个实用手段给每个任务设置 token 上限到达上限后强制停止并通知人工。让代理只读取与任务相关的文件而不是整个仓库的索引。可以通过 repo map 和文件白名单实现。把重复的静态信息从上下文中剥离。比如 Java 项目的父 pom 配置说明不需要每个任务都塞给代理。复用会话上下文。一个任务在开发环境中探索的成果尽量不要在下一个任务里从零开始。这里要特别强调显存和并发不是同一个话题。如果用的是本地推理服务比如通过 vLLM 或者 Ollama 部署的开源模型并发数直接与显存大小挂钩。不同的模型、量化方式、上下文长度、并发线程都会影响单卡能承载的代理数量。建议以本机实测为准不要盲目按网上某个数字部署。可以先从低并发开始测试逐步增加观察响应延迟和显存占用是否稳定。8.3 观察什么指标如果正在跑一个批量任务应该重点观察以下几项每个任务的耗时分布正常情况下应该集中在一个区间。如果出现长尾任务耗时数倍于中位数就需要排查是否卡在依赖安装或者无关文件读取上。代理的执行路径是否存在“空转”。日志里如果出现大段的 grep 和 find 命令而没有实际修改说明任务规格可能不够明确。模型调用失败率和重试次数。如果 API 频繁超时要考虑降低并发或扩容。9. 安全边界与合规要求9.1 最小权限原则AI 编程代理本质上是一个可以执行任意命令的进程。它的权限必须被严格约束。代理容器只能访问当前任务的代码快照不能访问其他任务的数据。代理账号只能对当前任务分支有写权限不能直接 push 到受保护分支。涉及生产环境的任何操作不论是改配置还是执行数据库脚本都必须经过人工审批。代理不应该接触任何私钥、生产 token、客户数据等敏感信息。9.2 代码安全扫描前置AI 生成的代码是天然的不安全代码候选者因为它可能参考过含漏洞的模式。除了常规的依赖漏洞扫描还应该增加针对引用了危险函数、不安全的反序列化、硬编码密钥的检查。这些检查放在哪个层级答案是 L0 和 L1 之间。如果静态检查能拦截绝大多数安全问题就不需要靠 AI 评审代理在最后兜底。9.3 授权与合规提醒这里需要明确一点无论软件工厂处理的是自研代码还是第三方代码都必须确认代码来源的合法授权。不要拿未授权的代码库投喂给模型做微调也不要在没有协议支撑的情况下用 AI 批量生成与某一商业产品高度相似的代码。涉及用户数据、内部系统信息时要确认数据脱敏是否到位。AI 代理读取到的代码和日志内容会进入模型上下文如果是外部模型服务数据就等于出了内网。对敏感项目要么使用私有化部署模型要么在数据进入代理之前做脱敏。10. 常见问题与排查方法问题现象可能原因排查方式解决方案代理频繁修改无关文件任务单缺少“禁止改动文件”约束查看代理行为日志在任务单中补充约束并在门禁中增加文件变更范围检查多个代理同时改同一个文件导致冲突调度器未做文件级冲突检测检查调度日志中的任务分配时间增加冲突检测命中冲突时延迟分配代理完成任务但门禁测试失败代理在自己的沙箱里验证过但基线环境不同对比沙箱和门禁环境差异统一下发依赖版本镜像保证环境一致代理 token 消耗过高上下文里塞入了大量与任务无关的文件查看模型调用日志中的 prompt 内容使用 repo map 按需加载文件限制单任务文件读取数批量任务大量超时并发跑满API 配额不够或者代理陷入死循环查看任务耗时分布和 API 配额降低并发数设置单任务最大执行时长代理生成的代码没遵循团队规范静态未检查出说明规范本身定义不全回顾门禁规则将规范转化为 lint 规则而不是依赖代理自觉AI 评审代理产生无关意见造成噪音规则不明确prompt 中任务目标和评审标准不清晰查看评审意见的命中率收紧评审规则限定评审范围使用结构化输出格式11. 最佳实践与建议11.1 从一个小型冷启动场景开始不要一开始就把整个组织几百个仓库全部接进软件工厂。先挑一个边界清晰、测试覆盖好、历史包袱少的后端服务做试点把整条流水线跑通再说。试点的目标不是完成任务而是验证流水线本身是否可靠。11.2 人工保留至少 10% 的抽检比例AI 编程代理写的代码即使是经过质量门禁的也不建议直接合并。可以设置一个规则low 风险任务人工抽检medium 以上风险任务全量人工复核。发布敏感服务前必须至少有一个人工 reviewer 手动确认。11.3 定期复盘任务单质量软件工厂投产一段时间后最有价值的复盘对象不是代码而是任务单。把代理表现最差和最好的任务单放在一起对比通常会发现任务单描述得越具体代理的表现越稳定。反过来那些描述模糊、验收条件缺失的任务单是大多数失败案例的根源。11.4 保持“最小可运行配置”不变把一组经过验证的任务单、验收脚本、镜像版本和工作流文件作为基线锁住防止任何人随意改动导致整条流水线回归。每次改动这些配置要走正常的代码评审流程。12. 总结与下一步面向 AI 编程代理的软件工厂不是买一个昂贵的工具就能完成的。它是一套工程治理体系核心是把“让代理自由发挥”变成“在受控流水线上完成明确工序”。最值得先做的事情有三件第一建立任务规格仓库让所有代理接收到的都是结构化任务单。 第二把质量门禁从 CI 扩展成 L0 到 L4 的全自动流水线用规则和评审双保险拦截问题。 第三完善行为日志与追溯让每一次代码变更都能从任务单追到交付物。最容易踩的坑也有三个任务规格不清晰代理就会在无关文件上游走门禁只做编译测试不跑集成测试质量问题就会后移不做环境隔离就批量并发改动冲突和权限事故会接踵而来。如果团队已经在用 AI 编程代理做日常开发下一步可以从规范任务单开始落地如果还没大规模使用可以先挑一个小模块做试点用一套最小可运行配置把流水线跑通再逐步扩展到全仓全模块。这篇文章里给出的架构和流程在实际落地时可以根据团队规模裁剪。一个 5 人小团队哪怕只用 shell 脚本和 GitHub Actions也能搭出版本零的软件工厂。关键是先把“任务规格 - 沙箱执行 - 质量门禁 - 审计追溯”这条闭环建立起来剩下的都是在此基础上的持续优化。