行业资讯
📅 2026/8/30 11:21:26
AI Agent工程化实战:LangGraph框架与工具调用应用开发指南
AI Agent 正在从“能聊天、会整理”的演示阶段进入“能干活、会上线”的工程化阶段。这个判断从 AGNTCon 这场专门面向 Agent 开发者的技术大会身上可以看得很清楚——今年九月它把举办地放在了阿姆斯特丹并从命名上直接指向 Agent 这一赛道。阵容公布这个节点通常意味着议题方向已经收敛也意味着整个行业开始认真把 Agent 当作一条独立的技术栈来对待而不是大模型的附属功能。很多开发者对 Agent 的认知还停留在“调大模型接口、写个 Prompt”的阶段。但真正进入工程化之后你会发现 Agent 开发要面对的问题和传统后端开发完全不在一个频道上状态怎么管理、工具权限怎么控制、上下文超了怎么办、工具调用出了错如何恢复、一轮任务烧掉多少 token、线上怎么观测。这些问题不是靠一个更好的模型就能自动解决的。这篇文章不打算替你搬运 AGNTCon 的每一条新闻而是借这条线索把 Agent 开发中最核心的概念、框架选型、最小可运行代码、常见坑和工程化建议一次讲清楚。读完你会明白一场以 Agent 命名的技术大会为什么值得关注以及一个真正能用的 Agent 应用到底应该怎么搭、怎么验证、怎么规避生产环境里的风险。1. AGNTCon 阿姆斯特丹一场大会背后的三个信号先说结论AGNTCon 出现在阿姆斯特丹本身就是 Agent 技术走向欧洲、走向工程化的一个信号。从公开信息看这场大会的时间定在九月地点放在荷兰阿姆斯特丹官方已经公布了第一波参会阵容。虽说我没有办法在这里给你列出一份完整的议程解读但以当前行业背景来判断这类大会的核心议题大概率会集中在四个方向Agent 应用框架、多智能体协作、评估与可观测性、生产环境落地实践。对于开发者来说这里面有三个信号比“谁来讲”更重要。第一个信号是工具链开始成熟。过去半年里LangGraph、AutoGen、CrewAI 这些框架迭代速度非常快Agent 不再只是“几个函数拼在一起”的玩具而是开始出现标准化的状态管理、持久化、断点续跑和人工审批机制。工具链成熟到什么程度决定了你能不能在真实业务里使用它而不是停留在 Demo 阶段。第二个信号是工程化成为主线。如果你看过早期的 Agent 演示会发现大多数 Demo 都在强调“模型能自动调用工具”。但到了今天大家讨论更多的反而是多轮对话状态怎么保存、Agent 的输出如何做校验、工具调用失败如何重试、敏感操作怎么加入人工确认。这些内容听起来不性感却决定了 Agent 能不能跑在真实的业务链路里。第三个信号是多智能体协作开始被严肃讨论。单个 Agent 的能力始终有限复杂任务往往需要拆分给多个角色比如一个 Agent 负责信息检索另一个负责内容生成还有一个负责质量校验。多智能体之间的通信协议、任务编排、冲突处理正在成为新的技术难点。所以如果你正在关注 Agent 开发我的建议是不要把 AGNTCon 当成一条新闻看完就过了而是把它当成一个检查点。对照大会议题看看自己目前掌握的技术栈是否还停留在“调模型接口”的层面。2. Agent 的核心概念模型调用之外的四个关键点什么是 Agent网上关于这个概念的讨论已经很多但真正写代码时你需要一个可操作的理解Agent 是一类以 LLM 为决策核心、能够自主调用外部工具并依据执行结果调整下一步动作的程序。它和普通 API 调用的关键区别在于“自主性”。普通程序里逻辑是开发者写死的Agent 程序里逻辑是模型根据任务现场“临时决策”的。这个变化带来很大的灵活性也带来了不小的失控风险。要构建一个能完成实际任务的 Agent你需要理解四个关键组件。第一个是 LLM 核心。模型负责理解用户目标、分解任务、判断下一步动作、综合结果生成最终答复。模型的能力直接决定 Agent 的上限尤其是工具调用Function Calling / Tool Calling能力。如果模型不支持稳定的工具调用Agent 的自动化就无从谈起。第二个是工具Tool。工具是 Agent 与外部世界交互的接口比如查询天气的 API、读写数据库的函数、发起 HTTP 请求的封装。没有工具Agent 只是一个聊天的模型有了工具它才能影响真实世界。工具定义本身需要写清楚名称、功能描述和参数结构模型才能正确决定何时调用、传什么参数。第三个是记忆Memory。记忆分短期和长期。短期记忆就是当前对话上下文里的一串消息它决定了模型能“看到”哪些信息长期记忆则是把需要持久化的数据保存到向量数据库或普通数据库供后续任务复用。工程化时你需要对记忆做裁剪、摘要和归档否则上下文会越来越长成本越来越高。第四个是规划与循环Planning and Loop。这是 Agent 最不容易理解的部分也是它和普通 Prompt 应用的本质区别。最经典的循环范式叫 ReAct即 Reasoning Acting。模型先推理当前状态再决定调用哪个工具拿到工具返回结果后继续推理直到信息足够才输出最终答案。整个循环可能只有一次也可能有十余次取决于任务的复杂度。如果用一张表来对比传统程序、Prompt 应用和 Agent 应用的差异会更清楚开发方式逻辑由谁决定能否操作外部系统状态管理可维护性传统程序开发者写死可以直接调用代码显式管理高但灵活度低Prompt 应用模型决定通常不能会话上下文中简单任务够用Agent 应用模型动态决策可以通过工具需要框架管理低需要较强工程能力看完这张表你就明白了Agent 开发不是“写 Prompt 的进阶版”而是把一部分控制流从代码移交给了模型。这意味着你的代码里要多做很多防御性设计。3. 主流 Agent 框架选型先看清抽象层级和适用边界选框架本质上是在选一种抽象方式。目前主流的 Agent 开发框架大的方向可以分成四类LangGraph 代表的生产级状态机方案AutoGen 代表的多智能体会话方案CrewAI 代表的角色化协作方案以及 Dify、Coze 这类可视化低代码平台。3.1 LangGraph状态机思维适合生产级流程LangGraph 把 Agent 应用建模成一张图有节点node、边edge和状态state。每个节点可以执行一段逻辑比如调用模型、调用工具、查询状态边则定义节点之间的流转条件。这种抽象方式的好处是流程可控、状态显式、便于插入人工审批和断点续跑。它适合什么场景需要精确控制流程、有复杂分支、必须处理长期运行任务、需要审计每一步操作的场景。缺点也明显对新手来说概念较多代码量比写一个普通脚本大不少。3.2 AutoGen多智能体会话适合研究原型AutoGen 的核心思路是把几个可以对话的角色组织在一起让它们通过“你来我往”的方式协作完成任务。比如一个 Agent 当程序员一个 Agent 当代码审查者。这种会话式模型很灵活适合快速验证想法。但它的代价是控制难度上升。多个 Agent 自主对话token 消耗难预估流程可预期性较弱。生产环境里你需要额外做很多防跑偏的机制所以我的判断是它更适合做研究探索和原型验证不太适合直接照搬进严苛的业务环境。3.3 CrewAI角色化团队协作上手容易CrewAI 的抽象非常直观你可以定义 Worker专家角色、Task任务和 Crew协作小组。它的学习曲线比较平缓适合用来模拟“团队协作”的场景比如让一个市场分析师 Agent 和一个内容编辑 Agent 共同完成一份行业报告。CrewAI 在原型阶段体验很好但真正上线时同样需要你自己补齐可观测性、任务失败重试和状态持久化这些基础设施。3.4 Dify / Coze可视化编排适合业务快速验证如果你不想写代码或者业务方希望尽快看到效果Dify 和 Coze 这类平台很有价值。你可以在界面上拖拽出工作流配置工具节点、知识库节点和模型节点然后一键发布成 API。这类平台的优点是交付速度快缺点也很直接深度定制能力受平台限制复杂状态逻辑难以表达数据出会有绑定风险。3.5 选型建议结合上面的分析按使用场景来选会比按框架知名度来选更实在如果你想把 Agent 集成到已有业务系统、需要精确控制流程、有权限审计需求优先考虑 LangGraph。如果你在写论文、做实验、探索多 Agent 交互机制AutoGen 值得一试。如果你只是做一个内部效率工具、Demo或者需要快速给业务方演示CrewAI 和低代码平台都可以。如果团队里以业务人员为主几乎不写代码低代码平台几乎是唯一选择。4. 环境准备跑通一个最小 Agent 需要什么在进入代码之前先把环境准备好。这里给你一个最小可运行的项目结构不依赖复杂的 Docker 或 K8s只在本地环境演示。agent-demo/ ├── .env ├── requirements.txt └── main.py建议使用 Python 3.10 以上版本。Python 3.10 引入了更完善的类型注解支持对后续代码可读性和工具定义都有帮助。虚拟环境可以按你习惯的方式创建推荐用uv速度更快。创建虚拟环境的命令如下uv venv agent-demo-venv source agent-demo-venv/bin/activate接下来创建requirements.txt内容如下langgraph0.2 langchain-openai0.2 langchain-core0.3 python-dotenv1.0这里没有把版本写死因为 Agent 框架迭代很快建议你在安装时留意当前最新版本。随后安装依赖pip install -r requirements.txt然后是.env文件用来保存模型服务的配置信息OPENAI_API_KEYsk-你的密钥 OPENAI_BASE_URLhttps://api.openai.com/v1 OPENAI_MODELgpt-4o-mini这里需要注意三点。第一如果你使用的是国内厂商提供的 OpenAI 兼容接口或者本地部署的 vLLM、Ollama 服务可以把OPENAI_BASE_URL改成对应地址只要接口协议兼容下面这段代码都可以跑通。第二OPENAI_API_KEY千万不要提交到 Git 仓库。项目里应该把.env加入.gitignore。第三不同的模型对工具调用的支持程度不一样。在使用非 OpenAI 模型前务必确认它是否支持 Function Calling / Tool Calling否则会出现模型根本不调用工具的问题。后面排查章节会专门讲这一点。5. 完整示例用 LangGraph 构建一个带工具调用的 Agent现在进入本文的核心部分用 LangGraph 写一个最小但完整的 Agent。这个 Agent 能自主决定调用两个工具——查询天气和获取当前时间——然后基于工具返回结果回答用户问题。5.1 定义工具工具是 Agent 的能力边界。在 LangChain 生态里用tool装饰器定义工具非常方便。工具函数本身要有清晰的 docstring因为模型会阅读这段描述来决定“什么时候该用这个工具”。# 文件路径agent-demo/tools.py from datetime import datetime from langchain_core.tools import tool tool def get_weather(city: str) - str: 查询指定城市的实时天气返回天气状况、温度和降水概率。 适用于用户询问某个城市的天气、穿衣建议、出行是否带雨具。 # 演示代码接入真实天气 API 后可替换为实际返回 if 阿姆斯特丹 in city: return 阿姆斯特丹多云16°C东南风 3 级降水概率 40%。 return f当前没有 {city} 的天气数据。 tool def get_current_time() - str: 获取当前时间返回年月日时分秒。 适用于用户询问“现在几点”“今天是几号”等问题。 return datetime.now().strftime(%Y-%m-%d %H:%M:%S)工具定义里的三要素是函数名、描述、参数。函数名要简短且语义明确描述要说明“什么时候使用”和“能返回什么”参数则要尽量少而清晰。模型在决策时非常依赖这三项信息写得不清楚模型就容易乱调用。5.2 组装模型与 Agent接下来是把模型、工具和 Agent 组装起来。create_react_agent是 LangGraph 提供的高层封装它会自动把 ReAct 循环搭好对新手非常友好。# 文件路径agent-demo/main.py import os from dotenv import load_dotenv from langchain_openai import ChatOpenAI from langgraph.prebuilt import create_react_agent from tools import get_current_time, get_weather load_dotenv() llm ChatOpenAI( modelos.getenv(OPENAI_MODEL, gpt-4o-mini), openai_api_keyos.getenv(OPENAI_API_KEY), openai_api_baseos.getenv(OPENAI_BASE_URL), temperature0, ) tools [get_weather, get_current_time] agent create_react_agent(llm, tools) def run(question: str) - None: result agent.invoke({messages: [(user, question)]}) for message in result[messages]: role getattr(message, type, str(type(message))) content getattr(message, content, str(message)) print(f[{role}] {content}) print(- * 60) if __name__ __main__: run(你好今天是几号顺便帮我查一下阿姆斯特丹的天气我应该穿什么衣服)这段代码的关键点有三个。第一个是ChatOpenAI的参数。openai_api_key和openai_api_base是 LangChain 生态里兼容性最好的参数名虽然某些新版本里已经开始推荐api_key和base_url但上面的写法在绝大多数版本里都能正常工作。第二个是create_react_agent的用法。第一个参数传模型实例第二个参数传工具列表。它内部已经帮你处理好了“模型输出工具调用意图 → 执行工具 → 把结果回传给模型 → 模型决定是否结束”的完整循环。第三个是结果解析。agent.invoke返回的result[messages]是一个消息列表里面包含用户消息、AI 消息、工具结果消息。把它们按顺序打印出来你就能直观地看到整个 Agent 的思考过程。5.3 运行入口运行之前记得先激活虚拟环境并确认.env文件在项目根目录下。然后执行python main.py如果一切正常你会看到类似下面的流程消息按顺序罗列[human] 你好今天是几号顺便帮我查一下阿姆斯特丹的天气我应该穿什么衣服 [ai] 我需要先获取当前时间再查询阿姆斯特丹的天气最后综合给出穿衣建议。 [ai] 我将同时调用两个工具来获取信息。 [tool] 当前没有 阿姆斯特丹 的天气数据。 [ai] 好的我这就查询阿姆斯特丹的天气。 [ai] 今天是 2025 年 6 月 8 日。阿姆斯特丹是多云16°C降水概率 40%建议穿轻薄外套并带上雨伞。上面这段是模拟输出具体内容会随模型版本和工具返回而变化。你真正需要观察的是消息列表里是否出现了tool类型的消息。只要出现了就说明模型真的产生了工具调用而不仅仅是在“假装”回答。6. 运行验证与链路检查代码跑通只是第一步。作为一个合格的开发流程你还应该主动验证“模型到底有没有正确调用工具”而不是只看一个漂亮的回答。验证可以分为三个层次。第一层确认模型本身支持工具调用。最直接的方式是用 curl 手动发一次请求传同样的工具描述看模型是否返回tool_calls。curl -X POST $OPENAI_BASE_URL/chat/completions \ -H Authorization: Bearer $OPENAI_API_KEY \ -H Content-Type: application/json \ -d { model: $OPENAI_MODEL, messages: [ {role: user, content: 阿姆斯特丹天气如何} ], tools: [ { type: function, function: { name: get_weather, description: 查询指定城市的天气, parameters: { type: object, properties: { city: {type: string} }, required: [city] } } } ], tool_choice: auto }如果响应里出现了tool_calls字段说明模型理解了工具协议。如果没有问题大概率在模型本身或工具描述上。第二层观察 LangGraph 的可观测性。建议在代码里加上最简单的结构化日志记录每一轮的类型、工具名、耗时和 token 消耗。不要只打印message.content因为模型调用工具时关键信息往往在tool_calls字段里而不是content字段。# 在 run 函数中增加调用信息输出 if hasattr(message, tool_calls) and message.tool_calls: for call in message.tool_calls: print(f[tool_call] name{call.get(name)}, args{call.get(args)})第三层验证工具返回是否正确传回模型。一个常见错误是工具返回了错误数据但模型把它当成正确数据继续回答。解决办法是工具内部做好数据校验如果查询失败明确返回“查询失败原因 xxx”而不是返回一个默认值误导模型。如果运行失败第一步不要急着改代码先检查三点.env配置是否加载成功、依赖是否完整安装、模型是否能通。把这三点排查完大部分问题都能解决。7. 常见问题与排查思路Agent 开发里踩坑几乎是必然的。下面把高频问题整理成一张排查表方便你对照处理。问题现象可能原因排查方式解决方案启动报 ModuleNotFoundError依赖未安装或未激活虚拟环境执行 pip list 检查包是否存在安装 requirements.txt 并确认当前虚拟环境认证失败 AuthenticationErrorAPI key 无效、未配置或格式错误打印 os.getenv 检查 .env 是否加载修正 .env 中的 OPENAI_API_KEY响应报 404 或模型不存在模型名称写错或该模型不可用使用 curl 直接请求该模型修改 OPENAI_MODEL 为有效模型名模型不调用任何工具模型不支持工具调用或工具描述不清晰curl 直接测试 tools 参数更换支持工具调用的模型精简工具描述工具被反复调用流程不结束工具返回值不明确模型认为任务未完成打印完整消息列表观察循环让工具返回更明确的结果或设置 recursion_limit上下文超过模型限制工具结果累积过多多轮对话太长检查 message 数量和 token 占用裁剪消息、摘要历史、精简工具输出请求被限流超出账号速率或并发限制观察 429 状态码增加重试退避控制并发避免死循环调用工具返回数据偏离预期工具实现有 bug或参数解析错误独立测试工具函数为工具补单元测试不依赖 Agent 测试这里面最容易被忽视的是工具返回值的结构化程度。工具返回的字符串如果语意含糊比如只写“0.2”模型会很难判断这个结果代表什么。建议工具返回时携带明确上下文例如“降水概率 20%”让模型不需要猜测。另外recursion_limit是一个值得提前了解的参数。如果 Agent 陷入死循环反复调用工具但不收敛你需要知道如何在框架层面“喊停”。在实际项目中建议一开始就把递归上限设置成 5 到 10 次而不是让它无限跑下去。8. Agent 工程化的最佳实践与安全边界最后这部分写给打算把 Agent 放进真实项目的团队。Demo 和生产的差距通常体现在下面几个方面。8.1 工具设计要克制职责要单一每一个工具都应该只做一件事并且把一件事做好。不要写一个“万能工具”接收各种参数、区分各种分支。工具描述要写清楚使用条件、返回值含义和可能的失败原因。模型在决策时本质上是靠工具描述来匹配任务描述越清晰决策越准。建议工具命名使用动词开头例如search_documents、send_email、create_ticket参数尽量少避免大量可选参数给模型增加理解负担。8.2 权限边界要清楚敏感操作必须人工确认Agent 能调用工具意味着它能影响外部系统。因此权限设计要遵循最小权限原则默认情况下只给查询类工具写操作、删除操作、转账操作等高风险动作必须走人工审批节点。LangGraph 提供了打断点interrupt的能力可以在工具执行前暂停流程等待人工确认后再继续。这种设计应该成为生产级 Agent 的标配而不是可选项。8.3 可观测性必须从第一天开始设计Agent 的决策路径不可完全预知所以日志比普通后端应用更重要。每一轮推理、每一次工具调用、每一个错误都应该有记录。推荐记录以下字段任务 ID、用户 ID、消息类型、调用的工具名、工具参数、工具返回摘要、耗时、token 消耗、最终答案。如果团队预算允许可以接入专门的 LLM 可观测性平台但至少要在本地日志里把这些信息记录下来。8.4 成本和性能需要主动控制Agent 的 token 消耗不像普通 API 调用那样直观一次多轮工具调用可能消耗几千甚至上万 token。控制成本的手段包括优先使用小模型完成简单任务对工具返回结果做截断设置单次任务最大 token 预算以及用语义缓存减少重复调用。8.5 测试策略要落在工具和模拟层面给 Agent 写测试不能只测最终答案。有效的测试至少分三层工具层单元测试、流程层集成测试、模型层回归测试。工具层测试最简单直接调用工具函数断言输出流程层测试用模拟工具替换真实网络请求验证编排逻辑模型层测试则准备一批固定问题观察输出质量变化。在生产环境变更时务必先在测试环境用相同配置全量跑一遍确认前后行为一致再切换。涉及生产数据库、用户数据或资金操作时更要严格执行备份、回滚和最小权限原则。9. 总结与后续学习路线回到开头那个判断Agent 正在进入工程化阶段。AGNTCon 这样的技术大会出现在阿姆斯特丹看起来只是一个行业事件但它背后反映的是开发者对 Agent 框架、多智能体协作、评估、安全边界这些工程问题的真实需求。如果你只是停留在“调一个模型 API”的层面很快就会在真实项目里遇到状态管理、工具权限、上下文爆炸这些绕不开的坎。本文从 Agent 的核心概念讲起对比了主流框架的选型思路然后给出了一个基于 LangGraph 的最小可运行 Agent并且覆盖了运行验证、常见排查手段和安全边界。下一步建议你按这样的顺序继续深入先照着上面的代码跑通一次 ReAct 循环理解工具调用消息的流转然后去掉create_react_agent的封装用 StateGraph 手动实现一次相同的流程这时你会真正理解 LangGraph 的节点和状态是怎么回事接着给 Agent 加上记忆持久化和人工审批节点最后再去研究多智能体协作和评测体系。一次技术大会能带来的最大价值不是你在会场上记住了多少新名词而是它帮你确认了“下一步该往哪里走”。Agent 开发的窗口期还很宽现在从最小示例开始把手弄脏比任何时候都划算。建议收藏这篇回头写代码时对照着用。