ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

从零构建 Claude Code 式编码 Harness:基于 CrewAI、E2B 与 OpenRouter 的分层 Agent 实现

从零构建 Claude Code 式编码 Harness:基于 CrewAI、E2B 与 OpenRouter 的分层 Agent 实现 从零构建 Claude Code 式编码 Harness基于 CrewAI、E2B 与 OpenRouter 的分层 Agent 实现【免费下载链接】ai-engineering-hubIn-depth tutorials on LLMs, RAGs and real-world AI agent applications.项目地址: https://gitcode.com/GitHub_Trending/ai/ai-engineering-hub导读本文围绕仓库build-code-harness/项目展开该项目在 README 中明确描述其目标从零重建rebuilds from scratch类 Claude Code 的编码 Agent harness——一个能对真实 bug 修复任务进行探索、编辑、测试并汇报结果的完整系统同时逐层内置了规划、记忆、检查点、沙箱执行与人工审批human-in-the-loop能力。文中将完整覆盖环境配置与运行步骤并深入 code_harness.py 源码讲清每个Claude Code 能力在 CrewAI 中的对应实现机制。读完你既能直接跑通这个开源示例也能理解如何用 CrewAI 分层搭建一个可靠的编码 Agent。说明原文档正文还包含 Newsletter 订阅推广与 Contribution 引导等与编码 harness 技术无关的内容本文不展开。技术栈与设计思路项目由三个核心服务协作而成README 对此有明确分工E2B沙箱化的 Shell 与 Python 执行环境——对应 Claude Code 中命令运行所依赖的隔离环境CrewAI用于构建层级式hierarchicalAgentic 工作流——对应子 Agent 委派与协作的编排层OpenRouter底层 LLM 提供商——通过一个 key 即可访问多个模型同时兼容任何 LiteLLM 支持的模型字符串。项目入口是单个 Python 文件 code_harness.py源码注释用一段能力映射把 Claude Code 的概念逐一翻译到 CrewAI 实现上模型 Brain文件工具 Hands子 Agent HelpersManager OrchestratorCrew.kickoff LoopplanningTrue Deep Agent 开关。理解这套映射后后续每层能力都能对号入座。环境配置与依赖安装1. 获取并配置 API KeyE2B API Key必需访问 E2B 官网注册账号在 Dashboard 创建新 Key然后写入.env文件需将.env.example重命名为.envE2B_API_KEY...OpenRouter API Key必需或任意 LiteLLM 支持的 provider keyOPENROUTER_API_KEY... MODELopenrouter/anthropic/claude-sonnet-4-6OpenAI API Key仅用于记忆模块README 特别说明——本 crew 开启了memoryTrue而 CrewAI 的记忆系统需要 embedding 模型先把文本转成向量才能保存/召回。默认 embedder 是 OpenAI 的text-embedding-3-large它与 agent 本身使用哪个 provider 无关因此即使项目中所有 LLM 调用都走 OpenRouter这个 key 依然必须配置。OPENAI_API_KEY...README 同时给出了两条规避方案从 .env.example 与源码可相互印证一是将 embedder 切换到其他 provider例如embedder{provider: ollama, ...}CrewAI memory 文档支持二是直接关闭memoryTrue。.env.example中对应的注释也确认了这一点。2. 安装依赖项目要求Python 3.11 或更高版本并安装 uv[project] name build-code-harness version 0.1.0 requires-python 3.11 dependencies [ crewai[tools,litellm], crewai-tools[e2b], python-dotenv, pytest, ]其中crewai[tools,litellm]表明 LLM 接入基于 LiteLLMcrewai-tools[e2b]引入 E2B 沙箱工具pytest用于承载workspace中的测试套件。执行同步uv sync运行项目进入项目目录并启动主脚本cd build-code-harness uv run python code_harness.pyREADME 提醒了两点运行期行为任务设置了human_inputTrue运行在得出答案后会暂停在终端等待你的批准后才算完成checkpointTrue会在每个任务完成后把进度写入./.checkpoints/该目录可在两次运行之间安全删除建议加入.gitignore。从源码看主流程在if __name__ __main__:分支中调用crew.kickoff(inputs{...})把一个真实的 bug 工单作为 objective 注入任务模板最终print(result)输出结果code_harness.py。内置的演示 Bug测试套件驱动整个 Harness项目自带一个微型演示仓库workspace/。README 明确其中预置了两个真实 bug配套 pytest 套件初始状态为3 failing / 2 passing一次完整运行应探索代码、只修复实现并把套件驱动到5 passing。逐个对照源码可定位到两个 bugwithdraw缺少透支检查——account.py 中withdraw直接self.balance - amount没有余额校验对应测试 test_account.py 期望在余额不足时抛出InsufficientFunds并保持余额不变transfer把款项记到了错误账户——account.py 中transfer调用的是self.withdraw(amount)后紧接self.deposit(amount)钱回到了自己账户而非other账户对应测试 test_account.py 期望alice余额减 30、bob余额加 30。此外transfer_respects_overdraft测试还把透支约束也覆盖了test_account.py。由于两个 bug 都只在account.py中而 harness 被要求只修account.py永不修改测试这条工单天然地迫使完整循环跑起来探索仓库 → 规划修复 → 编辑 → 运行测试 → 迭代至全绿。源码中的实际任务描述也正是如此code_harness.py。逐层拆解Harness 的架构实现第 1 层大脑——可插拔模型CrewAI 的 LLM 抽象让模型可替换成为可能。模型串从环境变量读取并带默认值MODEL os.getenv(MODEL, openrouter/anthropic/claude-sonnet-4-6) # swap here llm LLM(modelMODEL)所有 agent 与 manager 共享同一个llm实例默认模型是经 OpenRouter 访问的anthropic/claude-sonnet-4-6任何 LiteLLM 支持的模型字符串都可替换只需修改该行或环境变量。第 2 层双手——文件工具与沙箱工具Claude Code 的read_file/write_file/ls直接映射为 CrewAI 的文件工具code_harness.pyread_file FileReadTool() write_file FileWriterTool() # overwrites; edit read-then-write list_dir DirectoryReadTool() filesystem_tools [read_file, write_file, list_dir]write_file是覆盖写所以编辑本质是先读后写。沙箱是编码 agent 与普通聊天 agent 的关键差异。CrewAI 生态中受支持的路径是接入真实沙箱服务E2B 提供临时 VM 中的 Shell Python其 Shell 足以承载 grep/glob底层即真实的grep/find。源码在检测到E2B_API_KEY后才导入并构建沙箱工具code_harness.pysandbox_tools [] exec_tool None if os.getenv(E2B_API_KEY): from crewai_tools import E2BExecTool, E2BPythonTool exec_tool E2BExecTool() sandbox_tools [exec_tool, E2BPythonTool()] # run tests / run code自定义工具run_tests源码注释点出一个重要事实内置工具没有运行测试套件并报告通过/失败的语义只有通用 shell 执行。因此项目用tool装饰器手写了一个测试形态的薄封装把命令提交给上面的exec_tool从而与其他编码、测试动作运行在同一个隔离 VM 中code_harness.pyfrom crewai.tools import tool if exec_tool is not None: tool(run_tests) def run_tests(path: str tests/) - str: Run the pytest suite at the given path inside the sandbox and return the result. return exec_tool.run(commandfpytest {path} -q) custom_tools [run_tests] else: # No E2B key means no sandbox at all, so there is nowhere safe to run this. custom_tools []注意它的命名空间工具名run_tests是代码中唯一由项目自行设定的字符串后面审批门禁的集合构建正依赖这一点。同时注意无 E2B Key 即不定义该工具是有意的设计——一个无处路由的命令不算值得交给 agent 的工具。第 3 层帮手——三个专职子 AgentClaude Code 通过派生子 agent 来拆分工作、隔离上下文。在 CrewAI 中子 agent就是 manager 可以委派的对象而role/goal/backstory三件套即该 agent 的系统提示词——可靠性正是在这里被调优的。项目定义了三个角色code_harness.pyAgentrole负责内容挂载工具关键参数explorerCodebase Explorer在改动前读目录与文件建立仓库全貌绝不猜测文件内容read_file,list_dirllmllm,verboseTruecoderSoftware Engineer编辑磁盘文件实现最小且正确的改动filesystem_tools sandbox_toolsreasoningTrue,verboseTruetesterTest Runner在沙箱内运行测试并如实汇报 pass/fail不运行就绝不说通过sandbox_tools [read_file] custom_toolsverboseTrue值得展开的是coder上的reasoningTrue。源码注释强调它与 crew 级planningTrue的区别这是agent 级的规划表面——该 agent 在执行任务前自行反思并草拟一份简短计划而非由 crew 为所有人提前统一规划一次。作者特别说明之所以值得为coder单独开启是因为编辑磁盘文件是整个 crew 中最难撤销的动作code_harness.py。第 4 层编排者——允许委派的 ManagerProcess.hierarchical的本质是一个 manager agent 向上述帮手委派工作这正是 Claude Code 派生子 agent 的 CrewAI 对偶code_harness.pymanager Agent( roleEngineering Lead, goalBreak the request into steps and delegate each to the right specialist., backstory( You own the outcome. You decide who does what, review their results, and only finish once the change is implemented and the tests have actually run. ), llmllm, allow_delegationTrue, # delegation is off by default; the manager needs it on verboseTrue, )注释强调allow_delegation默认是关闭的manager 必须显式开启它。backstory你拥有最终结果……只有改动落地且测试真正跑过才算完本质是在约束 manager 的验收标准。第 5 层任务——开放目标 人工审批任务被刻意设计成一个开放式目标不预先指派给某个 agent而是由 planner manager 自行拆解、自由委派code_harness.pytask Task( description( In the working directory ./workspace, {objective}. Explore the code first, make the change, then run the tests and report. ), expected_outputA summary of the files changed and the final test output., human_inputTrue, )human_inputTrue是 CrewAI 的人机协同门禁一旦 crew 得出答案会在 CLI 上暂停、请求批准或反馈然后运行才算完成。这与第 7 层的命令级审批是两个不同位置的门禁一个在任务完成后一个在工具调用前。第 6 层主循环与深度 Agent开关crew.kickoff()就是循环本身而planningTrue是把浅层工具调用 crew 变成深度 agent的开关code_harness.py每次迭代前会有一个 AgentPlanner 写出逐步计划并注入任务——这相当于 Claude Code 的 todo-list 规划工具可理解为把规划当作上下文工程planning as context engineering。注意planning 默认使用gpt-4o-mini实际运行代码则把它显式设为 OpenRouter 上的同名模型见第 8 层 Crew 构造。记忆系统跨会话的长期记忆memoryTrue开启 CrewAI 的统一记忆系统crew 不仅记住单次运行内发生了什么还能记住过去多次kickoff()调用的经验。源码注释把这一点定位为跨会话击败上下文窗口限制的手段也正是 Claude Code 长期记忆与持久化的对应物——它与第 8 层的 checkpointing 是两回事memory 是跨运行的事实回忆checkpoint 是中断运行的恢复。第 7 层命令审批门禁在工具运行之前拦截这是全文最值得细读的安全机制。前面的Task(human_inputTrue)审查的是已经完成的答案而这里的 hook 是更早的一道闸在某个特定工具调用真正执行之前拦截它并且可以直接阻止。源码注释强调这是 Claude Code 权限层最接近的对偶物——约束在模型之外强制执行而不是一条要求模型小心的提示code_harness.pyfrom crewai.hooks import before_tool_call GATED_TOOLS {write_file.name, run_tests, *(t.name for t in sandbox_tools)} before_tool_call def require_approval(context): if context.tool_name in GATED_TOOLS: response input( fApprove {context.tool_name} with input {context.tool_input}? [yes/no] ) if response.strip().lower() ! yes: return False # blocks the call; the agent is told it was denied return None几个实现细节值得逐一说明门禁集合的构建方式GATED_TOOLS由上文已导入并实例化的真实工具对象集合组成write_file.name、sandbox_tools的工具名。run_tests以字面量字符串加入——因为它是项目通过tool(run_tests)自行设定的名字是集合中唯一一个百分之百确定的名称run_tests为何值得纳入门禁它如今通过exec_tool提交真实命令而非非沙箱执行尽管其命令被约束为比裸E2BExecTool更窄的pytest {path} -q但仍在沙箱内执行因此与其他沙箱工具走同一道审批hook 的返回值语义ToolCallHookContext只暴露tool_name、tool_input、tool、agent、task、crew、tool_result没有内置询问人类的方法因此在 stdin 上阻塞与Task(human_inputTrue)的工作方式保持一致。返回False会阻止该调用agent 会被告知请求被拒返回None则放行不变。第 8 层Crew 组装与断点续跑最后把所有部件组装成一个 Crewcode_harness.pycrew Crew( agents[explorer, coder, tester], tasks[task], manager_agentmanager, processProcess.hierarchical, planningTrue, planning_llmLLM(modelopenrouter/openai/gpt-4o-mini), memoryTrue, checkpointTrue, verboseTrue, )Checkpointing对应 README 的运行说明checkpointTrue在每个已完成任务之后把 crew 状态写入./.checkpoints/。若一次长运行中途被杀可以从最后保存的检查点继续而不必从头重来——这是长任务扛住中断的 CrewAI 方案与memoryTrue的跨运行事实回忆明确区分。完整能力映射速查表为便于快速引用将 Claude Code 能力与本文实现要点汇总如下Claude Code 能力本项目实现关键证据模型/推理LLM(modelMODEL)可经 OpenRouter 换模型code_harness.py文件读写FileReadTool/FileWriterTool/DirectoryReadToolcode_harness.py沙箱 Shell/代码执行E2B 的E2BExecTool/E2BPythonTool临时 VMcode_harness.py测试执行自定义run_tests薄封装路由进exec_toolcode_harness.py子 Agent / 上下文隔离explorer/coder/tester三专职 agentcode_harness.py编排与委派Process.hierarchicalmanager_agentallow_delegationTruecode_harness.pytodo 计划工具planningTrue 独立的planning_llmcode_harness.py长期记忆memoryTrue默认 OpenAItext-embedding-3-largeembeddercode_harness.py命令审批before_tool_callhook GATED_TOOLScode_harness.py断点续跑checkpointTrue写./.checkpoints/code_harness.py结果人工审批Task(human_inputTrue)code_harness.py运行验证建议与限制若想让完整门禁生效务必先配置好E2B_API_KEY无此 key 时沙箱工具与run_tests都不会被定义coder/tester实际可用的能力会显著受限这是源码中的有意设计非缺省兜底memoryTrue强依赖 OpenAI embedder key不想引入第二个 provider 时可如 README 所述改用其他 embedder 或关闭 memory运行后产生的./.checkpoints/目录为运行期产物两次运行之间可安全删除建议加入.gitignore本项目是教学性重建in-depth tutorial目标是把成熟的编码 agent 能力逐层还原在开源的 CrewAI E2B OpenRouter 组合上供开发者学习每个能力层的底层原理后自行裁剪扩展。示例代码位于 code_harness.py被修复的缺陷与测试用例位于 workspace/account.py 与 workspace/tests/test_account.py可作为最小复现与验证载体。【免费下载链接】ai-engineering-hubIn-depth tutorials on LLMs, RAGs and real-world AI agent applications.项目地址: https://gitcode.com/GitHub_Trending/ai/ai-engineering-hub创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进