构建你的Agent框架:从零打造HelloAgents
在前几章中,我们学习了智能体的基础知识,也体验了主流框架带来的开发便利。但从本章开始,我们将进入一个更具挑战性也更有价值的阶段:从零构建一个属于自己的Agent框架——HelloAgents。
需要说明的是,“从零”并不意味着凭空发明——我们将基于对Agent工作原理的深入理解,参考HelloAgents的设计思路,亲手实现每一个核心组件。这是一次从 “使用者”到“构建者” 的能力跃迁。
📊 全文知识框架图
一、为什么要自己造一个框架?
在Agent技术飞速发展的今天,市面上已经有了LangChain、AutoGen等成熟的框架。为什么还要自己造一个?
1.1 市场框架的“四重困境”
第一重:抽象过重
许多框架为了追求通用性,引入了大量抽象层和配置选项。以LangChain为例,它的链式调用机制虽然灵活,但对初学者来说学习曲线陡峭——为了完成一个简单任务,往往需要理解Chain、Agent、Tool、Memory、Retriever等十多个概念。
第二重:迭代太快
商业框架为了抢占市场,API接口频繁变更。开发者常常遇到“代码升级后无法运行”的窘境,维护成本居高不下。
第三重:黑盒化严重
许多框架将核心逻辑封装得太严实,开发者难以理解Agent内部的工作机制,缺乏深度定制能力。遇到问题时只能依赖文档和社区,如果社区不够活跃,反馈可能需要很长时间。
第四重:依赖复杂
成熟框架往往携带大量依赖包,安装包体积庞大,当需要与其他项目代码配合时,可能引发依赖冲突问题。
1.2 从“使用者”到“构建者”的能力跃迁
自己构建Agent框架,实际上是一次从“使用者”到“构建者”的转变。这种转变带来的价值是长期的:
| 价值 | 说明 |
|---|---|
| 深入理解Agent工作原理 | 亲手实现每个组件,真正理解Agent的思考过程、工具调用机制和各种设计模式的优劣 |
| 获得完全控制权 | 对每一行代码拥有完全控制,可以根据具体需求精确调优,不受第三方框架设计理念的约束 |
| 培养系统设计能力 | 框架构建过程涉及模块化设计、接口抽象、错误处理等核心软件工程技能 |
在实际应用中,不同场景对Agent的需求差异很大,往往需要基于通用框架进行二次开发。垂直领域(如金融、医疗、教育)通常需要有针对性的提示词模板、特殊的工具集成和定制化的安全策略。自建框架让我们能够精确控制响应时间、内存使用和并发处理能力,满足生产环境的精细化需求。
二、HelloAgents的设计理念
构建一个新框架,关键不在于功能多寡,而在于设计理念能否真正解决现有框架的痛点。
HelloAgents围绕一个核心问题展开设计:如何让学习者既能快速上手,又能深入理解Agent的工作原理?
2.1 轻量与教学友好的平衡
优秀的教学框架应该具备完整的可读性。HelloAgents按章节分离核心代码,遵循一个简单的原则:任何有一定编程基础的开发者,都应该能在合理时间内完全理解框架的工作原理。
在依赖管理上,框架采用极简策略——除了必要的HTTP请求库和基础工具库外,不引入任何与特定平台绑定的重型依赖。遇到问题时,可以直接定位到框架自身代码,无需在复杂的依赖关系中寻找答案。
2.2 基于标准API的务实选择
OpenAI的API已成为行业标准,几乎所有主流LLM提供商都在努力兼容这一接口。HelloAgents选择基于这一标准构建,而非重新发明一套抽象接口。
这一决策主要基于三点考虑:
- 兼容性保障:掌握HelloAgents后,迁移到其他框架或将其集成到现有项目中时,底层的API调用逻辑完全一致。
- 降低学习成本:无需学习新的概念模型,所有操作都基于你已熟悉的标准接口。
- 跨平台扩展:通过继承
HelloAgentsLLM类并重写部分方法,可以轻松扩展对ModelScope、智谱AI等不同平台的支持。
2.3 渐进式的学习路径
HelloAgents提供一条清晰的学习路径。每一章的学习代码都会保存为一个可通过pip安装的历史版本,无需担心使用代码的成本——因为每个核心功能都将由你自己编写。
这种设计让你可以根据自己的需求和节奏前进。每一次升级都是自然的,不会出现概念跳跃或理解断层。
2.4 统一工具抽象:“一切皆工具”
为了彻底贯彻轻量和教学友好的理念,HelloAgents在架构上做了一个关键简化:除了核心的Agent类,一切都是工具。
记忆(Memory)、RAG(检索增强生成)、RL(强化学习)、MCP(协议)等模块,在众多其他框架中需要独立学习。但在HelloAgents中,它们都被统一抽象为“工具”,极大地降低了学习负担。
三、核心架构:一张图看懂HelloAgents
HelloAgents的架构分为三个层次:
核心框架层:提供最基础的组件——Message(统一消息格式)、Config(配置管理)和HelloAgentsLLM(LLM客户端)。这一层是框架的“地基”。
Agent实现层:在核心框架层之上,实现具体的智能体范式——BaseAgent作为所有智能体的基类,以及ReActAgent、ReflectionAgent、PlanAndSolveAgent等具体实现。
工具系统层:提供统一的工具抽象和工具执行器,让智能体能够调用外部能力。
四、核心组件详解
4.1 Message类:统一消息格式
Message类是框架中最基础的组件之一,负责统一管理智能体之间的消息传递。
设计上,role字段严格限制为四种类型:"user"、"assistant"、"system"、"tool",直接对应OpenAI API规范,确保类型安全。除了content和role两个核心字段,还增加了timestamp和metadata,为日志记录和未来功能扩展预留了空间。
to_dict()方法是其核心功能之一,负责将内部使用的Message对象转换为兼容OpenAI API的字典格式,体现了“内部丰富、对外兼容”的设计原则。
4.2 Config类:集中配置管理
Config类的职责是将代码中的硬编码配置参数集中管理,并支持从环境变量读取。它基于Pydantic的BaseModel实现,提供类型安全和自动验证。
# 需要从 typing 导入 Optional
from typing import Optional
from pydantic import BaseModel
class Config(BaseModel):
"""HelloAgents配置类"""
# LLM配置
default_model: str = "gpt-3.5-turbo"
default_provider: str = "openai"
temperature: float = 0.7
max_tokens: Optional[int] = None
# 系统配置
debug: bool = False
log_level: str = "INFO"
这种设计让配置管理更加清晰,也方便在不同环境中切换配置。
4.3 HelloAgentsLLM:智能的LLM客户端
HelloAgentsLLM是框架与外部LLM服务交互的核心桥梁。它的设计体现了“约定优于配置”的原则——尽量减少用户的配置负担。
自动检测Provider的优先级:
Provider检测机制的核心逻辑:
- 最高优先级:检查
MODELSCOPE_API_KEY、OPENAI_API_KEY、ZHIPU_API_KEY等特定服务商的环境变量 - 第二优先级:解析
LLM_BASE_URL,通过域名匹配(如api-inference.modelscope.cn对应ModelScope)或端口匹配(如:11434对应Ollama)来识别服务商 - 辅助判断:分析API Key格式,如以
ms-开头的Key对应ModelScope
一旦provider确定(无论是用户指定还是自动检测),_resolve_credentials方法会根据provider的值主动搜索对应的环境变量并设置默认的base_url。
4.4 扩展LLM客户端:支持新平台
HelloAgents的设计让扩展新的LLM平台变得非常简单——只需继承HelloAgentsLLM类并重写部分方法。
以扩展ModelScope平台为例:
- 创建子类:继承
HelloAgentsLLM,在__init__中判断provider参数 - 处理特定逻辑:当
provider="modelscope"时,从环境变量读取MODELSCOPE_API_KEY,设置对应的base_url - 保持兼容性:其他情况调用父类的原始逻辑,保持对OpenAI等内置Provider的支持
这种“覆写”的方式确保了代码的整洁性和可维护性,即使未来升级hello-agents库,定制化的功能也不会丢失。
五、从范式到框架:ReAct、Reflection与Plan-and-Solve的实现
第四章我们学习了ReAct、Reflection和Plan-and-Solve三种经典范式。在HelloAgents框架中,我们将这些范式从“独立脚本”升级为“框架的标准化组件”。
5.1 从独立脚本到框架组件
在第四章中,我们通过编写独立的Python脚本来实现ReAct、Reflection和Plan-and-Solve。在HelloAgents框架中,这些实现被重新组织为:
- 继承BaseAgent:所有范式实现都继承自统一的
BaseAgent基类 - 集成工具系统:ReAct的工具调用机制与框架的
ToolExecutor无缝对接 - 统一消息格式:所有输入输出都使用
Message类进行标准化 - 配置驱动:通过
Config类集中管理各范式的参数
这种升级的核心价值在于复用性和可维护性——在框架层面实现一次,就可以在多个应用场景中重复使用。
5.2 设计原则
| 原则 | 说明 |
|---|---|
| 代码复用 | 所有范式共享BaseAgent中的通用逻辑(如消息管理、配置读取) |
| 接口统一 | 所有Agent都提供run()方法,调用方式一致 |
| 工具解耦 | 范式实现与具体工具解耦,通过ToolExecutor动态绑定 |
| 可观测性 | 框架内置日志记录,每一步的思考、行动和观察都可追踪 |
六、核心概念速查表(新手友好)
| 术语 | 通俗解释 |
|---|---|
| HelloAgents | 本章从零构建的Agent框架名称,寓意“Hello World”式的入门框架 |
| 自建框架 | 不依赖LangChain等现成框架,从零开始编写自己的Agent框架 |
| 抽象过重 | 框架为了通用性引入太多概念层,导致学习门槛过高 |
| 黑盒化 | 框架将核心逻辑封装太严,开发者看不清内部工作原理 |
| 统一工具抽象 | HelloAgents的设计理念:除了Agent类本身,其他一切都是工具 |
| 渐进式学习 | 按章节逐步构建框架,每一章在前一章基础上增加新功能 |
| Message类 | 框架中的统一消息格式,兼容OpenAI API规范 |
| Config类 | 集中管理配置参数,支持从环境变量读取 |
| Provider自动检测 | HelloAgentsLLM根据环境变量自动识别LLM服务商 |
七、思考题(帮助加深理解)
-
“抽象过重”是许多成熟框架的通病。 在你使用过的框架中,有没有遇到过“为了用一个功能,需要理解十几个概念”的情况?这种设计对学习和开发效率有什么影响?
-
HelloAgents的设计理念之一是“基于标准API”。 为什么选择OpenAI的API作为标准?这种选择有什么优势和潜在风险?
-
“一切皆工具”是HelloAgents的核心简化策略。 将Memory、RAG等模块统一抽象为工具,带来了什么好处?又可能牺牲了什么?
-
从“独立脚本”到“框架组件”的升级,体现了软件工程中的什么思想? 这种升级对代码的复用性和可维护性有什么帮助?
-
回顾从第四章到第七章的学习路径——从手写ReAct到使用低代码平台,再到使用专业框架,最后自己构建框架。 这条路径对你的学习有什么启发?
参考资料
- Datawhale Hello-Agents 第七章《构建你的Agent框架》
https://datawhalechina.github.io/hello-agents/#/./chapter7/第七章%20构建你的Agent框架
结语
在这一章中,我们完成了从“框架使用者”到“框架构建者”的转变:
- 为什么自建框架——市场框架存在抽象过重、迭代太快、黑盒化、依赖复杂等问题,自建框架能带来深入理解原理、获得完全控制、培养系统设计能力等长期价值
- HelloAgents的设计理念——轻量与教学友好、基于标准API、渐进式学习路径、统一工具抽象
- 核心架构——分为核心框架层(Message、Config、LLM客户端)、Agent实现层(BaseAgent及范式实现)和工具系统层
- 核心组件——Message统一消息格式、Config集中配置管理、HelloAgentsLLM智能客户端
从第四章的手写ReAct,到第五章的低代码平台,到第六章的专业框架,再到本章的自建框架——我们完成了一条完整的学习进阶路径。现在,你不仅知道如何使用Agent框架,更知道如何构建一个Agent框架。
本文参考:Datawhale《Hello-Agents》教程第七章《构建你的Agent框架》的内容框架与核心知识点。本文在忠实呈现该教程内容的基础上,为便于新手理解进行了通俗化改写和图表化呈现。
更多推荐



所有评论(0)