1. 项目概述一次长达25小时的Agent工程实践最近在AI工程圈里一个关于“OpenAI Harness Engineering”的讨论引起了我的注意。简单来说这不是一个具体的产品而是一种工程方法论或实践模式核心思想是像“驾驭”一样系统性地利用AI模型特别是像GPT-4、Claude Code这类代码生成模型来完成复杂的软件开发任务。我看到的这个项目标题很有意思“从 OpenAI Harness Engineering 蒸馏出四个 SkillAgent 跑了 25 小时”。这立刻让我联想到这很可能是一个探索AI智能体Agent自动化编码的极限实验。这个项目本质上是一次深度工程实践构建一个能够自主编码的AI Agent并让它连续运行25小时试图从“驾驭工程”的理念中提炼出四个核心的“技能”。这里的“Skill”不是指人的能力而是指赋予AI Agent的、可复用的、针对特定编码任务的程序化能力模块。而“跑了25小时”则暗示了这是一个长时间、高强度的自动化测试目的是观察Agent在无人干预下的稳定性、任务完成度以及“技能”的有效性。对于任何关注AI编程助手、自动化开发以及未来软件工程形态的开发者、技术负责人或创业者来说这个实验都极具参考价值。它触及了几个核心问题当前的AI编码能力边界在哪里如何系统化地构建一个可靠的编码Agent长时间运行的挑战是什么以及我们究竟能从中学到哪些可复用的工程模式2. 核心思路拆解何为“Harness Engineering”与“Skill蒸馏”在深入实操之前我们必须先厘清两个核心概念“Harness Engineering”和“Skill蒸馏”。这不仅是理解本项目的基础也是构建任何复杂AI编码系统的思维框架。2.1 解构“Harness Engineering”超越简单提示词“Harness”直译是“马具”、“驾驭”在工程上常指“测试工具”或“控制框架”。因此“Harness Engineering”可以理解为“驾驭式工程”或“框架化工程”。它区别于我们日常零散地使用ChatGPT或Copilot写几行代码。其核心在于系统性和工程化。想象一下你不是在让一匹马AI模型随意奔跑而是为它套上缰绳、安上马鞍、规划好路线Harness让它能按照既定目标稳定、高效地完成长途运输任务。在AI编码的语境下“Harness”就是这一整套控制框架任务分解与规划系统不是扔给AI一个“开发一个博客系统”的模糊指令而是将其分解为“设计数据库Schema”、“实现用户认证REST API”、“编写前端登录组件”等一系列原子任务并理清依赖关系。上下文管理与记忆Agent需要知道当前项目的整体结构、已完成的代码、之前的决策逻辑以及遇到的错误。这需要一套精密的上下文窗口管理、向量数据库检索或更高级的长期记忆机制。工具调用与执行环境真正的编码不只是生成文本还要能执行命令如git,npm、运行测试、调用外部API如获取天气数据、甚至操作IDE。Harness需要为Agent提供安全的“手和脚”。验证与反馈循环生成代码后必须有自动化机制进行验证静态检查Lint、单元测试、集成测试、甚至代码评审模拟。根据验证结果Harness要能引导Agent进行迭代修正。异常处理与降级策略当Agent陷入死循环、生成无意义代码或遇到无法解决的问题时Harness需要有超时机制、回滚策略或触发人工干预的流程。OpenAI团队内部可能采用类似的方法才能在“5个月零手写代码产出100万行系统”这样的传闻中取得成效。这不仅仅是模型能力强更是工程框架设计得好。2.2 “Skill蒸馏”从方法论到可复用模块“蒸馏”这个词用得很妙。在机器学习中知识蒸馏是指将大模型教师模型的知识压缩到小模型学生模型中。在这里“Skill蒸馏”是指从“Harness Engineering”这一庞大的方法论和无数次实验运行中提炼、固化出几个最关键、最通用、最有效的“技能”模块。这些“Skill”应该是高度抽象、可配置、可组合的。它们不是针对某个特定业务如“生成用户登录API”而是针对一类编码活动如“代码重构”、“测试生成”、“Bug定位”。本项目中提炼出的四个Skill就是这次25小时长跑实验最重要的产出。我们可以推测它们可能覆盖了智能体编码工作流中的几个关键环节需求解析与任务规划Skill将自然语言或模糊需求转化为具体的、可执行的任务列表和依赖图。上下文感知与代码检索Skill在庞大的代码库中快速定位相关代码、理解现有架构并为新代码生成提供精准的上下文。增量开发与迭代修正Skill以“小步快跑”的方式生成代码并基于测试反馈或静态分析结果进行自动修正避免一次性生成大量不可运行的代码。系统交互与工具调用Skill安全、规范地调用外部工具命令行、API、数据库等并正确处理返回结果。蒸馏出这些Skill的意义在于未来构建新的编码Agent时可以直接将这些经验证有效的模块像乐高积木一样组装起来大幅降低开发门槛和失败风险。3. 实验环境搭建与核心工具选型要复现或借鉴这样一个长时间运行的Agent实验环境搭建是第一步。这里的选择直接决定了Agent的能力上限和运行稳定性。3.1 模型选型Claude Code vs. GPT系列模型是Agent的“大脑”。当前在代码生成领域第一梯队的选择主要是OpenAI的GPT-4系列和Anthropic的Claude 3系列特别是Claude 3 Opus及其衍生的代码专用版本。GPT-4 (GPT-4 Turbo): 优势在于通用性强生态成熟API稳定工具调用Function Calling功能设计得非常好。对于需要复杂逻辑推理和广泛知识面的任务它仍然是首选。但成本相对较高且对于超长代码上下文如128K的处理效率需要评估。Claude 3 Opus / Claude Code: Anthropic的模型在长上下文处理上口碑极佳200K的上下文窗口是巨大优势非常适合需要携带大量项目代码作为参考的场景。它在代码生成的“逻辑严谨性”和“对指令的遵循程度”上经常获得开发者好评。Claude Code可能是针对代码场景进一步微调的版本。其API协议与OpenAI相似但并非完全兼容迁移时需注意。选择建议如果你的实验严重依赖长上下文例如需要分析整个代码仓库Claude Code可能是更好的起点。如果更看重工具调用的便捷性和生态工具链如LangChain对OpenAI的支持最全面GPT-4 Turbo是稳妥之选。本项目标题提及“OpenAI Harness Engineering”但实际Agent运行可能使用Claude Code这恰好说明了“Harness”的模型无关性——好的框架应该能适配不同的底层模型。3.2 开发框架与平台从LangChain到自主框架“Harness”需要一个骨架来实现这就是开发框架。LangChain / LlamaIndex: 对于快速原型验证它们是绝佳选择。提供了链Chain、代理Agent、工具Tool、记忆Memory等丰富的抽象。你可以用很少的代码搭建一个具备基础能力的Agent。但是对于“跑了25小时”这种强度和高定制化需求的实验纯用LangChain可能会遇到性能瓶颈、控制粒度不够细、调试困难等问题。标题中提到的“LangChain 仅优化 ha...”可能暗示了仅用LangChain不足以构建生产级Harness需要深度优化或自研。自主开发框架这是实现真正“Harness Engineering”的常见路径。你可以用Python从头构建核心组件包括任务队列与调度器使用Celery、RQ或简单的asyncio队列来管理待执行任务。状态机定义Agent的各个状态如“需求分析”、“编码中”、“测试中”、“等待反馈”并管理状态转换逻辑。上下文管理器负责维护对话历史、代码片段、工具调用结果。这里需要集成向量数据库如Chroma, Weaviate来实现基于语义的代码检索。工具抽象层统一封装对命令行、文件系统、API的调用并做好权限隔离和沙箱安全。观察与评估模块记录Agent的每一步操作、每一次模型调用并评估生成代码的质量通过测试通过率、静态分析得分等。我个人的经验是初期可以用LangChain快速验证想法但当你要进行长时间、自动化实验时往往会过渡到一个更轻量、更可控的自研框架上只从LangChain中抽取最有用的模块比如它的某些工具封装或提示词模板。3.3 安全与执行沙箱让Agent安全地“动手”这是至关重要且容易忽略的一环。让一个AI Agent自由运行命令和写文件是极其危险的。你必须建立一个安全的沙箱环境。容器化隔离使用Docker是最佳实践。为Agent创建一个干净的容器镜像包含项目所需的最小化运行时环境Node.js, Python等。每个任务或每一轮交互都在一个全新的、短暂的容器中运行任务结束后容器销毁。这确保了环境纯净也防止了Agent对宿主机造成破坏。资源限制在Docker运行参数中严格限制CPU、内存、磁盘空间和网络访问。避免Agent运行死循环代码耗尽资源。命令白名单不要允许Agent执行任意shell命令。应该实现一个工具层只暴露安全的、预先定义好的命令例如run_tests,install_dependencies,git_add等。在这些封装函数内部再进行参数校验和安全性检查。文件系统监控Agent的写权限应被限制在项目工作目录内。可以使用chroot或容器映射来实现。同时可以监控文件的频繁修改行为以防Agent陷入不断重写同一文件的循环。4. 四个核心Skill的具象化设计与实现基于前面的思路我们来具体构想一下那四个被“蒸馏”出来的Skill可能如何设计和实现。这是本次实验最精华的部分。4.1 Skill 1: 结构化任务分解与规划器这个Skill负责将用户或上级系统输入的模糊目标如“添加一个用户个人资料页面”转化为一张清晰的可执行任务图。实现要点输入规范化首先用一个提示词让模型将模糊需求重写为一个结构化的“项目目标描述”包括主要功能点、非功能性要求性能、安全等。生成任务列表基于目标描述让模型生成一个任务列表。每个任务应是原子性的例如“在backend/models目录下创建UserProfile模型”、“在backend/api目录下创建获取个人资料的GET端点”、“在frontend/components目录下创建Profile.vue组件”。识别依赖关系模型需要分析任务间的依赖。例如“创建API端点”依赖于“创建数据模型”“前端组件”依赖于“后端API”。输出应是一个有向无环图DAG。输出结构化数据最终输出必须是机器可读的格式如JSON或YAML。这样后续的调度器才能直接解析并执行。{ project_goal: 添加用户个人资料页面, tasks: [ {id: 1, description: 创建UserProfile数据模型, type: backend_model, depends_on: []}, {id: 2, description: 创建GET /api/user/profile端点, type: backend_api, depends_on: [1]}, {id: 3, description: 创建前端Profile组件, type: frontend_component, depends_on: [2]} ] }实操心得这个环节的提示词设计非常关键。你需要提供大量“好任务”的示例强调原子性、可验证性。同时要设定规则比如“一个任务对应的代码变更最好不超过5个文件”。否则模型可能会生成“实现整个前端页面”这样过于宏大的任务导致后续步骤失败。4.2 Skill 2: 上下文感知的代码生成器这是Agent的“核心生产车间”。它接收一个具体任务和当前代码库的上下文生成或修改代码。实现要点上下文检索与构建这是难点。不能简单地把整个项目代码塞进提示词。需要根据任务描述从代码库中检索最相关的文件。基于路径/命名的检索如果任务是“修改utils/logger.py”直接获取该文件。基于语义的检索使用嵌入模型如text-embedding-3-small将代码文件向量化。当任务描述是“实现一个与用户认证类似的日志中间件”时从向量库中查找与“认证”、“中间件”相关的代码文件。关键文件固定包含永远包含项目根目录的配置文件如package.json,requirements.txt、架构说明文档等让模型了解项目技术栈。提示词工程提示词必须清晰、结构化。一个有效的模板通常包括系统角色设定”你是一个资深软件工程师专注于编写简洁、高效、可维护的代码。”项目概况技术栈、目录结构、编码规范。当前任务详细描述。相关代码上一步检索到的代码片段用清晰的标记如### FILE: path/to/file.py分隔。操作指令明确要求如“请只输出需要新增或修改的代码用差分格式diff或明确指出要插入到哪个文件的什么位置之后。”生成与解析模型输出可能是代码块、diff格式或自然语言描述代码。需要编写一个解析器能准确提取出代码变更并应用到实际文件系统中。踩坑记录模型有时会“幻觉”出不存在的函数或类。解决方法是在提示词中强调“只使用现有代码库中出现的类和函数如果缺少请先实现它们”。另外生成代码后立即进行一次简单的语法检查如python -m py_compile或node -c可以提前发现低级错误避免错误累积。4.3 Skill 3: 自动化测试与验证执行器生成代码不是终点验证其正确性才是。这个Skill负责运行测试并解释结果。实现要点测试套件发现与执行根据项目类型自动发现并运行相关的测试。对于Python项目运行pytest。对于Node.js项目运行npm test或jest。需要能解析测试输出获取通过/失败的数量和具体的失败信息。静态分析与代码质量检查集成Linter如flake8for Python,ESLintfor JS和代码格式化工具如black,prettier。将违规信息作为反馈的一部分。反馈信息提炼测试失败信息可能很冗长。需要提炼出关键错误是编译错误运行时异常还是某个具体的断言失败将这些信息结构化后提供给下一个环节迭代修正。安全执行所有测试必须在之前提到的沙箱容器中运行确保不会影响主环境。一个反馈数据的结构示例{ task_id: 2, validation_passed: false, test_results: { total: 5, passed: 3, failed: 2, failures: [ { test_name: test_get_user_profile_not_found, error_type: AssertionError, error_message: Expected status code 404, but got 500., traceback: ... } ] }, lint_errors: [line 15: E501 line too long (82 79 characters)] }4.4 Skill 4: 迭代式调试与修正循环控制器当测试或检查失败时Agent不能直接放弃而应该进入一个调试修正循环。这个Skill管理这个循环。实现要点分析失败根源将验证执行器产生的失败信息连同出错的代码上下文再次发送给模型。提示词要引导模型分析原因例如“上述测试失败是因为API返回了500内部服务器错误而不是预期的404。请分析backend/api/profile.py中的get_profile函数找出可能引发500错误的原因。”生成修正方案模型基于分析提出代码修改方案。这可能比初次生成要求更高因为需要理解错误和现有代码的交互。应用修正并重新验证应用修正然后跳回Skill 3验证执行器再次运行测试。循环控制与熔断必须设置一个最大迭代次数例如5次。如果超过次数仍未通过则判定任务失败记录详细日志并可能升级到“需要人工干预”的状态。这防止了Agent陷入无限循环。核心技巧在修正循环中提供给模型的上下文应该越来越聚焦。第一次失败提供整个函数第二次失败可能只提供相关的几行代码和更详细的错误堆栈。这有助于节省令牌数并提高模型注意力。同时要记录每次修正的变更如果发现模型在来回修改同一段代码可以主动终止循环。5. 构建25小时耐力测试的完整工作流将上述四个Skill串联起来就构成了一个完整的自治编码Agent工作流。让这个工作流稳定运行25小时是对整个系统健壮性的终极考验。5.1 工作流编排与状态管理整个系统可以看作一个状态机核心状态包括IDLE空闲、PLANNING规划、EXECUTING_TASK执行任务、VALIDATING验证、DEBUGGING调试、FAILED失败、SUCCEEDED成功。初始化与目标输入工作流从一个明确的开发目标开始。目标可以是一个用户故事User Story或一个Issue描述。触发Skill 1规划器系统进入PLANNING状态调用规划器Skill生成任务图DAG。任务调度系统进入主循环。调度器从任务图中选取所有就绪即依赖已全部完成的任务放入执行队列。循环执行单个任务对于队列中的每个任务 a. 状态置为EXECUTING_TASK。 b. 调用Skill 2代码生成器结合当前代码库状态生成或修改代码。 c. 应用代码变更到工作副本。 d. 状态置为VALIDATING。 e. 调用Skill 3验证执行器运行测试和检查。 f. 如果验证通过任务状态标记为SUCCEEDED触发其依赖此任务的其他任务变为“就绪”。 g. 如果验证失败状态置为DEBUGGING。调用Skill 4修正控制器进入修正子循环。子循环成功则回到步骤d重新验证子循环失败超过重试次数则任务状态标记为FAILED整个工作流可能进入PAUSED或FAILED状态。循环与完成持续从任务图中获取就绪任务并执行直到所有任务成功整个目标达成或某个关键任务失败且无法绕过。5.2 持久化、监控与可观测性25小时的运行没有监控是不可想象的。全面日志记录记录下每一个关键事件模型调用输入/输出、工具执行命令/结果、文件变更、状态转换。日志要结构化JSON格式便于后续分析。日志级别要细分DEBUG级别记录详细推理过程INFO级别记录关键步骤。度量指标Metrics任务成功率成功完成的任务数 / 总任务数。平均迭代次数每个任务从生成到最终通过平均需要多少次验证-修正循环。令牌消耗按任务、按Skill统计使用的API令牌数这是成本控制的关键。执行时间分布规划、生成、验证、调试各阶段的时间占比。错误类型分布编译错误、测试失败、逻辑错误等各占多少。检查点Checkpointing定期将整个Agent的状态包括代码库的完整快照、任务图进度、记忆上下文持久化到磁盘或数据库。这样如果系统意外崩溃如断网、API限额用尽可以从最近的检查点恢复而不是从头开始。这是长时运行系统的必备特性。可视化仪表盘一个简单的Web界面实时展示任务图的状态用不同颜色标记成功、失败、进行中、资源消耗曲线、最新日志流。这让你在25小时内不用一直盯着终端。5.3 长时运行特有的挑战与应对策略连续运行一天以上会遇到一些短期测试中不明显的问题API稳定性与限流所有云AI服务都有速率限制和配额。必须实现健壮的重试机制和退避策略如指数退避。同时要监控配额使用情况在接近限额时优雅暂停而不是突然被中断。可以考虑配置多个API密钥进行负载均衡。上下文累积与模型失焦随着对话轮次增加上下文会越来越长。虽然Claude支持长上下文但成本会飙升且模型在超长上下文末尾的注意力可能下降。策略是定期总结和清理。例如每完成一个主要模块就让模型对已做的工作做一个简短总结然后将这个总结和最关键的相关代码作为新的“基础上下文”清空之前冗长的对话历史。代码库熵增与冲突Agent在多个文件上并行或交错修改可能会引入冲突或代码风格不一致。除了靠Linter可以定期如每完成5个任务启动一个“代码整理”子任务让模型统一检查代码风格、删除未使用的导入、优化重复代码。资源泄漏长时间运行的进程可能内存泄漏。确保你的Agent主进程、以及它启动的沙箱容器都有内存上限和自动重启机制。使用像supervisord这样的进程管理工具来守护Agent进程。6. 实验结果分析与经验提炼假设我们的Agent成功运行了25小时我们该如何分析结果并真正“蒸馏”出价值6.1 量化评估维度不能只看“是否完成了功能”需要多维度评估评估维度具体指标分析目的效率总产出代码行数LoC衡量Agent的“生产力”每小时完成任务数衡量Agent的“速度”任务平均耗时从开始到成功了解端到端效率质量首次生成代码的测试通过率衡量代码生成的“准确性”最终代码的测试覆盖率衡量代码的“健壮性”静态检查Lint违规数衡量代码的“规范性”人工评审抽样缺陷率引入主观质量评估成本总API令牌消耗 费用评估经济可行性平均每行代码成本关键的性价比指标稳健性任务失败率衡量系统可靠性平均调试迭代次数衡量自我修正能力系统异常中断次数衡量框架健壮性通过分析这些数据你可以回答Agent在哪些类型的任务上效率高如写CRUD API哪些任务容易失败如涉及复杂算法或第三方集成调试循环通常卡在哪里6.2 定性经验与模式识别除了数字日志和代码变更记录是宝藏成功模式总结反复查看那些一次性通过或快速修正成功的任务。Agent使用了哪些有效的“策略”例如它是否擅长模仿现有代码风格它是否在写函数前先写文档字符串如果项目中有此惯例将这些模式固化到提示词或Skill的逻辑中。失败根因分析深入分析失败的任务。是需求理解偏差是上下文检索不全是模型“幻觉”了不存在的API还是测试用例本身有问题针对每一类根因思考如何改进系统。例如如果是上下文问题可以强化检索逻辑如果是“幻觉”问题可以在提示词中加入更严格的约束。“技能”有效性验证回顾四个Skill的表现。规划器生成的任务是否粒度合适代码生成器在长上下文下的表现如何验证执行器是否捕获了所有关键问题修正控制器是否有效打破了僵局这可能促使你调整Skill的设计甚至蒸馏出第五、第六个Skill例如“代码审查模拟Skill”或“依赖管理Skill”。6.3 对“Harness Engineering”的再思考经过这样一次深度实践你会对“Harness Engineering”有更血肉的理解它不是银弹它不能替代工程师的架构设计和关键决策。它的价值在于接管大量重复、模式化的编码工作将工程师从“体力活”中解放出来专注于更高层次的抽象、复杂问题解决和系统集成。提示词即代码框架即产品在这个范式下精心设计的提示词和Agent工作流框架其价值不亚于传统软件。它们是需要迭代、测试和维护的核心资产。人机协作的新界面未来的工程师可能更像一个“产品经理”或“驯兽师”负责给AI Agent定义清晰的目标需求、设定约束条件架构与规范、并在关键节点进行评审和纠偏。与AI的交互会变得更加结构化和工程化。让一个AI Agent连续运行25小时完成编码任务听起来像科幻小说但通过系统性的“Harness Engineering”和模块化的“Skill”设计这正在变为可重复的工程实践。这个过程充满挑战从模型选型、安全沙箱、到Skill设计、长时运行维护每一步都需要细致的考量。但回报也是巨大的你不仅获得了一个自动化工具更获得了一套关于如何有效驾驭AI进行复杂创造的方法论。这次实验中最有价值的产出或许不是那25小时内生成的代码而是那四个被蒸馏出来的、可以不断复用和优化的核心Skill以及一整套让AI稳定可靠工作的工程框架。这标志着我们不再是零星地使用AI而是开始系统地将其整合到软件开发的生命周期之中。