AI Coding 已经能快速补全函数、生成模块,甚至完成小型需求,但代码生成只占研发工时的一部分。来源复盘给出的比例是 10% 到 32%:其余时间仍消耗在需求澄清、接口对齐、代码审查、测试、部署和故障排查上。真正影响交付速度的,不是模型一次能写多少代码,而是它能否在一套可验证、可回滚、可追踪的流程中持续推进任务。
Harness 全链路研发智能体的核心,就是把大模型放进研发控制回路:每个阶段读取明确输入、产出结构化制品,由工具执行验证,再根据结果决定继续、重试、修复还是交给工程师处理。
从代码生成器升级为交付执行器
传统 AI Coding 往往采用一次性对话:开发者描述需求,模型输出代码,后续工作重新回到人工流程。这里有三个明显断点。
- 模型不知道需求是否已经被正确理解,容易在错误假设上继续实现。
- 生成代码与仓库的构建、测试、权限和部署规则脱节。
- 测试失败后,错误日志没有自动回流,模型无法形成稳定的修复循环。
全链路智能体需要把研发任务拆成可检查的状态转换。例如,一个后端需求可以经过以下阶段:
- 将需求整理为验收条件、约束和待确认问题。
- 生成或更新 OpenAPI、数据库迁移等接口制品。
- 根据仓库规范修改代码。
- 执行静态检查、单元测试和安全扫描。
- 生成自动代码审查意见,并区分阻断项与建议项。
- 部署到临时环境,执行冒烟验证。
- 收集失败日志,定位问题并发起有限次数的修复。
- 达到质量门槛后提交人工审批。
这条链路的重点不是让模型掌握更多提示词,而是让每个阶段都有机器可判断的完成条件。比如,不能用“测试看起来没问题”作为结论,而应记录测试命令、退出码、失败用例和覆盖率报告位置。
用制品、状态和质量门禁构造闭环
一套可用的 Harness 通常需要三类工程对象。
制品是阶段之间传递的证据,包括需求说明、接口定义、代码补丁、审查结果、测试报告、部署地址和日志。模型应读取制品,而不是依赖越来越长的聊天记录。
状态描述当前任务进行到了哪里。推荐将状态持久化为 JSON 或数据库记录,至少包含任务 ID、仓库提交、阶段、执行次数、制品路径和人工审批结果。这样即使执行器中断,也可以从最近一次成功阶段继续。
质量门禁决定流程能否前进。门禁应尽量由确定性工具执行,例如:
- OpenAPI 校验器检查接口定义;
- 编译器和 linter 检查代码;
- 测试框架验证行为;
- 依赖与密钥扫描器检查安全风险;
kubectl rollout status判断部署是否完成;- HTTP 探针验证关键路径。
模型可以解释失败、提出修改并生成补丁,但不应自己宣布验证成功。执行结果必须来自真实工具。
一个可改造的最小 Harness
下面是一个概念性最小项目。假设仓库已经提供 make lint、make test 和 make smoke,智能体负责按顺序调用它们。示例不绑定某个模型 API,重点展示阶段、证据和失败反馈如何落盘。
先创建 harness.yaml:
task_id: add-order-query-api
max_fix_attempts: 2
stages:
- name: lint
command: make lint
blocking: true
- name: unit_test
command: make test
blocking: true
- name: smoke_test
command: make smoke
blocking: true
再创建 harness.py。运行前安装 PyYAML,并把 YAML 中的命令改成项目真实命令。
from __future__ import annotations
import json
import subprocess
import sys
import time
from pathlib import Path
import yaml
CONFIG = Path("harness.yaml")
ARTIFACTS = Path("artifacts")
def run_stage(stage: dict) -> dict:
started_at = time.time()
process = subprocess.run(
stage["command"],
shell=True,
text=True,
capture_output=True,
)
return {
"name": stage["name"],
"command": stage["command"],
"exit_code": process.returncode,
"duration_seconds": round(time.time() - started_at, 2),
"stdout": process.stdout[-8000:],
"stderr": process.stderr[-8000:],
"passed": process.returncode == 0,
}
def main() -> int:
config = yaml.safe_load(CONFIG.read_text(encoding="utf-8"))
task_dir = ARTIFACTS / config["task_id"]
task_dir.mkdir(parents=True, exist_ok=True)
state = {
"task_id": config["task_id"],
"status": "running",
"results": [],
}
for stage in config["stages"]:
result = run_stage(stage)
state["results"].append(result)
(task_dir / f'{stage["name"]}.json').write_text(
json.dumps(result, ensure_ascii=False, indent=2),
encoding="utf-8",
)
if not result["passed"] and stage.get("blocking", True):
state["status"] = "needs_fix"
state["failed_stage"] = stage["name"]
state["feedback_file"] = str(task_dir / f'{stage["name"]}.json')
break
else:
state["status"] = "ready_for_review"
(task_dir / "state.json").write_text(
json.dumps(state, ensure_ascii=False, indent=2),
encoding="utf-8",
)
print(json.dumps(state, ensure_ascii=False, indent=2))
return 0 if state["status"] == "ready_for_review" else 1
if __name__ == "__main__":
sys.exit(main())
执行方式如下:
python -m venv .venv
. .venv/bin/activate
pip install PyYAML
python harness.py
当单测失败时,artifacts/add-order-query-api/unit_test.json 会保留命令、退出码和日志。实际接入模型时,可以将这个 JSON、相关代码差异和仓库约束一起交给模型,要求它只返回补丁;应用补丁后再次执行同一阶段。修复次数必须受 max_fix_attempts 限制,超过阈值就转人工处理,避免智能体无限循环或不断扩大修改范围。
一个面向模型的修复提示可以这样实践:
你正在修复任务 add-order-query-api。
输入:
- 当前 git diff
- unit_test.json 中的失败输出
- CONTRIBUTING.md 中的仓库规则
要求:
1. 只处理导致当前测试失败的根因。
2. 不删除或跳过既有测试。
3. 不修改公开接口,除非验收条件明确要求。
4. 输出 unified diff,不要声称测试已经通过。
5. 如果证据不足,返回 NEEDS_HUMAN 和缺失信息列表。
这类约束能把模型的职责限制在分析和生成候选修改上,把是否通过的判断留给测试执行器。
自动 CR 和部署阶段需要更严格的边界
自动代码审查不应只输出一段自然语言评价。可以要求模型生成结构化结果,包含文件、行号、严重级别、问题类型、证据和建议。流水线只阻断明确的 correctness、security 或 compatibility 问题,风格建议则交给 linter 或作为非阻断评论。
部署阶段还要限制权限。智能体适合部署临时环境、查询只读日志和执行预定义回滚脚本,不适合持有长期生产管理员凭证。建议使用短期身份、命名空间隔离和命令白名单,并完整记录模型输入、工具调用、补丁和审批操作。
冒烟检查也应验证业务行为,而不只是检查进程存活。例如可以这样实践:
set -euo pipefail
BASE_URL="${BASE_URL:?set BASE_URL to the preview environment}"
curl --fail --silent --show-error \
--max-time 10 \
"$BASE_URL/healthz"
curl --fail --silent --show-error \
--max-time 10 \
-H 'Accept: application/json' \
"$BASE_URL/api/orders/1001" \
| jq -e '.id == 1001 and (.status | type == "string")'
这里需要把订单 ID、认证方式和响应字段替换为项目中的测试数据。探针失败后,应保存 HTTP 状态、响应体和对应服务日志,再进入诊断阶段。
落地时先收紧边界,再扩大自治范围
全链路智能体不是把 CI 脚本外面包一层大模型,也不是让模型直接接管生产环境。它的价值来自三点:流程有明确状态,阶段有真实证据,失败能回到受限的修复循环。
开始采用时,可以按以下顺序推进:
- 先选择测试充分、依赖边界清晰的小型需求。
- 固化仓库的构建、测试、部署和回滚命令。
- 为每个阶段定义输入、输出、超时和通过条件。
- 限制修改文件、工具权限、修复次数和令牌预算。
- 在合并、数据迁移和生产发布前保留人工审批。
- 统计一次通过率、人工接管率、回滚率和端到端交付时间,而不只统计生成代码量。
当团队能够回答“智能体当前在哪个阶段、依据什么继续、失败后修改了什么、谁批准了高风险操作”时,AI Coding 才从体感上的便利,变成可度量、可治理的工程能力。