Harness工程实践:AI代理如何在遗留单体仓库中编写生产代码
在Harness工程实践中,人类负责定义架构边界、测试场景和结果审查,而AI代理则生成所有生产代码。在一个包含31万行Scala/Java代码的遗留单体仓库实验中,这一方法证明了对提取模块等常见任务有效,且不改变原有行为。工程师角色转向管理上下文和流程,AI代理处理机械性重复工作。
单体仓库:25个SBT模块,8年历史,高负载系统。任务:将Channel X webhook处理提取为独立服务,遵循现有适配器模式。
实验设置与角色分工
人类不编写生产代码。角色明确分工:
- 人类:架构边界、任务拆解、需求定义、测试、审查、最终验证。
- AI代理:代码创建/修改、组件迁移、运行场景测试、基础设施搭建、bug修复。
典型任务:机械提取,包括布线和依赖调整,不涉及业务逻辑重构。通过单元测试和端到端测试验证。
上下文准备:文档作为控制接口
文档成为核心工具:ADR概述选项,计划定义阶段。AI代理严格遵守给定框架,不做猜测。
示例ADR:
# ADR-42:从单体中提取Channel X Webhook处理
## 背景
Channel X 当前在核心模块内处理。其他通道已作为独立服务运行,通过消息代理通信。
## 选项
1. 薄包装器:移动现有代码,仅做最小调整(包名、布线)。
2. 使用不同技术栈从头重写处理器。
3. 保持原状。
## 决策
选项1:最小化提取过程中隐式行为的丢失;与其它通道架构保持一致。
## 后果
+ 所有通道采用一致模式
− 临时代码重复;重构作为后续任务
分阶段计划减少错误:从骨架到完整端到端循环。
阶段与提示:逐步控制AI代理
拆分成步骤确保监督。提示示例:
- 架构蓝图:
研究Channel A和B适配器的工作方式:它们如何订阅代理并发布入站事件。
在单体中定位Channel X webhook处理。
编写ADR,包含三个选项:包装器/重写/保留在核心。推荐包装器并详述后果。
将文件置于architecture/adr/目录下,暂不碰代码。
- 测试作为契约:
在WebhookHandler类中,有按聊天类型分支的逻辑。将它提取为纯函数routeEvent(...)。
不要优化行为——原样复制分支。编写单元测试:私聊、群聊、未知类型、空body。
成功标准:模块的`sbt test`全绿通过。
- 新建模块:
根据ADR-42的SPEC创建sbt模块channel-x-adapter。
从单体复制指定文件;仅修改包名、导入和依赖,确保无`dependsOn(core)`即可干净编译。
规则:本阶段不重构业务逻辑。
- 端到端循环:
添加e2e/目录,使用pytest + testcontainers:代理容器、PostgreSQL、外部API模拟(独立端口)。
编写一个测试:POST webhook带"ping"文本 → 代理在预期主题收到事件,文本=ping。
测试驱动AI代理:目标是绿色的sbt test或pytest。
AI代理优势:受控常规任务
AI代理擅长:
- 代码提取与适配。
- 从示例复制模式。
- 生成样板代码。
- 构建测试基础设施。
- 批量相似编辑。
示例端到端测试(pytest + testcontainers):
# fixture:代理容器、适配器、外部HTTP API模拟
def test_incoming_webhook_publishes_to_broker(e2e):
e2e.http.post("/webhook/channel-x", json={"message": {"text": "hello", "chat": {"id": 42}}})
msg = e2e.broker.await_message("inbound.channel-x", timeout_s=5)
assert msg["text"] == "hello"
assert msg["chat_id"] == 42
def test_outgoing_command_reaches_external_api(e2e):
e2e.broker.publish("outbound.channel-x", {"chat_id": "42", "text": "hi"})
calls = e2e.external_mock.wait_for_requests(method="POST", path_contains="sendMessage")
assert any(b"hi" in c.body for c in calls)
验证的不只是编译,而是集成行为:代理、数据库、API模拟。
局限与边界
AI代理不取代架构决策,但加速机械工作。风险:隐藏回归(绿测试掩盖问题),需严格边界。适合有模式遗留系统,不宜绿地项目或研发。
开发者意见分歧:常规任务节省时间 vs. 上下文开销。
关键收获
- Harness工程:受控AI环境——规则、工具、反馈。
- 在遗留项目中胜出:代码提取/适配和测试基础设施。
- 测试:核心控制接口,而非仪式。
- 边界:有示例的常规任务,无架构创新。
- 行业趋势:Anthropic(90% AI代码)、Meta、Amazon——转向AI原生开发。
— Editorial Team
暂无评论。