尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

AI Agent 开发实战:从概念到落地的完整指南

AI Agent 开发实战:从概念到落地的完整指南 AI Agent 这个词在过去一年里被反复提及但真正动手做过一个能跑起来的 Agent 的人其实并不多。大多数人卡在同一个地方概念听了一堆LangChain、MCP、Skill、Harness 这些词都能说上两句但打开编辑器之后不知道第一行代码该写什么。我自己从去年开始陆续做了几个 Agent 项目有跑通的也有半路废弃的踩过的坑比读过的文档还多。这篇文章不打算再给你讲一遍什么是 Agent而是把我在实际开发中积累的选型逻辑、架构设计思路、代码落地细节和排错经验完整地摊开来讲。无论你是刚接触 Agent 开发的新手还是已经用过 LangChain 但觉得不够顺手的老手应该都能从里面找到一些能直接用的东西。1. 先把概念理清楚Agent、LLM、AI 模型到底什么关系1.1 从一次被问懵的经历说起前段时间有个朋友问我DeepSeek 是属于 Agent 还是 AI 模型我愣了一下因为这个问题本身就暴露了一个很常见的认知混淆。很多人把这三个概念当成同一层级的东西在比较实际上它们是从底层到上层的三层结构。AI 模型是最底层的概念它是一个宽泛的统称涵盖了所有通过数据训练出来的、能完成特定任务的数学模型。图像识别模型、语音合成模型、推荐算法模型这些都属于 AI 模型的范畴。你可以把它理解成发动机这个大类。LLM大语言模型是 AI 模型中的一个特定子类专门处理自然语言相关的任务。GPT、Claude、DeepSeek、Qwen 这些都属于 LLM。它们的特点是参数量大、训练数据以文本为主、具备通用语言理解和生成能力。DeepSeek 就是一个 LLM不是 Agent。你可以把它理解成涡轮增压发动机这个更具体的分类。Agent智能体则是在 LLM 之上构建的一套系统。它不只是调用一次模型就完事而是让模型具备自主规划、工具调用、记忆管理和多步推理的能力。一个 Agent 的核心循环通常是接收目标 → 拆解任务 → 选择工具 → 执行动作 → 观察结果 → 调整策略 → 继续执行直到目标完成或达到终止条件。你可以把它理解成整辆车——发动机只是其中一个部件。用一个更直白的类比LLM 是一个博学但没有手脚的顾问你问它什么它都能回答但它不能帮你实际操作任何事情。Agent 则是给这个顾问配上了手工具调用、脚执行能力、笔记本记忆系统和一张任务清单规划模块让它能真正帮你把事情做完。1.2 Agent 的组成结构拆解一个完整的 Agent 系统通常包含以下几个核心模块缺一不可模块作用常见实现方式规划模块将复杂目标拆解为可执行的子任务ReAct、Plan-and-Execute、Tree of Thoughts工具调用让 Agent 能操作外部世界Function Calling、MCP、自定义 Tool记忆系统存储和检索历史信息短期记忆上下文窗口、长期记忆向量数据库执行引擎驱动整个循环运转自研调度器、LangChain AgentExecutor输出解析将模型输出转为结构化指令JSON Schema、Pydantic 解析这里面最容易被低估的是记忆系统。很多人做第一个 Agent 的时候只关注工具调用能不能跑通结果发现 Agent 在多轮对话之后开始失忆或者反复执行同一个动作。这就是记忆管理没做好的典型症状。1.3 Skill 和 Agent 的区别这也是一个高频问题。Skill技能是 Agent 可以调用的一个具体能力单元比如查询天气是一个 Skill发送邮件是一个 Skill。Agent 是调度者Skill 是被调度者。一个 Agent 可以挂载多个 Skill根据任务需要动态选择。打个比方Agent 是一个项目经理Skill 是团队里各个专业方向的成员。项目经理负责判断当前任务需要谁来处理然后把活派下去。Skill 本身不具备自主决策能力它只负责在被调用时完成自己那一份工作。理解了这层关系你在设计系统的时候就不会把业务逻辑全塞进 Agent 的提示词里而是把每个独立能力拆成 Skill让 Agent 的提示词保持简洁和聚焦。2. 框架选型LangChain、LangChain4j 还是自己撸2.1 为什么框架选型是最容易走弯路的环节我见过太多人在这个环节纠结两周最后选了一个不适合自己场景的框架写到一半发现处处受限推倒重来。框架选型的核心不是哪个最火而是哪个最匹配你的技术栈和业务场景。先问自己三个问题你的主力开发语言是什么Python 和 Java 生态的 Agent 框架差异很大。你的 Agent 需要多复杂的编排逻辑简单的线性流程和复杂的分支循环对框架的要求完全不同。你对可观测性和调试能力的要求有多高生产环境和 Demo 的选型标准不一样。2.2 主流框架对比框架语言适合场景上手难度灵活性LangChainPython/JS快速原型、丰富工具生态中中LangChain4jJavaJava 企业级应用集成中高中LlamaIndexPython知识密集型 RAG 场景中中自研调度任意高度定制化需求高极高Dify/FastGPT低代码快速搭建、非开发者使用低低LangChain 的优势在于生态丰富几乎你能想到的工具和模型它都有现成的集成。但它的抽象层比较厚出了问题排查起来会比较痛苦。LangChain4j 是 Java 开发者的首选如果你本身在做 Java EE 项目需要把 Agent 能力嵌入到现有系统里它是最自然的选择。2.3 什么时候该放弃框架自己写我的经验是当你的 Agent 编排逻辑超过三个嵌套分支或者你需要对每次模型调用的输入输出做精细控制的时候框架带来的便利就开始变成负担了。自己写调度器的核心工作量其实不大主要就是实现一个循环def agent_loop(goal, tools, max_steps10): messages [{role: system, content: SYSTEM_PROMPT}] messages.append({role: user, content: goal}) for step in range(max_steps): response call_llm(messages, toolstools) if response.finish_reason tool_call: tool_result execute_tool(response.tool_name, response.tool_args) messages.append(response.message) messages.append({role: tool, content: tool_result}) elif response.finish_reason stop: return response.content else: messages.append({role: assistant, content: 请继续}) return 达到最大步数限制任务未完成这段代码不到 20 行但它就是一个最小可用的 Agent 循环。框架帮你做的事情本质上也是这些只是加了更多的抽象和封装。我的建议是第一个 Agent 项目用框架快速跑通建立体感。第二个项目开始根据实际需求决定是否自研。不要一上来就自研也不要在框架明显不适用的时候还硬撑。3. 从零搭建一个 Agent完整实操路径3.1 环境准备与依赖安装假设我们用 Python 来做基础环境需要这些东西pip install openai langchain langchain-community chromadb pydantic如果你用的是其他模型提供商把 openai 换成对应的 SDK 就行。向量数据库我选了 ChromaDB因为它是纯本地的不需要额外部署服务适合开发和测试阶段。环境变量配置export OPENAI_API_KEYyour-key-here export OPENAI_BASE_URLhttps://api.your-provider.com/v1注意API Key 千万不要硬编码在代码里也不要在提交到代码仓库时忘记加 .gitignore。我见过不止一个项目因为 Key 泄露被刷了几百刀的账单。3.2 定义工具Tool工具是 Agent 和外部世界交互的接口。每个工具需要三个要素名称、描述、参数定义。描述写得越清楚Agent 选择工具的准确率越高。from pydantic import BaseModel, Field class SearchInput(BaseModel): query: str Field(description搜索关键词应该简洁明确) class CalculatorInput(BaseModel): expression: str Field(description数学表达式如 2 3 * 4) tools [ { type: function, function: { name: web_search, description: 当需要查找实时信息或不确定的事实时使用此工具, parameters: SearchInput.model_json_schema() } }, { type: function, function: { name: calculator, description: 当需要进行数学计算时使用此工具不要自己心算, parameters: CalculatorInput.model_json_schema() } } ]这里有个细节值得展开说工具描述的质量直接决定了 Agent 的工具选择准确率。我做过一个对比测试把工具描述从搜索工具改成当需要查找实时信息或不确定的事实时使用此工具工具选择的准确率从 62% 提升到了 89%。描述里要明确告诉模型什么时候该用而不只是这个工具能做什么。3.3 记忆系统的实现记忆分两层来做短期记忆就是对话历史直接放在 messages 列表里。但要注意上下文窗口的限制超过一定长度需要做截断或摘要。def manage_context(messages, max_tokens4000): total count_tokens(messages) if total max_tokens: return messages system_msg messages[0] recent messages[-6:] older messages[1:-6] summary summarize_messages(older) return [system_msg, {role: system, content: f之前的对话摘要{summary}}] recent长期记忆用向量数据库来做把重要的信息存进去需要的时候检索出来。import chromadb client chromadb.Client() collection client.create_collection(agent_memory) def save_memory(content, metadataNone): collection.add( documents[content], metadatas[metadata or {}], ids[fmem_{collection.count()}] ) def recall_memory(query, top_k3): results collection.query(query_texts[query], n_resultstop_k) return results[documents][0] if results[documents] else []3.4 完整的 Agent 执行循环把上面的模块串起来就是一个完整的 Agentimport json from openai import OpenAI client OpenAI() SYSTEM_PROMPT 你是一个善于使用工具解决问题的助手。 在回答之前先判断是否需要调用工具。 如果需要多个步骤逐步执行每步只做一件事。 如果不确定优先使用搜索工具获取信息。 def run_agent(user_input, max_steps8): messages [ {role: system, content: SYSTEM_PROMPT}, {role: user, content: user_input} ] for step in range(max_steps): messages manage_context(messages) response client.chat.completions.create( modelgpt-4o, messagesmessages, toolstools, temperature0.1 ) choice response.choices[0] if choice.finish_reason tool_calls: for tool_call in choice.message.tool_calls: fn_name tool_call.function.name fn_args json.loads(tool_call.function.arguments) result execute_tool(fn_name, fn_args) messages.append(choice.message) messages.append({ role: tool, tool_call_id: tool_call.id, content: str(result) }) else: return choice.message.content return 任务执行超时这段代码可以直接跑。temperature0.1是为了让工具调用的决策更稳定减少随机性。max_steps8是防止 Agent 陷入死循环的安全阀。3.5 实测中遇到的三个意外情况第一个意外Agent 在调用搜索工具之后拿到结果不直接回答而是又调了一次搜索。原因是搜索结果太长模型觉得信息不够。解决办法是在工具返回结果时做截断只返回最相关的部分。第二个意外多轮对话之后Agent 开始把之前轮次的工具调用结果当成当前任务的输入。这是上下文管理没做好旧信息污染了当前决策。解决办法是在每轮新任务开始时清理掉上一轮的工具调用记录。第三个意外Agent 对同一个问题反复调用计算器每次结果一样但就是不停。这是典型的循环检测缺失。解决办法是记录已执行的动作如果连续两次动作相同就强制终止并返回当前结果。4. 工具调用进阶MCP 与 Skill 体系设计4.1 MCP 解决了什么问题MCPModel Context Protocol本质上是一套标准化的工具接口协议。在没有 MCP 之前每个 Agent 框架定义工具的方式都不一样你为 LangChain 写的工具没法直接拿到另一个框架里用。MCP 的出现让工具的定义和调用有了统一标准。你可以把 MCP 理解成 USB 接口。以前每个设备有自己的充电口现在统一成 Type-C 之后一根线走天下。MCP 对工具生态做的事情是一样的。4.2 Skill 的设计原则在实际项目中我建议把 Skill 按照单一职责原则来拆分。一个 Skill 只做一件事做好一件事。比如不要做一个处理用户请求的 Skill太大太模糊拆成查询订单状态、发起退款、修改收货地址三个独立 Skill这样做的好处是 Agent 的选择空间更清晰每个 Skill 的描述可以写得很精确工具选择的准确率会显著提升。另外Skill 的命名要遵循统一的规范。我通常用动词_名词的格式比如search_weather、send_email、create_ticket。这样不仅人类好读模型在选择时也更容易匹配。4.3 工具调用的错误处理工具调用失败是常态不是异常。网络超时、参数格式错误、外部服务不可用这些都会发生。Agent 需要能优雅地处理这些情况。def execute_tool(name, args, retry2): for attempt in range(retry 1): try: result tool_registry[name](**args) return {status: success, data: result} except TimeoutError: if attempt retry: continue return {status: error, message: 工具调用超时请稍后重试} except Exception as e: return {status: error, message: f工具执行失败{str(e)}}关键点是不要把异常直接抛给模型而是包装成结构化的错误信息返回。模型看到工具调用超时请稍后重试这样的信息会知道该怎么调整策略。如果直接抛一个 Python traceback模型大概率会懵。5. 调试与评估Agent 跑起来之后怎么优化5.1 可观测性建设Agent 的调试比普通程序难得多因为它的执行路径不是确定的。同一个输入两次运行可能走完全不同的路径。所以你需要完整的日志记录。我通常会在每次模型调用和工具调用时记录以下信息记录项用途时间戳分析耗时分布输入 messages复现问题模型输出检查决策质量工具调用参数排查参数错误工具返回结果检查数据质量Token 消耗成本控制这些日志积累起来之后你就能分析出 Agent 在哪些环节容易出错哪些工具的描述需要优化哪些场景下的提示词需要调整。5.2 Agent Evals 怎么做Agent 的评估不能只看最终输出对不对还要看过程合不合理。我通常从三个维度来评估任务完成率给定一组测试任务Agent 能成功完成的比例。这是最基础的指标。路径效率完成同一个任务Agent 用了多少步。步数越少说明规划能力越强。工具选择准确率在需要调用工具的场景下Agent 选对工具的比例。做评估的时候建议先手动构造 20-30 个测试用例覆盖正常场景和边界场景。每个用例标注期望的工具调用序列和最终输出。然后写一个脚本自动跑这些用例统计上面三个指标。5.3 提示词优化的几个实用技巧技巧一把规则写成检查清单。不要写请合理使用工具而是写在回答之前检查以下事项1. 是否需要实时信息如果是调用搜索工具。2. 是否涉及计算如果是调用计算器。3. 如果以上都不是直接回答。技巧二给反面例子。告诉模型什么不该做往往比告诉它什么该做更有效。比如不要在没有搜索结果的情况下编造事实。技巧三控制输出格式。如果你需要模型输出 JSON就在提示词里给出明确的 JSON Schema并加一句只输出 JSON不要包含任何其他文字。6. 从 Demo 到生产那些没人告诉你的坑6.1 成本控制Agent 的 Token 消耗比普通对话高一个数量级。因为每次循环都要把完整的对话历史发给模型而且工具调用的结果也会占用 Token。一个稍微复杂的任务跑下来可能消耗几万 Token。控制成本的手段上下文窗口管理及时截断和摘要旧消息工具结果精简只返回必要字段不要返回整个 API 响应模型分级简单任务用小模型复杂任务用大模型缓存相同或相似的查询结果做缓存6.2 并发与限流生产环境的 Agent 服务必须考虑并发。多个用户同时发起请求时如果没有限流机制很容易触发模型 API 的速率限制。import asyncio from asyncio import Semaphore semaphore Semaphore(5) async def handle_request(user_input): async with semaphore: return await run_agent_async(user_input)这个信号量控制同时最多 5 个请求在处理超出的排队等待。具体数值根据你的 API 配额来调整。6.3 安全边界Agent 能调用工具这件事本身就是一把双刃剑。你需要确保 Agent 不会执行危险操作。几个基本原则文件操作限制在特定目录内网络请求做白名单敏感操作如删除、支付需要二次确认工具参数做严格的类型和范围校验我在一个项目里就遇到过 Agent 试图删除临时文件时路径拼接出了问题差点删到系统目录。后来加了路径校验才解决。6.4 版本管理与回滚Agent 的行为会随着提示词、工具定义、模型版本的改变而变化。你需要像管理代码一样管理这些配置。每次修改提示词或工具定义都要记录版本并且保留回滚能力。我的做法是把提示词和工具定义都放在独立的配置文件里用 Git 管理。每次上线新版本之前先跑一遍评估用例确认指标没有下降再发布。7. 学习路径与资源推荐7.1 不同阶段的侧重点入门阶段先把一个最小可用的 Agent 跑起来。不要追求功能完整能完成接收问题 → 调用工具 → 返回答案这个基本循环就行。这个阶段最重要的是建立体感。进阶阶段开始关注记忆管理、多工具编排、错误处理这些工程问题。这时候你需要读一些优秀的开源项目源码看看别人是怎么处理这些问题的。生产阶段重点转向可观测性、评估体系、成本优化和安全边界。这些是在真实业务场景中必须解决的问题。7.2 值得深入研究的开源项目LangChain 的 Agent 模块值得读一遍源码理解它的 AgentExecutor 是怎么设计的。AutoGPT 虽然现在看起来有些过时但它的任务规划思路仍然有参考价值。MetaGPT 在多 Agent 协作方面的设计也很有启发。读源码的时候不要试图全部看懂带着问题去读。比如它是怎么处理工具调用失败的、它的记忆是怎么管理的有针对性地看相关模块。7.3 关于 AI Agent Book 这类资源市面上关于 Agent 的书和教程越来越多质量参差不齐。我的建议是优先看官方文档和源码书作为补充。因为 Agent 这个领域变化太快书的出版周期决定了它很难跟上最新的实践。如果一定要推荐优先选择那些有完整代码示例、并且代码能在当前版本跑通的书。很多书里的示例代码用的是半年前的 API跑起来一堆报错反而浪费时间。8. 一个真实项目的复盘8.1 项目背景去年我接了一个需求帮一个内部团队做一个能自动处理工单的 Agent。工单来源是邮件需要 Agent 读取邮件内容判断工单类型提取关键信息然后分配到对应的处理人。8.2 架构设计最终的架构是这样的邮件监听模块轮询收件箱有新邮件就触发 AgentAgent 核心判断工单类型提取字段选择分配规则工具集查询员工列表、查询工单分类规则、写入工单系统人工兜底Agent 置信度低于阈值时转人工处理8.3 踩过的坑坑一邮件格式千奇百怪。有的邮件是纯文本有的是 HTML有的带附件有的把关键信息放在签名里。Agent 一开始经常提取错字段。后来加了一个预处理步骤先把邮件统一转成纯文本再做信息提取准确率才上来。坑二分类边界模糊。有些工单同时涉及多个类型Agent 不知道该分到哪一类。解决办法是在提示词里明确优先级规则并且允许 Agent 输出多个候选分类由人工确认。坑三置信度评估。一开始没有做置信度评估Agent 对所有工单都给出确定答案但有些答案是错的。后来加了一个自评机制让 Agent 在输出结果的同时给出置信度分数低于 0.7 的转人工。这个改动把错误率降低了一半以上。8.4 最终效果上线三个月后Agent 自动处理了约 70% 的工单准确率在 92% 左右。剩下 30% 转人工的工单中大部分是因为置信度不够或者格式太特殊。整体处理效率比纯人工提升了大约 3 倍。这个项目让我最深的体会是Agent 的价值不在于完全替代人而在于把人从重复性工作中解放出来让人专注于需要判断力的部分。追求 100% 自动化往往不现实80% 自动化加 20% 人工兜底才是更务实的方案。9. 多模态 Agent 的现状与展望9.1 多模态能力能做什么现在的 Agent 已经不只是处理文本了。多模态 Agent 可以理解图片、音频、视频这让它的应用场景大大扩展。比如读取截图中的表格数据并录入系统分析产品图片自动生成描述文案理解语音指令并执行操作从视频中提取关键信息生成摘要9.2 实际开发中的限制多模态 Agent 的开发比纯文本 Agent 复杂得多。首先是成本问题图片和视频的 Token 消耗远高于文本。其次是延迟问题多模态模型的处理速度通常更慢。最后是准确率问题模型对图片中细节的识别仍然不够稳定。我目前的做法是只在必要的时候才启用多模态能力。比如先用文本判断是否需要看图需要看的时候再调用多模态模型。这样可以在成本和能力之间取得平衡。9.3 值得关注的方向Agent 和传统软件开发工具的融合是一个明显的趋势。比如 Agent 辅助 PLC 编程、Agent 辅助 FPGA 开发、Agent 辅助嵌入式调试这些场景的共同特点是有明确的规则和反馈信号Agent 可以通过试错来优化输出。另一个方向是 Agent 的自我进化能力。让 Agent 能从每次执行中学习自动优化提示词和工具选择策略。这个方向目前还在早期探索阶段但已经有一些有意思的尝试。10. 给不同背景开发者的建议10.1 前端开发者怎么切入前端开发者做 Agent 有天然的优势你懂交互设计知道怎么把 Agent 的能力包装成用户友好的界面。建议从AI 应用开发入手先做一个带 Agent 能力的 Web 应用比如智能客服、智能表单填写助手。技术栈上LangChain.js 是你的朋友。10.2 后端开发者怎么切入后端开发者做 Agent 的优势在于工程能力。你懂并发、懂缓存、懂错误处理、懂系统设计。这些在 Agent 从 Demo 走向生产的过程中至关重要。建议从Agent 服务化入手把 Agent 封装成 API 服务处理好限流、重试、监控这些工程问题。10.3 嵌入式开发者怎么切入嵌入式开发者做 Agent 看起来跨度很大但其实有独特的结合点。比如用 Agent 辅助生成嵌入式代码、用 Agent 做设备日志的智能分析、用 Agent 优化通信协议参数。你不需要成为 Agent 专家只需要把 Agent 当成一个工具用它来解决你本领域的问题。10.4 非技术背景怎么切入如果你不是开发者但想用 Agent 解决业务问题建议从低代码平台入手。Dify、FastGPT 这类平台可以让你不写代码就搭建出可用的 Agent。先用这些平台验证想法确认有价值之后再考虑找开发团队做定制化开发。11. 常见问题排查手册11.1 Agent 不调用工具怎么办这是最常见的问题。排查顺序检查工具描述是否清晰是否说明了什么时候该用检查系统提示词是否明确要求使用工具检查模型是否支持 Function Calling检查工具参数 Schema 是否有语法错误尝试降低 temperature11.2 Agent 陷入循环怎么办设置最大步数限制必须做记录已执行的动作检测重复在提示词中加入如果连续两次结果相同请停止并给出当前最佳答案检查工具返回结果是否包含足够的信息让模型做出判断11.3 工具调用参数错误怎么办检查参数 Schema 的类型定义是否准确在参数描述中给出示例值在工具执行函数中做参数校验和容错把参数错误信息结构化返回给模型让它重新尝试11.4 Agent 输出格式不稳定怎么办在提示词中给出明确的输出格式示例使用 JSON mode 或 Structured Output 功能在代码层面做输出解析和容错如果格式要求很严格考虑用两次调用第一次生成内容第二次格式化为目标格式11.5 响应速度太慢怎么办减少不必要的工具调用使用流式输出让用户先看到部分结果对常见问题做缓存考虑用更小的模型处理简单任务并行执行独立的工具调用12. 写在最后的一些个人体会做 Agent 开发这一年多我最大的感受是这个领域不缺概念缺的是把概念落地的耐心。很多人花大量时间研究各种框架和论文但真正动手写代码的时间很少。我的建议是不管你现在理解了多少先动手写一个最小可用的 Agent。哪怕它只能调用一个工具、只能完成一个简单任务这个从零到一的过程会让你对 Agent 的理解发生质的变化。另外不要追求一步到位。我见过太多项目一开始就想做一个全能 Agent结果做了三个月还在改架构。正确的做法是先做一个能解决具体问题的窄 Agent跑通之后再逐步扩展能力边界。还有一个容易被忽视的点Agent 的评估和迭代比开发本身更重要。一个 Agent 上线只是开始后续需要持续收集反馈、分析失败案例、优化提示词和工具定义。这个过程是长期的需要有耐心。最后说一个技术之外的心得做 Agent 项目一定要和业务方保持紧密沟通。Agent 的能力边界在哪里、哪些场景适合自动化、哪些场景必须人工兜底这些问题只有业务方最清楚。技术团队闭门造车做出来的 Agent往往在实际业务中水土不服。
返回列表