从零搭建一个 Agent Harness:我的第一版最小闭环

📅 2026/6/27 4:41:59
从零搭建一个 Agent Harness:我的第一版最小闭环
从零搭建一个 Agent Harness我的第一版最小闭环系列博客第一篇架构设计与核心模块每天更新记录我手搓 Agent 框架的全过程前言去年开始大模型应用开发的热度持续攀升各种 Agent 框架LangChain、AutoGen、DSPy 等层出不穷。但作为一个“什么都想亲手摸一遍”的开发者我总感觉直接上框架会错过很多底层细节——模型怎么调工具怎么注册事件流怎么设计Trace 怎么落盘于是我决定从零开始搭建一个研究导向的 Mini Agent Harness。目标不是造一个生产级框架而是通过自己动手把 Agent 系统的每一层都拆解清楚让每次执行都可观察、可复盘、可替换。今天我终于跑通了第一版最小闭环趁热打铁把设计思路和代码结构记录下来。后续我会每天更新一步步完善这个 Harness。项目定位与核心目标小而清晰代码量控制在千行级别模块职责单一杜绝过度抽象。闭环优先先让“用户输入 - 模型 - 工具 - 输出”跑通再逐步加功能。可观测性每个关键步骤都产生结构化的RunEvent便于 tracing 和 eval。渐进式学习从纯聊天到工具调用再到多轮、多 Agent按需演进。目前项目托管在本地后续会开源技术栈为TypeScript Node.js模型使用DeepSeek API因为性价比高且支持工具调用。整体架构分层清晰职责单一我设计了如下分层每个模块都放在src/下的独立目录中下面是整体架构的流程图清晰地展示了从 User Prompt 到 Trace/Eval 的数据流向和各模块关系User PromptAgentRuntime调度层TaskPolicy策略层direct or toolAgentEngine执行层chat / toolModelClient模型适配层ToolRegistry工具注册与执行RunEvent stream事件流Trace / Eval可观测与评估User Prompt - AgentRuntime (调度层) - TaskPolicy (策略层direct or tool) - AgentEngine (执行层chat / tool) - ModelClient (模型适配层) - ToolRegistry (工具注册与执行) - RunEvent stream (事件流) - Trace / Eval (可观测与评估)核心模块拆解按目录结构AgentRuntime (src/runtime/)管理一次运行的生命周期接收请求驱动流程生成事件流。TaskPolicy (src/policy/)根据用户输入判断该走“纯聊”还是“工具调用”。Engines (src/engines/)具体的执行器DeepSeekChatEngine 处理普通对话DeepSeekToolEngine 处理工具调用。ModelClient (src/model/)封装 DeepSeek API支持从 key.txt 读取密钥。ToolRegistry (src/tools/)注册所有可用工具统一执行、错误兜底、耗时统计。Trace (src/trace/)消费事件流将完整运行记录落盘为 JSONruns/{runId}.json。Eval (src/eval/)最小化的 benchmark 运行器用于评测任务集。typescript interface ToolResult { ok: boolean; data?: any; // 成功时的返回数据 error?: string; // 失败时的错误信息 meta: { toolName: string; durationMs: number; timestamp: string; }; } --- ## 快速开始 如果你也想动手尝试可以按照以下步骤快速开始 powershell # 克隆项目后续开源后会更新链接 cd /path/to/your/project npm install # 设置 DeepSeek API 密钥支持从 key.txt 读取 $env:DEEPSEEK_API_KEYsk-your-key # 运行一个简单的对话 npm run dev -- 你好介绍一下你自己 # 运行一个需要工具调用的任务 npm run dev -- 读取 README.md然后总结项目目标当前阶段与最新进展项目已经实现了第一版最小闭环包含以下核心组件AgentRuntime- 任务生命周期与事件流调度TaskPolicy- 判断任务走 direct 还是 toolDeepSeekClient- DeepSeek API 适配层DeepSeekChatEngine- 纯聊天模型执行器DeepSeekToolEngine- 工具调用模型执行器ToolRegistry- 工具注册、执行、错误兜底统一RunEvent- 结构化事件协议Trace JSON- 运行记录落盘最小 eval- benchmark 运行器最近新增功能统一ToolResult工具返回协议- 所有工具返回统一的数据结构interfaceToolResult{ok:boolean;data?:any;// 成功时的返回数据error?:string;// 失败时的错误信息meta:{toolName:string;durationMs:number;timestamp:string;};}ToolRegistry增强- 统一处理未知工具、工具异常和耗时统计本地工具完善-read_file、grep、write_file等工具都返回标准化的ok/data/error/meta结构学习文档与资源为了帮助自己和他人更好地理解项目我整理了以下文档docs/architecture.md- 整体架构说明详细解释每一层的设计思路docs/learning-notes.md- 学习笔记记录开发过程中的思考和问题docs/papers/README.md- DeepSeek 论文研读索引docs/change-log/001-tool-result.md- 统一工具返回协议这次改动的详细说明常用命令参考# 代码检查npm run check# 开发运行支持传入用户提示npm run dev--你的提示词# 运行评测任务集npm run eval# 查看 trace 日志lsruns/*.json下一步计划多轮对话支持- 让 Agent 能够记住上下文进行连续对话多 Agent 协作- 实现多个 Agent 之间的任务分配和协作更丰富的工具集- 添加网络搜索、数据库查询等常用工具可视化 Trace- 开发 Web 界面查看运行轨迹和性能指标开源准备- 完善文档、测试和示例准备在 GitHub 开源下一篇预告我将详细介绍ToolRegistry的设计与实现包括工具注册机制、错误处理和性能监控。如果你对某个特定模块感兴趣欢迎在评论区留言我会优先安排相关内容的分享。