尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Harness-of-Harness:AI智能体多日自主软件开发与持续改进

Harness-of-Harness:AI智能体多日自主软件开发与持续改进 1. 这篇文章真正要解决的问题如果只看“Harness-of-Harness”这个名字很容易误以为它只是又一个人工智能开发框架或者是某个开源项目的包装名称。但拆开标题里的另外两个关键词——“Multi-Day Autonomous Software Development”和“Continual Improvement”会发现它的定位要激进得多它要让 AI 智能体在无人干预的情况下持续运行数天乃至更长时间独立完成一个完整的软件开发任务并且在这个过程中不断自我修正、自我改进。这和我们熟悉的“AI 辅助编程”完全是两回事。今天大多数开发者使用的 AI 编程工具本质上是“人在回路中”的结对编程AI 写一段代码人审查、修改、点击运行发现问题后再丢给 AI。整个过程由人来控制节奏和质量。而 Harness-of-Harness 这类方向要解决的是“人不在回路中”的问题智能体自己面对一个大型软件开发任务自己拆解需求、编写代码、运行测试、发现错误、修复回归、迭代优化连续运行几天最后交付一个可运行的结果。你可能会问这现实吗说实话目前这个方向还没有到“完全替代工程师”的程度但它确实已经从前两年的“科学幻想”变成了“实验室和早期生产环境里可以跑通的工程原型”。这篇文章会重点拆解几件事Harness-of-Harness 这个名字到底意味着什么它和普通的 Agent 编排框架有什么区别。多日自主开发的核心技术挑战是什么为什么“能跑一步”和“能跑几天”是完全不同的工程问题。持续改进Continual Improvement在这一类系统中的真实作用它和我们常说的“模型微调”“提示词优化”有什么区别。如果你自己想做类似的实验从哪里入手怎么搭一个最小可运行的系统。这类系统有哪些已知的坑以及落地时应该如何控制风险。如果你正在关注 AI Agent 在软件工程领域的应用或者你所在团队已经在尝试用 AI 做自动化开发这篇文章可以帮你建立一个更完整的判断框架。它不会告诉你“AI 马上要取代程序员了”但会告诉你真正的工程难点不在“生成代码”而在“让系统能自己验证和修正自己”——这是 Harness-of-Harness 试图解决的核心问题。2. 从“Agent 框架”到“Harness-of-Harness”概念边界与核心差异2.1 什么是 Harness在 AI 领域Harness 这个词并不新鲜它经常被翻译为“调控框架”或“测试框架”。在模型评测场景中我们常见的是“评估 Harness”比如用一组标准测试集去运行模型、记录输出、计算得分。它的核心作用是给被测试对象提供标准输入约束运行环境然后观察和度量输出。到了 Agent 场景Harness 的含义发生了一点变化它不再只是评估模型而是控制和支撑智能体运行的一整套外围机制。比如给智能体提供工具调用接口、设定工作目录、管理上下文窗口、记录运行日志、处理超时重试、约束 token 消耗等。可以这么理解模型是智能体的“大脑”Harness 是包裹在“大脑”外面的一整套“神经、血管和骨架”。2.2 什么是 Harness-of-Harness“Harness-of-Harness”直译是“调控框架之上的调控框架”。从标题看它的意思是当智能体需要长时间自主完成软件任务时不能让一个静态的调控框架从头到尾固定不变而是需要有一个更高层的调控机制去动态调整这个调控框架本身。听起来有点绕我们拆成一个具体的例子。假设你给一个 AI 智能体下达了一个任务“用 Python 写一个支持用户注册、登录、发帖的 Web 应用要求有单元测试、数据库设计和 README 文档。”这通常不是一个一小时内能完成的任务而是一个需要拆解成多个子任务的长周期任务。在第一轮运行中智能体可能先写了一个简单的 Flask 应用。此时底层 Harness 会验证代码能不能跑、测试能不能过。但这个验证本身可能暴露出新的问题Flask 版本和依赖库冲突、测试覆盖率不足、数据库初始化方式有误。如果一切由人工处理我们会不断调整“验证框架”——比如换一个测试命令、新增一个 lint 规则、修改环境变量。问题是我们不在场谁来调整Harness-of-Harness 的答案是一个“元层”机制第一层 Harness 负责驱动智能体运行和验证第二层 Harness 负责根据第一层运行的结果去修改第一层的验证策略、提示词、工具调用方式、甚至任务分解方式。也就是说它不满足于让智能体在固定规则下运行而是要让系统具备自我修改运行规则的能力。2.3 和传统 Agent 编排的差异对比维度传统 Agent 编排Harness-of-Harness任务周期分钟到小时数天到数周人在回路通常需要人工介入目标是无人工介入或极少介入上下文管理单轮或短多轮需要跨会话长期记忆失败处理手动重试或简单回滚自动分析错误、修复并回归系统改进修改提示词或配置后重启系统运行时自动调整自身配置验证方式固定测试集或固定命令动态调整验证标准与验证流程这个对比能解释为什么 Harness-of-Harness 不是一个简单的“加了长期记忆的 Agent”。它强调的是封闭的、可自我修正的改进回路任务执行产生反馈反馈被高层机制消化高层机制反过来改变低层执行策略最终形成螺旋式上升。2.4 一个容易产生的误解很多人会把“长时间运行的 Agent”等同于“把中控 Agent 的上下文拉长”。实际上这是完全错误的。上下文窗口即使能容纳几十万 token也无法解决一个真实的长周期开发问题系统必须能够在“每次运行之间”保留有效状态——哪些代码已经写好了、哪些测试已经通过、哪些文件已经被修改、下一步应该做什么——而不是简单地把所有历史记录堆进上下文。上下文变长只会带来更严重的“迷失在细节中”的问题。真正的解决思路是状态外置与分层管理而不是靠窗口硬撑。Harness-of-Harness 之所以强调“元层机制”本质原因就在这里低层智能体会在数小时甚至数天后产生非常庞杂的中间状态必须有一套高层机制来“整理战场、修正方向、更换工具”才能让系统在多日运行中不偏离整体目标。3. 多日自主软件开发的核心工程挑战一次性的“生成代码”已经有很多产品做到但“多日自主软件开发”的难度完全不在同一个量级。按照我的观察任何想在这个方向落地的系统都必须正面解决下面五个问题。3.1 任务分解的粗粒度与细粒度多日任务必须被分解成子任务。如果分解得太粗智能体无法在单次会话内完成容易半途而废如果分解得太细智能体被各种琐碎步骤淹没全局目标反而被遗忘。实际系统通常采用“两阶段分解”高层 Harness 先把大任务拆成若干个可签收的工作包例如“搭建项目骨架”“实现认证模块”“实现发帖功能”“编写测试”“完善文档”低层 Agent 再在单个工作包内自行拆解具体的代码修改步骤。这就出现了一个典型的“Harness-of-Harness”设计高层控制“做什么”低层控制“怎么做”两者之间通过任务队列和状态文件衔接。3.2 长期状态的管理传统 Agent 对话结束后状态归零。而多日开发系统需要跨会话保留以下状态项目文件结构和当前代码内容。已完成任务和待办任务列表。测试通过率的历史记录。最近一次失败的详细日志。对整体任务目标的理解和当前优先级排序。一个务实的做法是把这些状态落盘到一个state/目录tasks.json记录任务看板memory.jsonl记录关键决策logs/记录每次运行的输出。高层 Harness 每次唤醒低层 Agent 时并不读取全部历史对话而是只读取这份“状态摘要”然后决定下一步动作。这种设计比把全部对话塞进上下文要可靠得多。3.3 验证与反馈闭环让智能体“写代码”容易让智能体“知道自己写错了”很难。多日自主开发的系统必须内置强大的验证机制。验证至少包括三层编译或语法检查。单元测试与集成测试。人工定义的需求验收标准例如“注册接口能返回 201”“未登录用户访问发帖接口返回 401”。关键不在于“跑一遍测试”而在于把测试结果转化为“下一步行动指令”。比如测试失败系统需要定位失败原因——是代码逻辑错误、依赖缺失、测试本身写错还是环境变量未配置。这个诊断过程正是高层 Harness 发挥作用的地方。3.4 上下文管理与记忆压缩即使采用任务队列和状态文件智能体在单个工作包内仍然可能产生大量中间上下文。例如“实现认证模块”这个子任务可能包含几十次文件修改、多次测试执行、多轮报错修复。这些记录不可能全部保留。务实方案是“分层记忆”让低层 Agent 处理子任务时保留完整上下文子任务结束后高层 Harness 将本次会话的关键结论压缩成一份“会话总结”存入长期记忆下一个子任务开始时低层 Agent 基于“全局目标 项目状态 历史总结”启动新一轮会话。这个“压缩—沉淀—再加载”的循环是多日开发系统能够持续运行的技术基础。3.5 失败恢复与方向纠正多日运行必然失败。可能是网络问题、依赖安装失败、测试环境异常也可能是智能体自身陷入低效循环。系统不能一失败就停止也不能无限重试。所以需要设计可重试的错误类型如网络超时与不可重试的错误类型如需求描述矛盾要有区分。在每个子任务上设置重试上限超过后自动降级处理方式。高层 Harness 要定期“审视”整体进展如果系统在同一个子任务上反复失败应该调整任务分解策略或提示词而不是继续原地打转。这五个问题本质上构成了 Harness-of-Harness 的技术骨架状态管理是基础任务分解是驱动器验证反馈是质量闸门上下文管理是续航保障失败恢复是稳定器。4. “持续改进”在这个系统中的真实含义4.1 不是模型微调也不是提示词优化很多人一看到 Continual Improvement就想到“系统根据测试结果自动改代码”或者“根据用户反馈微调模型”。这只是最浅层的理解。Harness-of-Harness 语境下的“持续改进”至少包含三种不同层次第一层是代码级改进测试失败智能体修改代码这属于最低层级的自我修正。今天的很多 Agent 都已经具备了这种能力。第二层是策略级改进系统发现某个子任务反复失败可能是因为任务分解方式不合理。此时系统不仅修改代码还修改的是自己“解决问题的方式”——例如把一个过于复杂的子任务拆成更小的步骤或者更换一种测试策略。这层改进发生在 Harness 的配置层面。第三层是元层改进系统通过分析自己在多个项目或多个任务上的历史表现调整整体的验证规则、提示词模板、工具选择逻辑甚至自动生成新的工具函数。此时改进的目标不再是某个具体任务而是“这个 Agent 系统本身的运行框架”。4.2 持续改进回路的设计思路一个可落地的持续改进回路通常包含四个步骤观察记录任务执行的中间指标例如测试通过率、失败类型分布、单次任务耗时、上下文消耗速度。分析高层 Harness 定期分析这些指标识别瓶颈。例如“系统在数据库迁移步骤上平均失败 3 次才成功”说明这一部分可能需要更详细的提示词或者需要提供数据库相关文档。调整根据分析结果修改 Harness 配置。可能是修改提示词模板也可能是新增一个用于自动修复数据库迁移的工具函数。回归调整后用已有的测试套件对调整本身做验证确保“改进措施”没有引入新的问题。这个回路很像一个“开发 DevTools 的研发团队在改进自己的生产力工具”先发现问题再改造工具然后验证工具效果。Harness-of-Harness 的特殊之处在于整个回路是由系统在运行时自动完成的而不是由人类工程师在开发周期中完成的。4.3 它为什么如此重要如果只停留在代码级修正多日自主开发的上限会很快触顶。原因很简单长时间运行的系统必然遇到各种“设计之外”的情况——依赖版本冲突、操作系统差异、测试环境不稳定、任务目标在实现过程中被证明不合理。如果系统只能改代码那它每次都要用一个老方法去处理新问题效率会越来越低。持续改进机制让系统有能力“换方法”。这是它在架构上区别于普通 Agent 的核心所在。换句话说普通 Agent 是“在规则内解题”Harness-of-Harness 是“一边解题一边改规则”。后者才真正配得上“自主软件开发”这个说法。5. 自建系统环境准备与基础架构设计如果只是了解概念这篇文章已经讲了大半。但对 CSDN 读者来说更关心的是如果我想自己搭一个类似的系统做实验应该怎么做。先说结论不必一步到位实现“完整版 Harness-of-Harness”但可以先搭一个具备“低层执行 高层调控 状态持久化”的最小框架然后逐步加入持久化、验证、改进回路。下面给出一个适合在本地或云服务器上运行的架构方案和代码骨架。5.1 环境要求组件建议选择说明操作系统LinuxUbuntu 22.04 以上或 macOSWindows 也可以但部分脚本命令需要调整编程语言Python 3.10 以上目前 AI Agent 生态对 Python 支持最好模型 APIOpenAI 兼容接口GPT-4o/Claude/DeepSeek 等本文示例使用 OpenAI 兼容接口实际模型请按项目配置版本管理Git 2.30 以上用于保存智能体的代码修改历史容器Docker可选用于隔离构建环境防止智能体操作本机任务队列JSON 文件即可起步阶段复杂场景可换 Redis 或数据库需要说明的是具体模型名称和版本以你实际可用的 API 为准。本文重点演示的是一种工程实现路径而不是绑定某个特定模型。5.2 整体目录结构harness-of-harness-demo/ ├── harness/ │ ├── low_level.py # 低层 Agent执行子任务 │ ├── high_level.py # 高层 Harness任务分解、状态管理、改进决策 │ ├── validator.py # 验证模块运行测试、检查结果 │ ├── memory.py # 长期记忆模块读写状态文件 │ └── prompts.py # 提示词模板 ├── tasks/ │ ├── todo.json # 待办任务队列 │ ├── done.json # 已完成任务记录 │ └── current_task.json # 当前正在执行的任务 ├── state/ │ ├── project_summary.md # 项目全局摘要 │ ├── session_logs/ # 每次会话的原始日志 │ └── insights.jsonl # 持续改进决策记录 ├── workspace/ # 智能体操作的代码目录 ├── requirements.txt └── main.py # 系统入口这个结构体现了分层思路harness/是控制逻辑tasks/是任务状态state/是长期记忆workspace/是智能体工作的真实场所。5.3 依赖安装建议新建虚拟环境python3 -m venv venv source venv/bin/activate pip install openai jsonschema这里只安装最基础的依赖。如果你的智能体需要操作 Git、执行测试命令、解析覆盖率报告可以继续补充gitpython、pytest等工具。不建议一开始就引入重量级编排框架等最小系统跑通后再考虑。5.4 环境变量配置在项目根目录创建.env文件写入模型 API 配置。注意不要硬编码密钥到代码里。# 文件路径.env OPENAI_API_KEYyour_api_key_here OPENAI_BASE_URLhttps://api.example.com/v1 MODEL_NAMEgpt-4o实际使用时把OPENAI_BASE_URL和MODEL_NAME替换成你能够访问的模型服务地址。不同模型的 API 格式差异不大但工具调用function calling的细节可能不同建议先读一遍对应平台的文档。6. 最小可运行系统核心代码实现这一节会给出一个能实际跑通的最小 Harness-of-Harness 示例。为了让示例保持简洁我用“生成一个 Python 脚本并验证它”作为演示任务而不是直接做完整的 Web 项目开发。但整体架构的所有关键环节都会包含任务分解、低层 Agent 执行、验证、状态落盘、高层 Harness 继续推进。6.1 配置文件实际运行前可以在config.json中定义系统参数{ max_retries_per_task: 3, max_subtasks: 5, workspace_path: ./workspace, state_path: ./state, task_path: ./tasks, model_name: gpt-4o, temperature: 0.2 }这里max_retries_per_task控制低层 Agent 在单个子任务上的最大重试次数max_subtasks控制高层 Harness 最多把大任务拆分成几个子任务temperature设低一点让 Agent 生成代码时更稳定。6.2 高层 Harness任务分解与调度高层 Harness 的核心职责是读取大任务描述调用模型拆解出子任务列表然后逐个派发给低层 Agent并最终汇总结果。# 文件路径harness/high_level.py import json import os from openai import OpenAI class HighLevelHarness: 高层 Harness负责任务分解、调度和最终汇总 def __init__(self, config_path: str config.json): with open(config_path, r, encodingutf-8) as f: self.config json.load(f) self.client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL), ) self.model_name self.config.get(model_name, gpt-4o) def decompose_task(self, task_description: str) - list[str]: 将大任务拆解为多个子任务返回子任务列表 prompt f 你是一个软件项目负责人。请把下面的开发任务拆解为多个子任务。 每个子任务必须足够小能够在一个 Python 脚本的 Agent 会话中完成。 请只输出 JSON 数组数组中的每个元素是一个字符串表示一个子任务。 不要输出任何其他文字。 开发任务 {task_description} response self.client.chat.completions.create( modelself.model_name, messages[{role: user, content: prompt}], temperature0.1, ) content response.choices[0].message.content content content.strip() # 兼容模型输出被代码块包裹的情况 if content.startswith(json): content content.replace(json, ).replace(, ).strip() subtasks json.loads(content) return subtasks def run(self, task_description: str) - dict: 执行完整的多日任务流程简化版 subtasks self.decompose_task(task_description) os.makedirs(tasks, exist_okTrue) with open(tasks/todo.json, w, encodingutf-8) as f: json.dump({subtasks: subtasks, index: 0}, f, ensure_asciiFalse, indent2) return { task: task_description, subtasks: subtasks, status: decomposed, }这段代码先让模型把大任务拆成子任务并写入tasks/todo.json。实际生产系统中拆解后还需要对每个子任务做依赖分析和可行性评估但最小演示版本已经足够说明问题。6.3 低层 Agent执行子任务低层 Agent 接收一个子任务调用模型生成代码、执行命令并把结果写回状态目录。这里用“生成一个 Python 函数并写入文件”做例子避免引入太多外部工具调用逻辑。# 文件路径harness/low_level.py import os import json from openai import OpenAI class LowLevelAgent: 低层 Agent执行单个子任务 def __init__(self, workspace_path: str, model_name: str gpt-4o): self.workspace_path workspace_path os.makedirs(workspace_path, exist_okTrue) self.client OpenAI( api_keyos.getenv(OPENAI_API_KEY), base_urlos.getenv(OPENAI_BASE_URL), ) self.model_name model_name def execute(self, subtask: str) - dict: 执行一个子任务并返回执行状态 system_prompt f 你是一名资深 Python 工程师。你被要求实现以下子任务 {subtask} 当前工作目录是 {self.workspace_path}。 请完整输出你要创建的 Python 文件内容。 如果任务需要多个文件请分别用 文件名分隔格式如下 ### 文件路径: relative/path/to/file.py python # 文件内容只输出文件内容不要输出额外的解释。 response self.client.chat.completions.create( modelself.model_name, messages[{role: system, content: system_prompt}], temperature0.2, )content response.choices[0].message.content files_written self._parse_and_write_files(content) return { subtask: subtask, files_written: files_written, status: done, } def _parse_and_write_files(self, content: str) - list[str]: 解析模型输出中的文件块并写入工作目录 lines content.splitlines() current_file None current_content: list[str] [] files_written: list[str] [] for line in lines: if line.startswith(### 文件路径:): # 保存上一个文件 if current_file and current_content: self._write_file(current_file, \n.join(current_content)) files_written.append(current_file) current_file line.replace(### 文件路径:, ).strip() current_content [] elif line.startswith() and current_file: # 跳过代码块起始/结束标记 continue else: if current_file: current_content.append(line) # 写最后一个文件 if current_file and current_content: self._write_file(current_file, \n.join(current_content)) files_written.append(current_file) return files_written def _write_file(self, relative_path: str, content: str) - None: full_path os.path.join(self.workspace_path, relative_path) os.makedirs(os.path.dirname(full_path), exist_okTrue) with open(full_path, w, encodingutf-8) as f: f.write(content) print(f[低层Agent] 已写入文件: {full_path})这个类解析模型返回的“文件块”格式将代码实际写入 workspace/ 目录。你可以把这个解析逻辑替换成更健壮的策略比如要求模型输出 JSON 格式或者用工具调用接口直接返回结构化文件内容。 ### 6.4 验证模块检查执行结果 低层 Agent 写完代码后验证模块需要确认代码是否正确。最小示例用“语法编译检查 导入测试”的方式 python # 文件路径harness/validator.py import ast import subprocess import sys import os class Validator: 验证模块检查代码语法与运行结果 def __init__(self, workspace_path: str): self.workspace_path workspace_path def validate_python_syntax(self, file_path: str) - bool: 使用 ast 模块检查 Python 语法 full_path os.path.join(self.workspace_path, file_path) try: with open(full_path, r, encodingutf-8) as f: source f.read() ast.parse(source) return True except Exception as e: print(f[验证] Python 语法检查失败: {e}) return False def run_python_file(self, file_path: str) - tuple[bool, str]: 运行 Python 文件并返回执行结果 full_path os.path.join(self.workspace_path, file_path) try: result subprocess.run( [sys.executable, full_path], capture_outputTrue, textTrue, timeout30, cwdself.workspace_path, ) if result.returncode 0: return True, result.stdout else: return False, result.stderr except subprocess.TimeoutExpired: return False, 执行超时 except Exception as e: return False, str(e)在真实的多日开发系统中这里的验证逻辑会更复杂需要运行pytest、检查覆盖率、执行ruff代码规范检查、甚至启动一个临时服务做接口测试。但核心思路不变验证结果必须结构化并且能被高层 Harness 理解和使用。6.5 高层 Harness 改进回路改进回路是 Harness-of-Harness 的关键。为了演示我们设计一个最简单的改进策略如果某个子任务连续失败两次高层 Harness 会把子任务描述拆成两个更小的子任务并追加到任务队列中。# 文件路径harness/high_level.py 中的扩展方法 from openai import OpenAI import json class HighLevelHarnessWithImprovement(HighLevelHarness): 带持续改进能力的高层 Harness def analyze_failure_and_improve(self, subtask: str, error_log: str) - list[str]: 分析失败原因并返回改进后的子任务列表 prompt f 一个子任务执行失败了。失败信息如下 子任务{subtask} 错误日志 {error_log} 请分析失败原因并决定下一步策略。 如果问题可以通过把该子任务拆分为更小的子任务来解决请输出拆分后的子任务列表。 要求 1. 只输出 JSON 数组 2. 每个元素是一个字符串表示一个子任务 3. 如果认为不应该继续重试输出一个空数组 4. 不要输出其他文字 response self.client.chat.completions.create( modelself.model_name, messages[{role: user, content: prompt}], temperature0.1, ) content response.choices[0].message.content.strip() if content.startswith(json): content content.replace(json, ).replace(, ).strip() try: new_subtasks json.loads(content) if not isinstance(new_subtasks, list): return [] return [str(item) for item in new_subtasks] except json.JSONDecodeError: return [] def update_task_queue(self, new_subtasks: list[str]) - None: 把改进后的子任务插入待办队列 if not new_subtasks: return with open(tasks/todo.json, r, encodingutf-8) as f: queue json.load(f) index queue[index] # 在当前位置之后插入新的子任务 queue[subtasks] ( queue[subtasks][: index 1] new_subtasks queue[subtasks][index 1:] ) with open(tasks/todo.json, w, encodingutf-8) as f: json.dump(queue, f, ensure_asciiFalse, indent2) print(f[高层Harness] 已将失败子任务拆分为 {len(new_subtasks)} 个新子任务)这里的“改进”很简单但它已经体现了核心思想系统的反应不只是“重试同一个子任务”而是“改变任务的分解方式”。你可以在此基础上继续扩展例如把失败日志写入state/insights.jsonl让后续任务可以复用改进经验或者分析多次失败的类型自动调整提示词模板。6.6 主流程入口把所有模块串起来的主函数如下# 文件路径main.py import os import json from dotenv import load_dotenv from harness.high_level import HighLevelHarnessWithImprovement from harness.low_level import LowLevelAgent from harness.validator import Validator load_dotenv() HIGH_LEVEL_TASK 创建一个名为 math_tools.py 的 Python 脚本其中包含两个函数 1. add(a, b)返回两个数字之和。 2. multiply(a, b)返回两个数字之积。 脚本最后要用示例参数调用这两个函数并打印结果。 def main(): os.makedirs(tasks, exist_okTrue) os.makedirs(state, exist_okTrue) os.makedirs(workspace, exist_okTrue) high_level HighLevelHarnessWithImprovement(config.json) low_level LowLevelAgent( workspace_pathworkspace, model_nameos.getenv(MODEL_NAME, gpt-4o), ) validator Validator(workspace_pathworkspace) # 第一步高层 Harness 任务分解 result high_level.run(HIGH_LEVEL_TASK) print(任务分解结果:, json.dumps(result, ensure_asciiFalse, indent2)) with open(tasks/todo.json, r, encodingutf-8) as f: queue json.load(f) index queue[index] retry_count 0 max_retries high_level.config[max_retries_per_task] while index len(queue[subtasks]): subtask queue[subtasks][index] print(f\n 正在执行子任务 {index 1}/{len(queue[subtasks])}: {subtask} ) execution_result low_level.execute(subtask) print(低层Agent执行结果:, json.dumps(execution_result, ensure_asciiFalse, indent2)) # 验证至少检查一个写入文件的语法 files_written execution_result[files_written] all_valid True for file_path in files_written: if file_path.endswith(.py): valid validator.validate_python_syntax(file_path) if not valid: all_valid False else: success, output validator.run_python_file(file_path) print(f运行 {file_path}: success{success}) if success: print(运行输出:) print(output) if all_valid: print(f子任务完成: {subtask}) queue[index] 1 retry_count 0 else: retry_count 1 print(f子任务验证失败重试次数: {retry_count}/{max_retries}) if retry_count max_retries: print(达到最大重试次数触发高层 Harness 改进机制) error_log 子任务多次验证失败需要拆分或调整。 new_subtasks high_level.analyze_failure_and_improve(subtask, error_log) if new_subtasks: high_level.update_task_queue(new_subtasks) retry_count 0 else: print(高层 Harness 建议放弃当前子任务继续下一个) queue[index] 1 retry_count 0 with open(tasks/todo.json, w, encodingutf-8) as f: json.dump(queue, f, ensure_asciiFalse, indent2) index queue[index] print(\n全部任务执行完毕) if __name__ __main__: main()这个流程覆盖了三个核心环节高层 Harness 分解任务。低层 Agent 执行子任务并写文件。验证模块检查结果失败时高层 Harness 重新拆解任务形成“持续改进”回路。你可以在本地直接运行python main.py观察流程。首次运行建议用一个非常简单的任务做测试比如让智能体生成一个hello.py检查打印结果。这样能尽快排除 API 配置、环境变量、文件解析等基础问题。7. 运行结果与效果验证7.1 预期运行轨迹以下是运行成功后终端输出的大致结构模型实际返回内容可能不同任务分解结果: { task: 创建一个名为 math_tools.py ..., subtasks: [ 创建 math_tools.py实现 add 和 multiply 函数, 补充示例调用并验证输出 ], status: decomposed } 正在执行子任务 1/2: 创建 math_tools.py ... [低层Agent] 已写入文件: math_tools.py 运行 math_tools.py: successTrue 运行输出: 3 15 正在执行子任务 2/2: 补充示例调用并验证输出 [低层Agent] 已写入文件: math_tools.py 运行 math_tools.py: successTrue 运行输出: add(2, 3) 5 multiply(3, 5) 15 全部任务执行完毕判断成功的标准不是“代码文件写出来了”而是“验证模块实际执行了该文件并得到了预期的输出”。7.2 验证改进回路是否生效要测试高层 Harness 的改进机制可以故意构造一个难以完成的子任务。例如把任务描述改成“创建一个能够运行但包含随机语法错误的 Python 脚本”或者让低层 Agent 连续输出有语法错误的代码。当验证模块持续失败并触发最大重试后高层 Harness 会调用analyze_failure_and_improve生成新的子任务列表。判断改进回路是否生效的方法很简单查看tasks/todo.json中是否新增了子任务。查看state/insights.jsonl如果已经实现中是否有失败分析和改进记录。观察终端是否打印了“已将失败子任务拆分为 N 个新子任务”的日志。如果这些现象出现说明系统已经具备“从失败中学习并改变自身执行策略”的基本能力。7.3 失败排查顺序运行失败时不要急着改代码。建议按顺序排查看 API 配置检查.env中的OPENAI_API_KEY和OPENAI_BASE_URL是否正确模型名是否可用。看模型输出解析低层 Agent 在解析### 文件路径:标记时非常敏感只要模型输出格式稍有变化就可能导致没有文件被写入。可以临时在main.py中打印低层 Agent 的原始响应确认输出格式。看验证命令确认validator.run_python_file是否在正确的目录下执行。如果工作目录不对即使代码正确也会报 ImportError。看任务队列状态如果子任务迟迟不推进打开tasks/todo.json查看index是否在预期位置。失败次数过多时高层 Harness 可能已经把任务拆分成更小的子任务。8. 常见问题与排查思路下面这张表整理了我认为在这个方向最容易遇到的几类问题。这些不是空泛的“启动失败”而是多日 Agent 系统真正会踩的坑。问题现象可能原因排查方式解决方案低层 Agent 写出的文件为空模型没有按“### 文件路径:”格式输出解析失败打印低层 Agent 原始响应检查格式改用 JSON 结构化输出或增强解析器容错代码语法检查通过但运行时失败工作目录不对依赖缺失或代码依赖项目内其他文件查看运行命令的cwd参数检查导入路径确保运行目录为workspace/必要时先执行依赖安装子任务反复失败系统陷入死循环高层 Harness 没有正确触发改进机制或生成的新子任务仍然太难检查max_retries_per_task配置查看任务队列是否有新增任务调低最大重试次数设置全局任务总数上限增加“放弃任务”策略上下文越来越长响应变慢低层 Agent 的会话没有及时关闭长期记忆没有压缩检查代码中是否每次都重新创建 Agent 实例每个子任务结束后主动结束会话把总结写入project_summary.md模型 API 超时任务描述过长或配置了过长的最大 token 输出查看 API 调用耗时检查任务描述长度在高层 Harness 中限制单次任务描述长度必要时分两次调用改进机制生成了空数组模型认为当前问题无法通过拆分任务解决查看高层 Harness 的 Prompt 是否有歧义改进 Prompt补充“何时应该输出空数组”的示例多日运行时磁盘被占满每次会话日志和中间文件没有清理查看state/session_logs/目录大小添加日志轮转机制只保留最近 N 次会话日志智能体修改了系统关键文件工作目录隔离不到位Agent 路径权限过大检查运行用户权限检查是否存在rm -rf等高危命令使用容器或沙箱隔离工作目录限制文件系统访问范围9. 生产环境落地最佳实践与风险控制9.1 务必使用沙箱或容器环境多日自主开发意味着智能体有大量机会执行外部命令、安装依赖、修改文件。在生产环境的早期实验中我强烈建议把智能体的工作目录放进 Docker 容器或至少是虚拟机中。理由很简单防止误删宿主机的关键文件。防止依赖安装污染系统环境。便于一键重建干净环境。一个最简单的 Docker 运行方式可以是这样docker run --rm -it \ -v $(pwd)/workspace:/app/workspace \ -v $(pwd)/config.json:/app/config.json \ -e OPENAI_API_KEY$OPENAI_API_KEY \ -e OPENAI_BASE_URL$OPENAI_BASE_URL \ python:3.10-slim bash进入容器后再执行pip install openai python-dotenv和python main.py。这能极大降低系统被智能体误操作的风险。9.2 设置明确的任务边界在大规模实验中你会发现智能体会经常“发散”它可能为了修复一个测试失败而重构整个项目结构或者引入一个全新的第三方库。这在单次开发任务中或许还能接受但在多日任务中可能引发不可控的连锁反应。控制方法包括在高层 Harness 的 Prompt 中强调“保持改动局部化不要修改与当前子任务无关的文件”。对workspace/使用 Git 管理每次子任务完成后记录 commit回滚时只需git checkout。对依赖安装命令做白名单限制禁止智能体随意安装未知来源的包。9.3 日志与状态的可观测性多日系统最大的风险是“看起来在运行实际上已经偏离方向”。必须设计可观测性机制每次低层 Agent 会话结束都写入一份结构化日志子任务内容、产生的文件、验证结果、运行时长、token 消耗。高层 Harness 每次改进决策都要记录原因和效果方便后续复盘。如果系统运行超过 24 小时应定期生成“项目进展摘要”让人工能快速了解系统在做什么。9.4 人机协作的兜底机制即使是最激进的多日自主开发系统也不建议在早期完全脱离人工监督。更稳妥的模式是“有限自主”系统自主执行可明确验证的子任务但遇到以下情况必须暂停并通知人类需要修改全局架构。需要删除已有功能。连续多次验证失败且自动拆分后仍然失败。需要访问外部系统或敏感资源。这种模式不会降低系统的自主性反而能显著提升系统在真实项目中的存活率——因为多日任务的失败往往不是“代码写不出来”而是“需求理解出现偏差”这种偏差只有人才能快速纠正。10. 从示例到完整项目值得继续深入的方向本文给出的最小系统已经具备 Harness-of-Harness 的三个核心要素但它离一个能“数天自主完成真实项目”的系统还有很大距离。如果你对这个方向感兴趣后续可以从以下几个方向继续深入10.1 工具调用与外部能力扩展真实软件开发不仅仅是“写 Python 文件”。它需要安装依赖、运行测试、执行数据库迁移、启动服务、调用 Git。要支持这些低层 Agent 必须具备“工具调用”能力。在实际代码中这意味着要使用 OpenAI 兼容的 function calling 接口把execute_command、git_commit、list_files、read_file等能力注册给模型。工具调用的稳定性直接决定系统能走多远。10.2 长期记忆的压缩与检索目前示例中的project_summary.md是手工维护的且非常简陋。真实多日系统需要更高强度的记忆压缩比如让模型定期把最近若干次会话的要点提炼成结构化条目需要根据当前子任务检索历史经验而不是每次调用都传递全部记忆。向量检索RAG是一个常见选择但工程上更重要的是“什么值得记住什么应该丢弃”的判断规则。10.3 错误诊断的深度本文的验证模块只做了“语法检查 运行检查”远远不够。真实系统中验证失败后需要回答更复杂的问题是代码逻辑错误还是依赖安装失败是环境变量缺失还是测试用例本身写错了是需求理解偏差导致实现方向错误还是只是小 bug每多精确一层诊断低层 Agent 修复成功的概率就显著提高。这也是持续改进回路中最值得投入的部分。10.4 多项目经验的迁移更高层次的“持续改进”可以从单任务内部扩展到多项目之间系统在项目 A 中学会了“处理数据库迁移失败”的经验是否能在项目 B 中复用这需要把改进经验从“任务队列调整”升级为“可复用的技能库”。当一个系统具备跨项目复用改进经验的能力时它才真正接近“自主软件研发”的概念。11. 对开发者的建议现在应该做什么11.1 谁适合尝试这个方向如果你满足以下条件非常适合投入时间研究你已经熟悉常见 AI Agent 框架的基本用法不再满足于“单轮对话生成代码”。你正在设计内部工具或平台希望用 AI 完成一些重复性较高的开发任务。你对系统架构感兴趣愿意花时间设计状态管理、验证回调和失败恢复机制。如果你只是想找一个开箱即用的工具来提升日常编码效率这个方向在目前阶段可能还不是最合适的选择。市面上的 AI 辅助编程工具往往会带来更直接的体验提升。11.2 小步快跑的建议路径第一步复制本文的最小系统跑通一个“生成数学工具脚本并自动验证”的流程。第二步加入 Git 版本管理让每个子任务完成后自动提交一次。第三步加入更复杂的验证方式例如pytest执行真正的测试用例。第四步替换低层 Agent 的执行方式支持函数调用和外部命令执行。第五步实现“失败总结”写入长期记忆并在后续子任务的提示词中引用历史经验。每完成一步系统的自主能力都会有质的提升。不要试图一次性实现完整的 Harness-of-Harness。这个方向的所有工程难点都需要在实践中逐步暴露和解决。11.3 心态先解决“可控”再追求“自主”在尝试多日自主开发系统时最大的诱惑是“让 AI 放开了跑”。但工程实践告诉我们系统的自主性越高外围的约束和验证机制就必须越强。不要先追求“智能体能在几天内完成任务”而要先追求“智能体在几天内犯错时系统能快速发现、定位并恢复”。可控性前置自主性自然浮现。这个顺序非常值得在后续实践中反复体会。
返回列表