全栈开发知识库

第七章 构建你的智能体框架(架构导读)

一句话总结

这一章是全书的"内功大考":把前六章学到的所有零件——LLM 调用、消息、工具、范式——组装成一个可以 pip install、可以 import、别人拿去就能用的智能体框架。完整的 15 文件手敲教程在 docs/2 第 18 篇《终极手敲-构建你自己的Agent框架》,本文负责让你先看懂架构再动手,敲起来事半功倍。

为什么要自己造框架(明明有 LangGraph 们)

三个理由,一个比一个实在:

  1. 祛魅:用过框架(第六章)你会觉得它们很神,造过框架你会发现核心不过千行代码。祛魅之后,再读 LangChain/AutoGen 源码就像逛自己家后院;
  2. 面试硬通货:"我从零写过一个支持四种范式、可 pip 安装的 Agent 框架"——这句话在面试里的分量,远超"我会用 LangChain";
  3. 工程能力跃迁:包设计、抽象基类、依赖注入、多提供商适配……这些通用软件工程能力,只有"造轮子"能逼你练出来。

框架的架构:五层积木

动手前,先把要造的东西的全貌装进脑子。我们的迷你框架(myagents)分五层,自下而上依次构建:

┌─────────────────────────────────────────┐
│  第5层 Agent 范式层                        │
│  SimpleAgent / ReActAgent / ReflectionAgent│
│  / PlanAndSolveAgent / FunctionCallAgent   │
├─────────────────────────────────────────┤
│  第4层 工具层  Tool / ToolRegistry / 内置工具 │
├─────────────────────────────────────────┤
│  第3层 LLM 层  多提供商适配 / 流式 / 原生函数调用│
├─────────────────────────────────────────┤
│  第2层 数据层  Message(消息) / Config(配置)   │
├─────────────────────────────────────────┤
│  第1层 包基建  pyproject.toml / __init__.py  │
└─────────────────────────────────────────┘

每一层解决一个明确的问题:

  • 包基建:让 pip install -e . 生效,你的代码从"一堆脚本"升格为"一个可安装的库"。pyproject.toml 是包的身份证(名字、版本、依赖、Python 版本要求);
  • 数据层:Message(role + content 的标准结构)统一全框架的对话表示;Config 集中管密钥、模型名、超时等配置——别让 os.getenv 散落在二十个文件里;
  • LLM 层:一个 LLM 类适配多家提供商(DeepSeek/通义/Kimi/本地 Ollama……),支持流式输出和原生 tool_calls。框架最值钱的一层:上层代码永远不用关心底下接的是哪家模型;
  • 工具层:Tool 定义"一个工具长什么样"(名字、描述、参数、执行函数),ToolRegistry 负责注册和查找——第四章 ToolExecutor 的正式版;
  • 范式层:一个抽象基类 Agent 定义所有智能体的公共骨架(名字、LLM、run 方法),五个子类各实现一种范式——第四章徒手写的三个范式,在这里变成框架的"标准件",外加最简单的 SimpleAgent 和用原生函数调用的 FunctionCallAgent。

名词补课——抽象基类(ABC):Python 里"只定规矩、不干实事"的类。Agent 基类规定"所有智能体必须有 run 方法",子类不实现就报错。这保证了框架使用者面对任何范式都是同一套用法:agent.run(question)。

造完之后长什么样(先看终点)

框架完工后,使用者(包括三个月后的你)的体验是这样的:

from myagents import LLM, Config
from myagents.agents import ReActAgent
from myagents.tools import ToolRegistry, calculator

config = Config()                       # 自动读 .env
llm = LLM(config)                       # 自动识别提供商
registry = ToolRegistry()
registry.register(calculator)

agent = ReActAgent("小助手", llm, registry)
print(agent.run("123 乘以 456 等于多少?"))

五行组装一个能用工具的智能体——对比第一章你敲的 110 行单文件,这就是"框架化"的意义:把不变的部分沉淀成库,把会变的部分留给使用者。

动手路线(去 docs/2 第 18 篇,按顺序敲)

完整教程 15 个文件、约 600 行,分八节循序渐进,每节带 Checkpoint:

  1. 第 1~2 节:建包骨架(pyproject.toml + 空 __init__.py)→ pip install -e .。注意教程里的顺序:先建好所有 __init__.py 再安装,顺序错了会踩"命名空间包"的坑(教程里有说明);
  2. 第 3 节:message.py + config.py(数据层,用 dataclasses);
  3. 第 4 节:llm.py(多提供商检测、流式、invoke_with_tools 原生函数调用);
  4. 第 5 节:tool.py + registry.py + builtin_tools.py(工具层);
  5. 第 6~7 节:base.py 抽象基类 + 五个范式各一个文件;
  6. 第 8 节:总装测试——在框架外面新建项目,import myagents 跑通全部五种范式。

总验收标准:在任意新目录里 from myagents.agents import ReActAgent 能用,五种范式全部跑通,你就拥有了一个真正属于自己的框架。

面试视角:造框架时最值得记住的三个设计决策

  1. "为什么 LLM 层要做多提供商适配?"——供应商锁定是真实风险(涨价、限流、下线)。适配层让"换模型"变成改一行配置。追问实现:按 base_url 特征自动检测提供商,各家的小差异(参数名、流式格式)在适配层内消化。
  2. "文本协议解析工具调用 vs 原生 Function Calling,怎么选?"——文本协议(Action: xxx[...])通用、任何模型都能用,但解析易碎;原生 tool_calls 可靠、结构化,但依赖模型支持。框架两种都提供(ReActAgent 用前者,FunctionCallAgent 用后者),让使用者按模型能力选。
  3. "抽象基类的 run 方法为什么只收一个字符串?"——接口最小化原则:签名越简单,子类越自由,使用者心智负担越小。复杂需求(历史、流式回调)通过构造函数和可选参数扩展,不污染核心接口。

划重点

  1. 造框架的三重收益:祛魅、面试硬通货、工程能力跃迁。
  2. 架构五层自下而上:包基建 → 数据 → LLM → 工具 → 范式,每层只解决一个问题。
  3. 框架化的本质:不变的沉淀成库,会变的留给使用者。
  4. 抽象基类统一接口、适配层隔离供应商、注册表管理工具——三个模式在所有主流框架里都能找到影子。
  5. 现在就去 docs/2 第 18 篇 动手,敲完回来看第六章的框架,你会有"不过如此"的踏实感。

下一章预告:框架有了,但你的智能体还是"金鱼记忆"——关掉进程就忘光。第八章给它装上记忆系统和 RAG 检索,让它记住你、并能查阅私有知识库。

本页由 Markdown 自动渲染 · 共 628 篇笔记