
做 AI 大模型应用开发的同学应该都有过这样的经历打开某个 Agent 框架的官方文档准备照着写一个智能体结果发现概念一个接一个——Chain、Graph、Node、State、Memory、Retriever、Tool……光是把框架的“骨架”看懂就已经耗掉了半天时间。等你终于跑通一个 Demo又发现它内部封装太重出了问题根本不知道从哪里排查。这篇文章就来解决这个问题。我会围绕 DeepAgents 这套保持“骨架简单”的智能体框架从核心原理讲到完整实战最后补充工程落地的常见坑点和最佳实践。不管你是刚接触 AI 大模型应用开发的新手还是已经写过一段时间 Agent 代码的开发者这篇文章都能帮你把“框架原理”这条线捋清楚。读完之后你能掌握三件事一是理解 Agent 框架内部的工作循环到底是怎么跑起来的二是能基于 DeepAgents 搭建一个完整的、多工具协作的智能体应用三是知道在真实项目中应该怎么设计工具、怎么调试、怎么做可观测性。1. 从“会调大模型”到“会做 AI 应用开发”差在哪里1.1 单纯调 API 和开发 Agent 应用是两件事很多初学者是从“调用大模型 API”入门的。写一个 prompt调用一下模型接口拿到返回结果这确实是 AI 应用开发的一部分但它只是最外层的一小部分。真正进入企业级 AI 大模型应用开发之后你会发现项目里大量时间花在下面这些事情上怎么让模型能调用外部工具比如查数据库、调接口、操作文件怎么管理多轮对话里的上下文而不是每次把全部历史都塞进 prompt怎么把一个复杂任务拆成多个步骤让模型逐步执行怎么处理模型返回格式不稳定的问题怎么在模型出错或者工具调用失败时让流程能自动恢复或者优雅退出。这些问题如果全部自己写工作量会非常大。Agent 框架就是来解决这些通用问题的。1.2 Agent 和传统程序的区别传统程序是“确定性的”代码怎么写结果就怎么执行每一步都是开发者提前定义好的。Agent 程序是“半确定性的”开发者定义目标和可用工具大模型在运行时决定调用哪个工具、按什么顺序执行、如何解读返回结果。开发者拥有的不是“一段固定流程”而是一个“可以让模型自主编排的空间”。这个区别非常重要因为它决定了你在开发 Agent 应用时核心工作不是写业务逻辑而是设计清楚两件事Agent 的“能力边界”它能用哪些工具Agent 的“行为边界”它在什么情况下做什么决策。1.3 为什么需要一套 Agent 框架如果没有框架你需要自己实现模型调用、工具注册、结果解析、上下文管理、错误重试、日志追踪。这些逻辑写一遍不难难的是写得稳定、可扩展、可观测。框架的价值在于它把这些通用能力固化下来让你把精力集中在业务本身。但框架也有一个麻烦如果封装太重你会失去对执行过程的控制力出了问题很难排查。DeepAgents 的出发点就是在这两者之间找平衡。2. DeepAgents 是什么2.1 一句话理解 DeepAgentsDeepAgents 是一套保持“骨架简单”的 Agent 框架。它的核心思路是Agent 的运行时骨架只保留最基本的执行循环而把工具定义、模型运行时、Agent 原语这些外围能力解耦出来让你可以按需组合。它既可以用 Python 库的方式直接调用也可以用 JSON 或 YAML 这样的 DSL 配置来声明整个 Agent。这句话里的关键不是“它有什么功能”而是“它不做什么”。很多 Agent 框架会预置大量复杂的概念比如节点图、状态机、编排引擎这些概念功能强但学习成本高。DeepAgents 希望反过来先把骨架做得足够简单让开发者对执行过程有完全的掌控。2.2 DeepAgents 强调的三个原则在官方设计理念中DeepAgents 特别强调对 LLM 的可见性、可控性和可扩展性。可见性VisibilityAgent 内部每一步在想什么、调用了什么工具、拿到了什么结果这些信息应该暴露给开发者而不是被封装在黑盒里。可控性Control开发者能干预 Agent 的执行过程而不是只能“发起一次对话然后等结果”。可扩展性Extensibility新增工具、更换模型、接入自定义逻辑都应该是低成本操作不需要改动框架核心。这三个原则恰恰是大型 Agent 应用工程化落地时需要关注的重点。2.3 和 LangChain、LangGraph、AutoGen 等框架的定位差异很多读者会拿 DeepAgents 和其他流行框架对比。这里先做一个大致的区分框架设计哲学适合场景学习成本LangChain面向链式调用提供了大量集成组件快速把 LLM 接入现有系统中LangGraph基于图结构编排 Agent状态管理能力强复杂多节点、需要精细控制的任务流偏高AutoGen多智能体对话协作强调多个 Agent 之间的交互多角色协作、自动化实验偏高DeepAgents骨架简单原语与运行时解耦强调可控性想深入理解 Agent 原理、需要定制执行的开发者低到中这里并不是说哪个框架绝对更好而是要看项目的实际约束。如果你希望快速使用一套成熟方案可以选 LangChain如果你要处理复杂的图状流程LangGraph 是合适的方向如果你想深入掌握 Agent 的执行机制并且希望框架尽量少限制你那 DeepAgents 就很值得研究。从学习路径的角度看我个人的建议是先用简单框架跑通一个最小 Demo理解 Agent 内部的工作循环再去看复杂框架思路会清晰很多。这也是这篇文章选择 DeepAgents 作为主线的原因。3. 环境准备与项目搭建3.1 运行环境要求DeepAgents 是一个 Python 库所以你需要先准备好 Python 环境。示例环境如下版本需要根据你的项目实际情况调整重点看配置思路Python 3.9 及以上 操作系统Windows / macOS / Linux 均可 包管理工具pip 或 poetry建议使用虚拟环境避免不同项目的依赖互相冲突python -m venv venv source venv/bin/activate # Linux / macOS venv\Scripts\activate # Windows3.2 安装 DeepAgents安装命令很简单pip install deepagents如果你需要使用 OpenAI 或 Anthropic 等模型运行时还需要安装对应的 SDKpip install openai anthropic这里要特别提醒DeepAgents 的 API 和依赖范围会随版本更新变化具体安装方式和可选依赖请以你安装版本的官方文档为准。本文中的代码示例采用的是当前主流的写法如果你用的版本较新个别参数可能会有调整。3.3 最小项目结构我们用一个实际项目来演示。先创建下面的目录结构deepagents-demo/ ├── .env ├── requirements.txt ├── agents/ │ └── researcher_agent.py ├── tools/ │ ├── __init__.py │ ├── search_tool.py │ └── calculator_tool.py ├── main.py └── README.md分工如下main.py程序入口负责加载环境变量、创建 Agent、进行对话agents/researcher_agent.py定义 Agent 的核心逻辑tools/存放各类工具函数.env存放 API Key 等敏感配置。这种拆分方式虽然现在看起来“重”但等 Agent 数量和工具数量变多后你会感谢自己当初做了目录分层。4. DeepAgents 核心原理拆解4.1 Agent 的核心工作循环无论什么 Agent 框架底层都有一个类似的核心循环。下面用文字描述一遍系统接收用户输入框架把系统提示词、对话历史、工具描述拼装成模型输入模型返回结果结果可能是文本回复也可能是工具调用请求如果是工具调用请求框架执行对应工具并把工具结果回传给模型模型根据工具结果继续推理直到生成最终回复最终回复返回给用户。这个循环就是 Agent 的“心脏”。DeepAgents 的整个设计都是为了让这个循环可控、可观测、可扩展。在 DeepAgents 中这个循环被抽象成 Agent 对象的核心执行方法当你调用 agent 的时候框架会循环执行“推理 - 行动 - 观察”的动作只不过这些细节被隐藏了起来。4.2 一个最简单的 DeepAgents Agent先来看最基础的用法。在项目根目录下创建main.py# 文件路径main.py import os from dotenv import load_dotenv from deepagents import Agent load_dotenv() agent Agent( nameassistant, instructions你是一个乐于助人的智能助手请用简洁的中文回答问题。, modelos.getenv(MODEL_NAME, gpt-4o), ) if __name__ __main__: response agent.run(介绍一下你自己) print(response)代码解释Agent是核心类负责整个 Agent 的执行循环instructions是系统提示词它决定了 Agent 的行为模式model指定使用的模型名称这里通过环境变量读取方便切换agent.run()是同步执行入口。在项目根目录创建.env文件OPENAI_API_KEY你的openai_api_key MODEL_NAMEgpt-4o如果你使用的是国内大模型或开源模型平台可以按服务商要求修改OPENAI_API_BASE等参数。由于各家模型服务商的接口兼容性不同这里只演示思路具体参数以平台文档为准。4.3 工具机制Agent 的“手脚”单个 Agent 只能“想”不能“做”。想让 Agent 真正发挥作用必须给它注册工具。DeepAgents 中的工具定义非常直观。你只需要写一个普通函数然后加上描述信息。创建tools/calculator_tool.py# 文件路径tools/calculator_tool.py def calculator(expression: str) - str: 计算数学表达式的结果。 参数: expression: 一个数学表达式字符串例如 1 2 * 3。 返回: 计算结果字符串。 # 注意这里使用 eval 仅用于演示真实场景建议使用更安全的表达式解析库 try: result eval(expression) return str(result) except Exception as e: return f计算失败{e}注意这个工具使用了eval生产环境千万不要直接这么写。后面“最佳实践”部分会介绍更安全的替代方案。创建tools/search_tool.py# 文件路径tools/search_tool.py def search_web(query: str) - str: 搜索互联网获取信息。当用户提问涉及实时信息、新闻或不确定的知识时使用。 参数: query: 搜索关键词或问题。 返回: 搜索结果摘要字符串。 # 这里档演示用途返回一个模拟结果 # 真实项目中可接入搜索 API 或内部知识库 return f模拟搜索结果关于“{query}”的最新信息请参考官方资料。DeepAgents 会自动从函数的docstring中提取工具描述并传给模型让模型知道“什么时候该调用哪个工具”。所以工具函数的 docstring 要写得足够清楚尤其是参数说明和适用场景。4.4 如何注册多个工具在实际项目中一个 Agent 往往包含多个工具。修改main.py# 文件路径main.py import os from dotenv import load_dotenv from deepagents import Agent from tools.calculator_tool import calculator from tools.search_tool import search_web load_dotenv() agent Agent( nameassistant, instructions( 你是一个智能助手。当用户需要计算时使用 calculator 工具 当用户询问实时信息或不确定的知识时使用 search_web 工具。 ), tools[calculator, search_web], modelos.getenv(MODEL_NAME, gpt-4o), ) if __name__ __main__: while True: user_input input(你) if user_input.strip().lower() in [exit, quit, 退出]: break response agent.run(user_input) print(f助手{response})这段代码做成了一个简单的交互式对话程序。运行时模型会自行判断什么时候调用计算器、什么时候调用搜索工具。4.5 深入理解 Agent 的多步推理这里有一个关键概念工具调用不一定是“一次就结束”的。举个例子用户问“帮我算一下 12345 乘以 6789然后再加 100结果是”模型可能会经历这样的内部过程调用calculator(12345 * 6789)得到中间结果用上一次结果调用calculator(83825205 100)拿到最终结果后生成自然语言回复。在这个过程中Agent 内部会执行多轮循环。DeepAgents 会记录每一轮的工具调用和结果这也是它强调“可见性”的体现你可以看到 Agent 每一步做了什么而不是只能拿到最后那句回答。如果你的 Agent 出现回答不准的情况首先应该检查的就是这个多步推理过程看看模型有没有调用错误的工具、传入错误的参数。很多“模型变笨了”的问题其实是工具调用链条断了。5. 实战搭建一个完整的 DeepAgents 应用为了让例子更贴近真实项目我们做一个“智能研究助手”。假设你是一个技术团队负责人希望有一个 Agent 能帮助团队做技术调研。它应该具备以下能力回答技术概念问题对简单数据进行计算分析根据用户给出的任务拆分调研步骤并且输出结构化报告。5.1 定义调研报告工具创建tools/report_tool.py# 文件路径tools/report_tool.py from datetime import datetime def write_report(topic: str, content: str) - str: 根据给定的主题和调研内容生成一份 Markdown 格式的技术调研报告。 参数: topic: 调研主题的简短标题。 content: 调研内容的正文应包含关键信息。 返回: 报告文件保存路径。 timestamp datetime.now().strftime(%Y%m%d_%H%M%S) filename freports/{topic}_{timestamp}.md report f# {topic}\n\n{content}\n with open(filename, w, encodingutf-8) as f: f.write(report) return filename5.2 创建 Agent 配置文件对于更复杂的 Agent框架支持用 DSL 来做声明式配置。这是一个示意性的 YAML 文件实际字段请以官方文档为准# 文件路径agent_config.yaml name: research_assistant instructions: | 你是一个技术调研助手。 你会根据用户的问题先拆解调研要点然后使用可用工具收集信息。 最终用 write_report 工具输出一份 Markdown 报告。 model: gpt-4o tools: - tools.calculator_tool.calculator - tools.search_tool.search_web - tools.report_tool.write_report通过外部配置文件来管理 Agent 的定义可以让运维和产品同学也参与 Agent 行为的调整而不需要改动代码。5.3 编写主程序创建research_main.py# 文件路径research_main.py import os from dotenv import load_dotenv from deepagents import Agent, load_config from tools.calculator_tool import calculator from tools.report_tool import write_report from tools.search_tool import search_web load_dotenv() # 方式一代码中直接定义 agent Agent( nameresearch_assistant, instructions( 你是一个技术调研助手。 如果用户需要查询知识使用 search_web 如果需要计算使用 calculator 最后根据调研结果使用 write_report 生成报告。 ), tools[calculator, search_web, write_report], modelos.getenv(MODEL_NAME, gpt-4o), ) def main(): # 确保 reports 目录存在 os.makedirs(reports, exist_okTrue) questions [ 请调研一下 RAG 技术的基本原理并计算 RAG 和 Fine-tuning 两个关键词的热度差异。, 请介绍 Agent 框架中 ReAct 模式的核心思想并生成一份报告。, ] for question in questions: print(f用户问题{question}) response agent.run(question) print(fAgent 回复{response}) print(- * 60) if __name__ __main__: main()5.4 运行与验证python research_main.py预期可以看到类似这样的输出节奏Agent 先调用 search_web 搜索“RAG 技术”相关知识调用 calculator 做简单热度差值计算如果模型认为有必要调用 write_report 生成 Markdown 文件最终回复用户报告已生成。这里有一个重要观察点模型召回工具的路径并不总是固定的。比如第二个问题模型可能直接调 write_report也可能先 search_web 再 write_report具体取决于 instructions 的约束力度和模型自身的判断。5.5 结果说明运行结束后查看reports/目录可以看到生成的报告文件reports/ └── RAG技术调研_20260101_120000.md打开文件里面是标准的 Markdown 格式。整个流程印证了 Agent 应用的核心逻辑模型负责决策工具负责执行框架负责调度。6. 常见问题与排查思路6.1 模型不调用工具这是初学者遇到最多的问题。问题现象常见原因解决思路模型总是直接回答完全不调用工具工具描述不清楚优化函数 docstring说明工具使用场景和参数格式模型调用了错误的工具instructions 冲突在 instructions 中明确工具优先级和调用时机调用工具后报错工具函数内部异常检查函数日志和参数格式添加异常捕获建议在开发阶段把所有工具调用日志打印出来确认模型每一步决策是否合理。6.2 上下文太长导致费用暴涨Agent 多轮工具调用时每一轮都要重新把历史记录传给模型token 消耗会成倍增长。解决方向精简系统提示词只保留必要的行为约束对工具返回的长文本做截断或摘要在框架里配置上下文窗口策略只保留最近 N 轮对话使用支持更便宜输入的模型处理中间步骤。6.3 API Key 泄露新手经常会把 API Key 直接写死在代码里然后提交到 Git 仓库。正确做法使用.env管理密钥将.env加入.gitignore使用团队密钥管理平台如 Vault、KMS管理生产环境的密钥一旦发现密钥泄露立即在服务商后台吊销并重建。6.4 Agent 运行不稳定同样的输入结果不同这是大模型应用开发的固有特性。模型有随机性工具调用结果也可能变化。建议合理设置 temperature 参数偏向稳定性场景建议设置为 0.2 或 0使用结构化输出约束模型返回格式增加重试机制对失败的工具调用进行有限次数重试针对关键流程编写自动化测试用例定期回归。7. 工程化最佳实践7.1 工具设计要“小而专”每个工具只做一件事并且要做清楚。工具描述里要写清楚“什么时候用”和“什么时候不用”因为模型会优先读取这些描述来做决策。反面例子def process_data(data_type: str, value: str) - str: ...这种“万能工具”会让模型无法判断该什么时候调用它。正面例子def get_user_balance(user_id: str) - str: 根据用户ID查询账户余额。仅当用户明确询问余额时使用。7.2 工具安全边界Agent 的工具本质上是给模型一个“执行权限”。权限越大风险越高。几个必须遵守的原则工具函数只接受必要参数不要设计成能执行任意代码涉及删除、更新、转账等高风险操作时必须加入人工确认环节生产环境所有工具调用都应该有审计日志不要把数据库连接串、私钥等敏感信息暴露给 Agent。回到前面用eval的例子生产环境建议改成# 文件路径tools/safe_calculator_tool.py import ast import operator # 仅允许白名单中的操作符 OPERATORS { ast.Add: operator.add, ast.Sub: operator.sub, ast.Mult: operator.mul, ast.Div: operator.truediv, } def safe_eval(expression: str) - str: 安全计算仅包含四则运算的表达式。 tree ast.parse(expression, modeeval) return str(_eval_node(tree.body)) def _eval_node(node): if isinstance(node, ast.Expression): return _eval_node(node.body) if isinstance(node, ast.Constant): return node.value if isinstance(node, ast.BinOp) and type(node.op) in OPERATORS: left _eval_node(node.left) right _eval_node(node.right) return OPERATORS[type(node.op)](left, right) raise ValueError(f不支持的表达式节点: {type(node)})这样既保留了计算能力又限制了操作范围。7.3 可观测性给 Agent 加上“体检报告”Agent 应用调试困难是因为它不是一个纯函数而是一个有状态的执行过程。建议你在框架日志的基础上额外记录以下内容# 文件路径utils/logger.py import json import logging from datetime import datetime logging.basicConfig(levellogging.INFO, format%(asctime)s [%(levelname)s] %(message)s) logger logging.getLogger(deepagents_demo) def log_tool_call(tool_name: str, args: dict, result: str): log_data { tool: tool_name, args: args, result_preview: str(result)[:200], time: datetime.now().isoformat(), } logger.info(json.dumps(log_data, ensure_asciiFalse))在生产环境可以把这些日志接入 ELK、Loki 或云日志服务后续做 OOM、耗时分析、成本分析都靠它。7.4 配置管理随着 Agent 数量变多建议统一管理配置模型名称、API Key、temperature 放在环境变量配置中心Agent 的行为定义instructions、tools 列表和代码分离便于非研发人员调整不同环境开发、测试、生产使用不同的配置项任何配置变更都要走版本管理。7.5 版本控制和测试不要因为“模型不写代码就可以不测试”。代码可能不会崩但 Agent 行为会漂移。建议你维护一组回归用例test_cases/ ├── basic_chat.json # 基础对话类测试 ├── tool_call_calc.json # 工具调用类测试 ├── multi_step_tool.json # 多步工具调用测试 └── security_policy.json # 安全合规类测试每个测试用例至少包含输入、期望行为调用哪个工具、返回什么格式、关键断言项。每次修改 Agent 配置后都跑一遍回归用例。8. 学习路线与进阶建议8.1 按顺序掌握的核心内容如果你想把 Agent 框架真正搞明白建议按下面的顺序学习大模型 API 基础消息格式、角色、上下文窗口、参数含义提示词工程写好 System Prompt学会约束输出格式工具调用机制理解 Function Calling 的请求与响应结构Agent 循环理解“推理 - 行动 - 观察”的多步执行过程框架源码阅读不要只停留在调用层读一遍框架的 Agent 核心循环源码工程化能力设计工具、加监控、控制成本、做权限管理。8.2 动手建议理论学习再多不如动手跑一个项目。建议从下面这个场景练手做一个“微信聊天记录分析助手”做一个“个人知识库问答机器人”做一个“定时调研行业竞品的自动化 Agent”。选一个和你日常工作相关的场景坚持把它做到能稳定运行两周你对 Agent 框架的理解会远超只看教程的同学。DeepAgents 这类轻量框架尤其适合用来“看清底层”因为它的骨架简单不会用复杂概念把你绕晕。当你理解了 Agent 的核心循环之后再去看 LangGraph、AutoGen 这类复杂框架你会发现自己的理解速度明显加快。如果你正打算进入 AI 大模型应用开发这个方向或者已经在这个方向里挣扎了一段时间希望这篇文章能帮你把框架底层的原理串起来。记得把文中的工具安全边界、日志记录和配置管理几个习惯带到项目里这比多写十个 Demo 都更值钱。