公司动态

从LLM到智能体:构建具备工具调用能力的AI助手全流程解析

📅 2026/8/14 18:52:56
从LLM到智能体:构建具备工具调用能力的AI助手全流程解析
1. 从“大模型”到“智能体”一场认知的升维最近和不少同行、朋友聊天发现一个挺有意思的现象大家嘴里都挂着“LLM”、“Agent”、“Skill”这些词但真要问起来“它们到底啥关系怎么用”很多人又有点含糊。这种感觉就像手里拿着一堆新工具却不知道它们分别该拧哪颗螺丝更别说组装成一台能跑的机器了。这种“名词焦虑”其实挺普遍的尤其是在技术快速迭代的今天。今天我们不谈那些高深莫测的理论就从最朴素的“解决问题”的角度来捋一捋从LLM到Agent再到Skill这条技术链。你可以把它看作一个“能力封装”和“任务分解”的演进过程。LLM是那个无所不知但有点“手无缚鸡之力”的超级大脑Agent是给这个大脑配上了感知、规划和执行的手脚而Skill则是让这些手脚掌握的具体“手艺”或“工具”。理解了这个关系你就能明白为什么现在做AI应用光调API已经不够了你得学会“组装”和“调度”。这篇文章就是帮你把这一串名词背后的逻辑链条和实操价值讲清楚。无论你是刚入行的开发者还是想用AI赋能业务的产品经理或者是被各种新概念搞得头晕的爱好者都能从这里获得一张清晰的“地图”。我们会从最基础的LLM能力讲起一步步拆解Agent是如何工作的最后落到最接地气的Skill设计与实现上。目标就一个让你不仅能听懂这些词更能知道怎么用它们去解决真实世界的问题。2. LLM能力的基石与它的“阿喀琉斯之踵”要理解后续的一切我们必须先回到起点大语言模型。你可以把今天的LLM想象成一个在人类全部文本知识海洋里浸泡过的“通才”。它通过海量数据的预训练学会了语言的统计规律、世界的常识、甚至复杂的逻辑推理模式。当你向它提问时它并不是在“检索”答案而是在根据上文以极高的概率“生成”最合理的下文。这种能力带来了革命性的变化。以前我们需要为“天气查询”写一套规则为“情感分析”训练一个专用模型。现在我们只需要用自然语言向LLM描述任务它往往就能给出不错的结果。这就是所谓的“泛化能力”或“零样本/少样本学习能力”。它让AI应用的开发门槛前所未有地降低了。然而这个“通才”有几个致命的弱点我称之为“阿喀琉斯之踵”2.1 幻觉与事实性错误这是LLM最被诟病的一点。因为它本质是“生成”而非“检索”所以在缺乏确切知识或上下文模糊时它会自信地编造出看似合理实则错误的内容。比如它可能会生成一个不存在的学术论文引用或者搞错一个历史事件的日期。在需要高可靠性的场景如法律、医疗、金融这是不可接受的。2.2 缺乏实时性与行动能力LLM的知识截止于其训练数据的时间点。它不知道今天股市涨跌不知道你邮箱里刚收到的新邮件更不可能帮你点击网页上的一个按钮。它是一个静态的、封闭的知识库无法感知和影响外部世界。2.3 复杂任务规划的无力感当你让LLM“帮我策划一个三天的北京旅游行程”时它可能能生成一个看起来不错的文本列表。但如果你接着问“请根据这个行程帮我预订第一天晚上王府井附近的酒店并查询故宫门票的购买政策”它就无能为力了。它无法将“策划行程”这个高层目标分解成“查询酒店信息”、“比价”、“调用预订API”、“阅读官网政策”等一系列可执行的子步骤更无法按顺序执行这些步骤。2.4 上下文长度的限制与成本虽然上下文窗口在不断增大但处理超长文本如整本书、大量历史对话依然面临性能、成本和注意力分散的挑战。它难以在超长上下文中精准地维持对核心信息的关注和连贯的逻辑。正是这些弱点催生了我们对“智能体”的需求。我们需要的不是一个只会聊天的百科全书而是一个能真正为我们办事的“智能助手”。LLM提供了强大的认知内核但它需要被“封装”进一个更大的、具备感知和行动能力的框架里。3. Agent为LLM装上“手脚”与“小脑”如果说LLM是大脑那么Agent智能体就是为这个大脑配上了一整套身体系统。一个典型的Agent架构可以类比为一个拥有“感知-思考-行动”循环的自主系统。它的核心目标是接收一个高层目标比如“帮我总结上周所有项目邮件的核心内容并生成报告”然后自主地规划、执行一系列动作最终达成目标。3.1 Agent的核心组件与工作流一个功能完整的Agent通常包含以下几个关键组件它们共同构成了一个循环规划模块这是Agent的“思考”核心通常由LLM驱动。当接收到一个复杂任务时规划模块负责将其分解成一系列清晰的、可执行的子任务。例如对于“总结邮件并报告”这个任务规划可能输出① 登录邮箱② 过滤出过去7天、来自项目组的邮件③ 逐封提取核心内容④ 将内容汇总成结构化报告⑤ 将报告保存为Word文档。工具调用模块这是Agent的“手”。它负责将规划模块输出的抽象指令如“登录邮箱”映射到具体的、可执行的工具或API上。这些工具就是Skill我们下一章会细讲比如“使用OAuth2协议调用Gmail API”、“调用文件读写接口”。LLM在这里的作用是根据上下文决定在何时、调用何种工具、传入什么参数。记忆模块这是Agent的“经验库”。它分为短期记忆记录当前任务循环中的上下文、工具执行结果和长期记忆存储跨会话的用户偏好、学到的经验。记忆让Agent能进行多轮交互记住之前做了什么、结果如何从而做出更连贯的决策。例如如果上次调用某个API失败了记忆会提醒它这次尝试另一种方法。执行与观察模块这是Agent的“感知-行动”循环。它调用工具获取执行结果成功、失败、返回数据并将这个“观察”反馈给规划模块。规划模块根据观察决定下一步是继续执行下一个子任务还是需要调整计划比如重试、或选择备用方案。这个“规划 - 选择工具 - 执行 - 观察 - 再规划”的循环就是Agent自主工作的核心逻辑。它让LLM从一个文本生成器升级成了一个能够处理复杂、动态任务的决策中枢。3.2 主流Agent框架的实践选择理解了原理我们来看看市面上如何实现它。你不会从头造轮子通常会选择成熟的框架LangChain / LangGraph这可能是目前最流行的“组装”框架。它不提供一个开箱即用的完整Agent而是提供了极其丰富的“积木块”。你可以用它的Tools定义Skill用Chains组合简单流程用Agents封装规划逻辑用LangGraph来构建有状态、带循环的复杂工作流。它的优点是灵活、生态强大缺点是学习曲线较陡需要你自己设计很多架构细节。Dify的Workflow可视化功能其底层思想就与LangGraph构建状态图非常相似。Dify / Coze 等低代码平台这类平台将Agent的组件工具、LLM、记忆、提示词进行了可视化封装。你通过拖拽节点、连线的方式就能构建一个应用。例如在Dify中你可以轻松创建一个Workflow先让LLM判断用户意图然后根据意图选择调用“天气查询工具”还是“邮件搜索工具”最后将结果格式化输出。它的优点是上手极快适合快速原型验证和不太复杂的场景缺点是在处理非常复杂、定制化程度高的逻辑时可能不如代码灵活。专有Agent框架例如AutoGPT、BabyAGI等它们提供了一种更偏向“自主探索”的Agent范式设定一个目标后Agent会自己上网搜索、写代码、执行试图完成目标。这类框架更实验性在可控的生产环境中应用较少。选择哪个框架取决于你的团队背景和任务复杂度。对于需要深度定制和复杂逻辑的团队LangChain是瑞士军刀对于追求效率和快速上线的业务团队Dify这类平台是更优选择。4. Skill让Agent“有一技之长”的原子能力现在我们来到了最接地气、也是最能直接产生价值的一层Skill。如果说Agent是一个“人”那么Skill就是这个人掌握的“技能”或可以使用的“工具”。它是Agent与外部世界交互的唯一途径也是将LLM的认知能力转化为实际生产力的关键。4.1 Skill的本质标准化接口与描述一个Skill本质上是一个可以被Agent具体是其中的规划/工具调用模块理解和调用的功能单元。它通常包含两个核心部分实现代码就是实实在在的功能。可以是一段查询数据库的SQL操作一个调用第三方API的HTTP请求一个操作本地文件的函数甚至是一段复杂的业务逻辑代码。描述信息这是让LLM能“看懂”并“决定使用”这个Skill的关键。通常以结构化格式如JSON Schema描述包括name: 技能名称如get_weather。description: 自然语言描述清晰说明这个技能是做什么的。这里的描述质量至关重要直接决定了LLM能否正确调用它。例如“获取城市天气”就比“天气功能”好得多。parameters: 参数定义包括名称、类型、描述、是否必填等。例如city: string, 城市名称如‘北京’。当LLM在规划时它会阅读所有可用Skill的描述然后判断“要完成当前步骤我需要使用哪个Skill需要传入什么参数”这个过程类似于函数调用但是由LLM根据自然语言上下文动态决定的。4.2 Skill的设计模式与实战案例设计一个好的Skill远不止写个函数那么简单。下面通过几个案例来说明不同模式案例一信息查询Skill如天气、股票# 伪代码示例 def get_weather(city: str) - str: # 调用第三方天气API如和风天气、OpenWeatherMap api_url fhttps://api.weather.com/v3/...?city{city} response requests.get(api_url) data response.json() # 将API返回的JSON数据转换成一句自然语言描述 return f{city}今天天气{data[condition]}气温{data[temp_min]}到{data[temp_max]}摄氏度。设计要点这类Skill的关键在于结果格式化。外部API返回的往往是结构化数据JSON你需要将其转化为LLM或用户易于理解的自然语言句子方便后续的整合与展示。案例二操作执行Skill如发送邮件、创建日历def send_email(to: str, subject: str, body: str) - str: # 使用SMTP库或邮件服务商API如SendGrid, AWS SES # 进行身份验证、构造邮件、发送 # ... if success: return f邮件已成功发送至{to}。 else: return f邮件发送失败错误原因{error_msg}。设计要点这类Skill要特别注重错误处理与状态反馈。执行可能失败网络问题、权限不足Skill必须将明确的结果成功/失败原因返回给AgentAgent才能据此决定下一步如重试或通知用户。案例三复杂业务Skill如生成周报这通常不是一个单一操作而是一个微型的“子工作流”。例如“生成周报”Skill内部可能依次调用① 查询JIRA/禅道API获取本周任务列表② 查询Git日志获取代码提交③ 查询会议日历获取会议纪要④ 使用LLM总结以上信息生成报告草稿⑤ 调用文件保存Skill存储报告。设计要点这类Skill体现了“分层”思想。对外它仍然是一个简单的generate_weekly_report(date: str)接口。对内它封装了复杂性。这有助于保持顶层Agent规划的简洁。4.3 Skill描述的“艺术”与常见坑让LLM准确调用Skill七分靠描述。以下是几个核心技巧和避坑指南描述要具体、无歧义差search搜什么怎么搜好search_web使用搜索引擎进行关键词搜索并返回最相关的几条摘要。适用于查找实时信息、事实核查。更好在描述中明确边界。例如get_current_stock_price的描述可以加上“仅支持查询美股的实时股价股票代码需为英文大写如AAPL、GOOGL。”参数描述要示例化在参数描述里直接给出例子能极大降低LLM的理解错误。例如city: string, 城市的中文名称例如‘北京市’、‘上海市’。处理模糊的用户输入 用户可能说“看看明天天气”。这里隐含了“城市”参数。有两种处理方式方式一推荐在Agent的规划层让LLM主动向用户追问“请问您想查询哪个城市的天气”方式二在Skill层设计默认值或从上下文记忆中推断例如默认查询用户所在城市。但这需要更复杂的记忆管理。Skill的编排与冲突 当Skill数量增多时可能会出现功能重叠。例如既有search_web又有search_internal_wiki。这时LLM可能困惑该用哪个。解决方案是在描述中更精确地界定范围“内部知识库” vs “公开互联网”。设计一个“路由”Skill或规划逻辑先判断问题类型再分派到具体的搜索Skill。5. 从架构到实战构建你的第一个AI助手理论说了这么多我们动手搭一个最简单的、但能完整跑通“LLM - Agent - Skill”链条的智能助手。这个助手的目标是回答需要实时信息的混合问题比如“特斯拉最新的股价是多少然后用中文总结一下它最近一周的新闻。”我们将使用LangChain和OpenAI API来构建。这里假设你已有基本的Python环境。5.1 环境准备与依赖安装首先创建一个新的项目目录并安装核心库。我们选择LangChain是因为它足够灵活能让我们看清每一个环节。pip install langchain langchain-openai requests同时你需要准备一个OpenAI的API密钥并设置环境变量export OPENAI_API_KEY你的sk-...密钥5.2 第一步打造你的“工具箱”我们创建两个最基础的Skill一个用于查询股价一个用于搜索新闻。# skills.py import requests from typing import Optional def get_stock_price(symbol: str) - str: 获取指定美股代码的实时股价。 参数: symbol: 美股股票代码大写字母例如 TSLA, AAPL。 返回: 包含股价信息的字符串。 # 这里使用一个免费的模拟API实际应用中请替换为真实的金融数据API如Alpha Vantage, Yahoo Finance # 注意免费API通常有调用频率限制。 try: # 示例URL仅用于演示 url fhttps://api.example-stock.com/v1/quote?symbol{symbol} response requests.get(url, timeout10) data response.json() price data.get(latestPrice, 未知) return f{symbol}的当前股价是 ${price}。 except Exception as e: return f查询{symbol}股价时出错{str(e)}。请检查股票代码或网络连接。 def search_news(keyword: str, max_results: int 3) - str: 根据关键词搜索近期新闻摘要。 参数: keyword: 搜索关键词例如 Tesla earnings。 max_results: 返回的最大新闻条数默认为3。 返回: 汇总的新闻摘要字符串。 # 同样这里使用模拟或免费的新闻API如NewsAPI需要注册 try: url fhttps://api.example-news.com/v2/everything?q{keyword}pageSize{max_results} response requests.get(url, timeout10) articles response.json().get(articles, []) if not articles: return f未找到关于{keyword}的近期新闻。 summaries [] for i, article in enumerate(articles[:max_results], 1): title article.get(title, 无标题) # 简单截取描述实际可更复杂 desc article.get(description, )[:100] ... if article.get(description) else 无摘要 summaries.append(f{i}. {title} - {desc}) return f关于{keyword}的新闻摘要\n \n.join(summaries) except Exception as e: return f搜索新闻时出错{str(e)}。5.3 第二步将工具“包装”成LangChain可识别的格式LangChain需要将我们的Python函数包装成它定义的Tool对象并附上让LLM理解的描述。# agent_builder.py from langchain.agents import Tool from skills import get_stock_price, search_news # 创建Tool对象 tools [ Tool( nameGetStockPrice, funcget_stock_price, description当需要查询美股的实时股价时使用此工具。输入必须是标准的股票代码例如TSLA代表特斯拉。 ), Tool( nameSearchNews, funcsearch_news, description当需要查找关于某个公司、产品或事件的近期新闻时使用此工具。输入是一个或多个关键词。 ), ]5.4 第三步创建Agent执行器我们使用LangChain提供的create_react_agent一种经典的推理行动模式来组装Agent。# agent_builder.py (续) from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain_core.prompts import PromptTemplate # 1. 初始化LLM llm ChatOpenAI(modelgpt-4o, temperature0) # 使用gpt-4o以获得更好的推理能力temperature0使输出更稳定 # 2. 定义提示词模板告诉Agent它的角色和可用工具 prompt_template PromptTemplate.from_template( 你是一个专业的金融信息助手。请根据用户的问题思考你需要做什么然后使用合适的工具来获取信息最后综合所有信息给出回答。 你有以下工具可以使用 {tools} 请严格按照以下格式思考和回应 思考首先分析用户的问题决定是否需要使用工具以及使用哪个工具。 行动需要使用的工具名称必须是以下之一[{tool_names}] 行动输入工具的输入参数 观察工具返回的结果 ... (这个思考-行动-观察的循环可以重复多次) 思考我现在有足够的信息来回答用户的问题了。 最终答案用清晰、友好的中文给出完整的答案。 现在开始 用户问题{input} {agent_scratchpad} # 这个部分用于记录循环的中间步骤 ) # 3. 创建Agent agent create_react_agent(llmllm, toolstools, promptprompt_template) # 4. 创建执行器它负责运行整个循环 agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue)5.5 第四步运行与测试现在让我们用最初的问题来测试我们的Agent。# run_agent.py from agent_builder import agent_executor question 特斯拉最新的股价是多少然后用中文总结一下它最近一周的新闻。 result agent_executor.invoke({input: question}) print(\n *50) print(最终答案) print(result[output])当你运行这段代码并将verbose设为True时你会在控制台看到类似以下的推理过程这是LangChain输出的日志非常有助于调试思考用户问了两个问题1. 特斯拉的股价。2. 特斯拉最近一周的新闻。我需要先获取股价再获取新闻。 行动GetStockPrice 行动输入TSLA 观察TSLA的当前股价是 $250.75。 思考我已经拿到了股价。现在需要获取特斯拉的新闻。 行动SearchNews 行动输入Tesla 观察关于Tesla的新闻摘要 1. 特斯拉发布新款Model 3 - 续航提升内饰更新... 2. 特斯拉上海工厂季度产量创新高 - 得益于供应链优化... 3. 马斯克宣布特斯拉AI日将于下月举行 - 将展示机器人最新进展... 思考我现在有足够的信息来回答用户的问题了。 最终答案根据查询特斯拉(TSLA)的最新股价为250.75美元。关于其近期动态过去一周的主要新闻包括1. 特斯拉发布了新款Model 3主要提升了续航里程并更新了内饰设计2. 其上海工厂本季度产量创下新高这得益于供应链的持续优化3. 首席执行官埃隆·马斯克宣布特斯拉的AI日活动将于下个月举行届时将展示其人形机器人的最新研发进展。看一个简单的、但具备自主规划和使用工具能力的AI助手就诞生了它自动将你的复杂问题分解依次调用两个Skill并将结果整合成一个连贯的回答。6. 避坑指南Agent开发中的典型挑战与对策在实际开发中你会遇到比示例复杂得多的情况。以下是我从多个项目中总结出的常见“坑”及其应对策略。6.1 工具选择错误与参数解析失败这是最常见的问题。LLM可能误解了工具描述调用了错误的工具或者传入了格式错误的参数。现象Agent在应该调用SearchNews时却调用了GetStockPrice或者给GetStockPrice传入了特斯拉而不是TSLA。根因分析工具描述模糊SearchNews的描述如果只是“搜索信息”LLM在查询股价时也可能用它。提示词引导不足系统提示词没有明确要求Agent先“思考”再“行动”导致其草率决策。缺乏参数校验与转换Skill函数内部没有对输入做清洗和转换。解决方案精细化工具描述如前所述在描述中明确使用场景、输入格式和边界。例如“仅当用户明确询问股票价格、股价时使用。输入必须是纯英文大写股票代码。”强化提示词工程在系统提示词中加入强约束。例如“你必须严格按照以下步骤工作1. 理解问题拆解子任务。2. 为每个子任务选择最精确的工具。3. 确保输入参数格式完全符合工具要求。”实现参数预处理层在Skill被调用前可以加入一个“参数格式化”的步骤。例如用一个轻量级的LLM调用或规则引擎将“特斯拉”转换为“TSLA”。或者在Skill函数开头加入逻辑if not symbol.isupper(): # 尝试从内部映射表查找中文名对应的代码...。6.2 复杂任务规划中的“迷失”与循环对于步骤超过5步的复杂任务Agent可能会在中间步骤“迷失”忘记最终目标或者陷入无效循环。现象任务执行到一半开始重复调用同一个工具或者执行与最终目标无关的操作。根因分析短期记忆溢出上下文窗口有限早期的任务目标和规划在对话中被挤到后面LLM“忘了”。缺乏全局状态跟踪Agent没有清晰的任务完成度概念。工具反馈的误导某个工具返回了错误或无关信息导致后续规划跑偏。解决方案采用结构化状态管理使用如LangGraph这样的框架显式地定义任务状态机。将任务分解为固定的阶段如“收集信息”、“分析”、“生成报告”每个阶段有明确的进入和退出条件防止跑偏。设计“检查点”提示在关键步骤后让LLM进行自我评估。例如在收集完所有数据后插入一个步骤“请根据最初的问题‘生成季度报告’检查目前收集到的信息是否完整。如果完整请进入分析阶段如果不完整请列出缺失项并继续收集。”设置超时与最大步数在AgentExecutor中务必设置max_iterations或max_execution_time防止无限循环消耗资源。6.3 外部工具的不确定性与错误处理外部API可能失败、超时返回的数据格式可能变化这些都会导致Agent崩溃。现象工具调用返回429 Too Many Requests错误或返回的JSON结构解析失败整个Agent流程中断。根因分析Skill函数没有考虑足够的异常情况Agent执行器没有设计重试或降级机制。解决方案Skill内部健壮性每个Skill函数都必须有完善的try-except并返回对Agent友好的错误信息而不是抛出异常。例如返回“新闻API服务暂时不可用请稍后再试”而不是一个Python异常栈。Agent层面的重试与降级配置AgentExecutor的handle_parsing_errorsTrue。对于可重试的错误如网络超时可以在框架层面配置自动重试策略。对于关键工具失效可以设计备用工具如主新闻API挂了切换到一个简单的网页搜索Skill。输入验证与默认值在调用工具前对参数进行基础验证。6.4 成本与延迟控制每一次LLM的“思考”和每一次工具调用都可能产生成本API费用和延迟。复杂的Agent循环可能又慢又贵。策略缓存对频繁且结果不变的查询如“苹果公司CEO是谁”进行缓存。简化规划对于简单、模式固定的任务可以不用复杂的ReAct循环而是用更直接的LLMChain或预定义的工作流。选择性价比模型在规划需要强推理环节使用能力强的模型如GPT-4在简单的文本生成或格式化环节使用更便宜、更快的模型如GPT-3.5-Turbo。设置预算监控API调用次数和Token消耗设置每日/每月限额。7. 进阶思考从单Agent到多Agent协作与生态当你掌握了构建单个Agent的技能后视野可以进一步打开。真实世界的复杂问题往往需要多个各有所长的Agent协同工作。7.1 多Agent系统架构想象一个“虚拟公司”研究员Agent擅长使用搜索工具、阅读文档负责信息收集与初步分析。分析师Agent擅长数据处理和图表生成负责将研究员收集的数据做成可视化报告。撰稿人Agent文笔好负责将分析师的报告润色成一篇正式的博客文章。协调员Agent或称为主Agent接收用户指令“写一篇关于新能源汽车市场趋势的报告”然后负责将任务分解指派给研究员、分析师、撰稿人并协调他们的工作顺序汇总最终成果。这种架构可以通过LangGraph等工具来实现其中每个Agent是一个节点它们通过消息传递进行协作。这大大提升了处理复杂任务的能力和系统的模块化程度。7.2 Skill的共享与市场随着AI应用生态的发展会出现“Skill商店”或“工具市场”。开发者可以将自己编写的高质量、通用的Skill如“发送Slack消息”、“查询CRM客户信息”、“生成特定格式的合同草案”发布出来。其他开发者可以像安装库一样将这些Skill轻松集成到自己的Agent中无需重复开发。这类似于手机上的“小程序”或“插件”生态将极大加速AI应用的创新。7.3 对人机交互的重新定义当Agent能力越来越强我们与软件的交互方式将从“手动操作每一个功能”转变为“用自然语言下达目标”。产品经理需要思考的不再是按钮和菜单如何布局而是如何设计一套强大的Skill库以及如何让Agent更准确地理解用户的意图和上下文。UI可能会演变成一个简单的对话输入框背后却是一个由无数Skill支撑的、强大的智能体系统。走到这一步你会发现最初的“LLM”、“Agent”、“Skill”这些名词已经内化为你设计系统时一种自然而然的分层思维模式。你不再为名词焦虑而是清晰地知道面对一个具体问题该在哪个层面去解决它是微调Prompt提升LLM的生成质量是优化Agent的规划逻辑还是开发一个新的Skill来扩展能力边界这种清晰的认知才是应对技术浪潮最有力的武器。