【AI】十六.模型Agent智能体进阶开发实战 小滴课堂讲师 2025年09月19日 ai大模型, aigc 预计阅读 40 分钟 #### 大模型智能体之CoT思维链和ReAct推理行动 ##### 需求背景:为什么需要CoT/ReAct? * 问题场景:传统大模型直接输出结果,但复杂任务(数学推理/多步骤决策)易出错 * 核心需求:让模型展示思考过程 + 动态调整策略 * 类比理解: * 普通模型 → 考试直接写答案 * CoT → 在试卷上写解题步骤 * ReAct → 边查公式手册边解题 ##### 什么是CoT(思维链,Chain of Thought) * **核心机制**:通过显式生成推理步骤得出最终答案 ```python """ 问题:...[输入问题]... 思考步骤: 1. 第一步分析(如提取关键数据) 2. 第二步计算(如公式应用) 3. ...(更多步骤) 最终答案:...[结论]... """ 比如问题:A超市苹果每斤5元,买3斤送1斤;B超市同品质苹果每斤6元但买二送一。买8斤哪家更划算? CoT推理: 1. A超市实际获得:3+1=4斤,花费3×5=15元 → 单价15/4=3.75元/斤 2. 买8斤需要购买两次活动:4×2=8斤 → 总价15×2=30元 3. B超市每3斤花费6×2=12元 → 单价12/3=4元/斤 4. 买8斤需购买3次活动(3×3=9斤)花费12×3=36元 → 实际单价36/9=4元/斤 5. 结论:A超市更优惠 ``` * 是一种促使大语言模型产生一系列中间推理步骤,进而得出最终答案的技术。 * 以往的大模型通常直接给出问题的答案,而 CoT 鼓励模型展示其思考过程,就像人类在解决复杂问题时逐步推导一样。 * 这种方法能增强模型在处理复杂推理任务时的性能,尤其是涉及算术、常识推理和符号操作的任务。 * 局限性 * **依赖模型知识**:若模型内部知识错误,推理链条也可能错误(如“太阳绕地球转”)。 * **不适用于动态信息**:无法处理需要实时数据的问题(如“今天天气如何”)。 * **步骤冗余**:简单问题可能因分步反而降低效率。 * 案例说明:算术问题 * 问题:小明有 5 个苹果,小红给他 3 个,然后他吃了 2 个,还剩下多少个苹果? * 无 CoT 回答:“6 个”。 * CoT 回答: * 首先,小明原本有 5 个苹果,小红又给了他 3 个,那么此时他拥有的苹果数为 5 + 3 = 8 个。 * 接着,他吃了 2 个苹果,所以剩下的苹果数是 8 - 2 = 6 个。 * 因此,小明最后还剩下 6 个苹果。 * 应用场景 * 教育领域 * 用于辅导学生学习数学、科学等学科的推理问题。 * 通过展示推理过程,学生能更好地理解解题思路,提高学习效果。 * 智能客服 * 在回答客户复杂问题时,展示推理过程能让客户更清楚解决方案的由来,增强客户对服务的信任。 ##### 什么是ReAct(推理与行动,Reasoning and Acting) * **交互逻辑**:循环执行"思考-行动-观察"步骤 ```python """ 问题:...[输入问题]... 思考:当前需要解决的问题是... 行动:调用__工具名称__(参数) 观察:工具返回结果... 思考:根据结果分析... (循环直至得出结论) 答案:...[最终结果]... """ 比如问题:2027年诺贝尔文学奖得主的代表作是什么? ReAct流程: [思考] 需要先确定最新获奖者 → 调用搜索工具 [行动] 使用DuckDuckGo搜索"2027诺贝尔文学奖获得者" [观察] 结果显示:法国作家安妮·艾诺 [思考] 需要确认其代表作品 → 调用维基百科工具 [行动] 查询维基百科"安妮·艾诺" [观察] 主要作品:《悠悠岁月》《位置》等 [结论] 代表作是《悠悠岁月》 ``` * ReAct 是一种让大模型结合推理和行动的范式,不是前端框架React * 模型不仅要进行推理,还能根据推理结果调用外部工具(如搜索引擎、数据库等)来获取额外信息,从而更有效地解决问题。 * 它使模型能够与外部环境交互,拓展了模型的能力边界。 * ReAct的优势 * 减少幻觉:通过实时调用外部工具验证信息,降低模型编造错误答案的概率。 * 处理复杂任务:适合多步骤问题(如数学计算、事实核查),传统单次生成容易出错。 * 透明可解释:模型的推理过程以自然语言呈现,便于人类理解其决策逻辑。 * 案例说明: * 问题:2027 年 NBA 总冠军是哪个队伍? * 无 ReAct 处理:由于模型训练数据可能存在时效性问题,可能无法给出准确答案或给出过时的信息。 * ReAct 处理: * 推理:模型意识到自己可能没有最新的 2026 年 NBA 总冠军信息,需要调用外部资源获取。 * 行动:调用体育新闻网站的 API 或搜索引擎查询相关信息。 * 结果:获取到最新信息后,给出准确回答,如 “2026年 NBA 总冠军是 [具体队伍名称]。 * 应用场景 * 知识问答系统 * 处理需要实时信息或特定领域最新数据的问题,如财经数据、体育赛事结果、科技动态等。 * 任务自动化 * 在自动化流程中,根据任务需求调用不同的工具和服务,如预订机票、查询物流信息、控制智能家居设备等。 ##### 技术框架对比 | 维度 | CoT | ReAct | | :---------------: | :-------------------------------: | :---------------------------------: | | **核心组件** | 纯提示工程,依赖模型知识 | 代理(Agent)+ 工具调用 | | **数据依赖** | 仅依赖内部知识 | 可接入外部数据源/API | | **错误修复** | 单次推理完成 | 可通过多次行动修正结果 | | **适用场景** | 理论推导/数学计算 | 实时信息查询/复杂任务分解 | | **计算开销** | 低 | 中高(涉及外部调用) | | **LangChain组件** | `ChatPromptTemplate` + `LLMChain` | `Agent` + `Tools` + `AgentExecutor` | | **优势** | 简单、透明 | 实时交互,扩展性强 | | **缺点** | 无法获取最新信息 | 依赖工具API的稳定性 | ##### 应用场景指南 | 场景类型 | 推荐方法 | 原因说明 | | :--------------: | :------: | :------------------------: | | 数学/逻辑推理 | CoT | 无需外部数据,单步推理高效 | | 实时数据获取 | ReAct | 需要调用搜索/API工具 | | 多步骤决策任务 | ReAct | 支持动态调整执行路径 | | 知识密集型问答 | CoT | 依赖模型内部知识库 | | 复杂问题分解执行 | 混合架构 | 兼顾推理与执行效率 | ##### 开发建议 * **方法选择原则**: - 纯推理 → CoT - 需实时数据 → ReAct * **提示工程技巧**: - CoT需明确定义步骤格式 - ReAct要严格规范行动命名(如`调用API名称_参数`) * **常见陷阱**: - CoT可能产生错误中间步骤 - ReAct需处理API调用失败情况 * 通过`verbose=True`参数观察两种方法的执行过程差异 * LangChain框架的模块化设计,可以灵活组合这两种技术,适应不同场景需求 #### 大模型的Zero-Shot和Few-Shot案例实战 ##### 零样本(Zero-Shot)学习 * 模型在**没有特定任务训练数据**的情况下,直接通过预训练知识和自然语言理解能力完成任务。 * 例如,直接要求模型生成从未见过的任务结果(如翻译、分类)。 * **核心原理**:依赖大模型在预训练阶段学习到的通用知识泛化能力 * 示例 - 用户输入:“将这句话翻译成中文:Hello, how are you?” - 模型输出:“你好” ##### 少量样本(Few-Shot)学习【照猫画虎】 - 模型通过**少量示例(通常3-5个)** 快速理解任务格式和需求,提升任务表现。 - 例如,提供几个问答示例后,模型能模仿格式回答新问题。 - **核心原理**:通过示例激发模型的上下文学习(In-Context Learning)能力,提升输出准确性和一致性。 - 示例 ``` 输入:“苹果 -> 水果”,输出:“香蕉 -> 水果” 输入:“汽车 -> 交通工具”,输出:“飞机 -> 交通工具” 输入:“猫 ->”,输出:“动物” ``` ##### 应用场景对比 | **场景** | **零样本(Zero-Shot)** | **少量样本(Few-Shot)** | | :----------------: | :------------------------: | :------------------------------------------: | | **适用任务复杂度** | 简单任务(如翻译、分类) | 复杂任务(如逻辑推理、特定格式生成) | | **数据依赖** | 无需示例 | 需要少量高质量示例 | | **输出可控性** | 较低(依赖模型预训练知识) | 较高(通过示例明确格式和规则) | | **典型用例** | 快速原型开发、通用问答 | 领域特定任务(如法律文档解析、医疗术语抽取) | ##### 案例实战 * 零样本学习案例:直接通过指令调用大模型生成答案 ```python from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate # 零样本提示模板 zero_shot_prompt = ChatPromptTemplate.from_messages([ ("system", "你是一个专业翻译,将文本从{source_lang}翻译到{target_lang}"), ("human", "{text}") ]) # 初始化大模型 llm = ChatOpenAI( model_name = "qwen-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", api_key="sk-005c3c25f6d042848b29d75f2f020f08", temperature=0.7 ) # 链式调用 chain = zero_shot_prompt | llm # 执行翻译(中文→英文) response = chain.invoke({ "source_lang": "中文", "target_lang": "英文", "text": "今天天气不错,我要学习AI大模型开发" }) print(response.content) ``` * 少量样本学习案例: 通过示例指导模型理解任务格式 ```python from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate from langchain_openai import ChatOpenAI import secret # 初始化大模型 llm = ChatOpenAI( model_name="qwen-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", api_key=secret.api_key, temperature=0.7 ) # 示例数据 examples = [ { "input": "苹果公司的总部在哪里?", "output": "根据我的大量思考:苹果公司的总部位于美国加利福尼亚州的库比蒂诺(Cupertino)。" }, { "input": "OpenAI的CEO是谁?", "output": "根据我的大量思考:OpenAI的现任CEO是萨姆·阿尔特曼(Sam Altman)。" } ] # 定义单条示例模板 example_template = """ 输入:{input} 输出:{output} """ example_prompt = PromptTemplate( template=example_template, input_variables=["input", "output"], ) # 构建Few-Shot提示模板 few_shot_prompt = FewShotPromptTemplate( examples=examples, example_prompt=example_prompt, suffix="输入:{question}\n输出:", input_variables=["question"] ) # 创建Chain并调用 few_shot_chain = few_shot_prompt | llm response = few_shot_chain.invoke({"question": "亚马逊的创始人是谁?"}) print(response.content) # 输出:根据我的大量思考:亚马逊的创始人是杰夫·贝索斯(Jeff Bezos)。 ``` * 总结 * **零样本 vs 少量样本**: - 零样本依赖模型预训练知识,适合通用任务。 - 少量样本通过示例提升任务适配性,适合专业场景。 * **LangChain 实现要点**: - **零样本**:使用 `AgentType.ZERO_SHOT_REACT_DESCRIPTION` 初始化智能体。 - **少量样本**:通过 `PromptTemplate` 设计含示例的提示词。 * **设计原则**: - **清晰指令**:明确任务目标和输出格式。 - **示例质量**:少量样本的示例需覆盖典型场景。 #### LangChain智能体执行引擎AgentExecutor ##### 需求背景:为什么需要 AgentExecutor? * 问题:当智能体(Agent)需要执行多步操作(如多次调用工具、循环推理)时,开发者需手动处理: * 执行循环:根据模型输出决定是否继续调用工具。 * 错误处理:捕获工具调用或模型解析中的异常。 * 流程控制:限制最大迭代次数,防止无限循环。 * 日志记录:追踪每一步的输入、输出和中间状态。 * 痛点: * 代码冗余:重复编写循环和错误处理逻辑。 * 维护成本高:复杂任务中难以保证流程稳定性。 * 可观测性差:难以调试多步骤执行过程。 ##### AgentExecutor介绍 * LangChain 提供的智能体执行引擎,封装了执行循环、错误处理和日志追踪,让开发者聚焦业务逻辑。 * 核心功能 | **功能** | **说明** | | :--------------: | :----------------------------------------------------------: | | **执行循环控制** | 自动迭代执行智能体的 `思考 -> 行动 -> 观察` 流程,直到满足终止条件。 | | **错误处理** | 捕获工具调用异常、模型解析错误,支持自定义重试或回退逻辑。 | | **迭代限制** | 通过 `max_iterations` 防止无限循环(如模型陷入死循环)。 | | **日志与追踪** | 记录每一步的详细执行过程(需设置 `verbose=True`),支持集成 LangSmith。 | | **输入输出处理** | 统一格式化最终结果,隐藏中间步骤细节(除非显式要求输出)。 | * 关键参数 | **参数** | **作用** | | :-------------------------: | :----------------------------------------------------------: | | `agent` | 绑定的智能体实例(如 `create_react_agent` 的返回值)。 | | `tools` | 智能体可调用的工具列表。 | | `verbose` | 是否打印详细执行日志(调试时建议开启)。 | | `max_iterations` | 最大迭代次数,防止死循环。 | | `handle_parsing_errors` | 自动处理模型输出解析错误(如返回无效工具名),可设置为 `True` 或自定义函数。 | | `return_intermediate_steps` | 是否返回中间步骤结果(用于调试或展示完整链路)。 | ##### 使用场景:何时需要 AgentExecutor * **多步骤任务**: - 例如:先调用搜索工具获取数据,再调用计算工具处理结果 ```python # 示例:计算商品折扣价 "思考:需要先获取商品价格,再计算折扣。" "行动1:调用 get_price(商品A)" "观察1:价格=100元" "行动2:调用 calculate_discount(100, 20%)" "观察2:折扣价=80元" ``` * **工具依赖场景**: - 例如:预订航班需要先查询航班号,再调用支付接口。 * **复杂推理任务**: - 例如:解决数学问题需多次尝试不同公式。 * **生产环境部署**: - 需保证服务稳定性(自动处理超时、限流等异常) * 伪代码参考 ```python from langchain.agents import AgentExecutor agent_executor = AgentExecutor( agent=agent, tools=tools, verbose=True, max_iterations=3, handle_parsing_errors=True ) # 执行查询(自动处理循环和错误) response = agent_executor.invoke({"input": "北京的气温是多少华氏度?"}) print(response["output"]) # 输出:25℃ = 77℉ ``` #### LangChain智能体之initialize_agent开发实战 ##### 需求背景 | 手工调用工具的问题 | `initialize_agent`解决方案 | | :----------------------: | :--------------------------: | | 需要手动编写工具选择逻辑 | 自动根据输入选择最合适的工具 | | 缺乏错误重试机制 | 内置异常处理和重试策略 | | 输出格式不统一 | 标准化响应格式 | | 难以处理多工具协作场景 | 自动编排工具调用顺序 | * 手动执行需要开发者自己处理任务分解、工具选择、参数生成、结果整合等步骤 * Agent利用大模型的推理能力自动完成这些步骤,提高了开发效率和系统的灵活性。 * 解决方案: * langchain内置多个方法快速创建智能体,能减少手动编码的复杂性,提升系统的智能性和适应性。 * 包括自动化任务分解、动态工具选择、错误处理、结果整合等 * 主要包含以下核心方法: * `initialize_agent`:通用初始化方法,快速构建智能体(兼容旧版)返回AgentExecutor。 * `create_react_agent`:基于 ReAct 框架的智能体,支持多步推理。 * `create_tool_calling_agent`:专为工具调用优化的智能体,支持结构化输出。 * 其他方法:如 `create_json_agent`(处理 JSON )、`create_openai_tools_agent`(适配 OpenAI 工具调用格式)  ##### initialize_agent方法介绍 * 通过封装智能体的决策逻辑和工具调度,旧版方法,未来可能被弃用 * **适用场景**:快速原型开发、简单任务处理 * 实现 * 自动化工具选择:根据输入动态调用合适的工具。 * 流程标准化:统一处理错误、重试、结果格式化。 * 简化开发:一行代码完成智能体初始化。 * 语法与参数详解 ```python from langchain.agents import initialize_agent def initialize_agent( tools: Sequence[BaseTool], # 可用工具列表 llm: BaseLanguageModel, # 大模型实例 agent: Optional[AgentType] = None, # Agent类型 verbose: bool = False, # 是否显示详细过程 ) -> AgentExecutor: ``` * **关键参数说明**:`agent_type` | AgentType | 适用场景 | 特点 | | :-----------------------------------------: | :------------------------------------: | :-----------------------: | | ZERO_SHOT_REACT_DESCRIPTION | 通用任务处理 | 基于ReAct框架,零样本学习 | | STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION | 结构化输入输出 | 支持复杂参数类型 | | CONVERSATIONAL_REACT_DESCRIPTION | 多轮对话场景 | 保留对话历史上下文 | | SELF_ASK_WITH_SEARCH | 结合自问自答和搜索工具,适合问答场景。 | 自动生成中间问题并验证 | ##### 案例实战 ```python from langchain.agents import initialize_agent, AgentType from langchain_openai import ChatOpenAI from langchain_core.tools import tool from langchain.agents import initialize_agent from langchain_community.utilities import SearchApiAPIWrapper import os # 设置SearchAPI的API密钥 os.environ["SEARCHAPI_API_KEY"] = "qQBHMQo4Rk8SihmpJjCs7fML" # 实例化SearchApiAPIWrapper对象,用于调用搜索API search = SearchApiAPIWrapper() #定义搜索工具 @tool("web_search", return_direct=True) def web_search(query: str) -> str: """ 当需要获取实时信息、最新事件或未知领域知识时使用,输入应为搜索关键词 """ try: results = search.results(query) # 获取前3条结果 return "\n\n".join([ f"来源:{res['title']}\n内容:{res['snippet']}" for res in results['organic_results'] ]) except Exception as e: return f"搜索失败:{str(e)}" # 使用 @tool 定义进行数学计算的工具 @tool("math_calculator", return_direct=True) def math_calculator(expression: str) -> str: """用于进行数学计算,输入应该是一个有效的数学表达式,如 '2 + 3' 或 '5 * 4'""" try: result = eval(expression) return str(result) except Exception as e: return f"计算出错: {str(e)}" #不同大模型效果不一样,有些会报错,不支持多个输入参数的工具 @tool("multiply") def multiply(a: int, b: int) -> int: """ 把传递的两个参数相乘 """ return a * b # 创建工具列表 tools = [math_calculator,web_search] # 初始化大模型 llm = ChatOpenAI( model_name = "qwen-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", api_key="sk-005c3c25f6d042848b29d75f2f020f08", temperature=0.7 ) # 使用 initialize_agent 创建代理 agent_chain = initialize_agent( tools=tools, # 使用的工具列表 llm=llm, # 使用的语言模型 agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, # 指定代理类型 verbose=True, # 打开详细日志,便于查看代理的思考过程 handle_parsing_errors=True #自动处理解析错误,提高Agent的稳定性。 ) #打印对应的智能体,更清晰底层逻辑 print(agent_chain.agent.llm_chain) print(agent_chain.agent.llm_chain.prompt.template) print(agent_chain.agent.llm_chain.prompt.input_variables) # 测试代理 # 需求 1: 计算 5 乘以 6 的结果 result1 = agent_chain.invoke({"input":"计算 5 乘以 6 的结果"}) print("计算 5 乘以 6 的结果:", result1) # 需求 2: 获取当前日期 #result2 = agent_chain.run("腾讯最新的股价") #result2 = agent_chain.invoke({"input":"腾讯最新的股价"}) #print("腾讯最新的股价:", result2 ``` #### 个人AI助理智能体之tool_calling_agent实战 ##### `create_tool_calling_agent `方法介绍 * 是 LangChain 0.3 新增的智能体创建方法, 要求模型直接返回工具调用参数(如 JSON 格式),减少中间解析错误。 * **结构化工具调用**:显式调用工具并传递结构化参数(支持复杂数据类型) * **多步骤任务处理**:适合需要按顺序调用多个工具的场景 * **精准控制**:通过自定义 Prompt 模板指导 Agent 行为 * 方法参数 ```python from langchain.agents import create_tool_calling_agent agent = create_tool_calling_agent( llm: BaseLanguageModel, # 语言模型实例(需支持结构化输出) tools: List[BaseTool], # 工具列表 prompt: ChatPromptTemplate # 提示模板(需明确工具调用规则) ) ``` | 参数 | 类型 | 必填 | 说明 | | :----: | :----------------: | :--: | :----------------------------------------------------------: | | llm | BaseLanguageModel | 是 | 支持工具调用的模型(如 `ChatOpenAI`) | | tools | Sequence[BaseTool] | 是 | 工具列表,每个工具需用 `@tool` 装饰器定义 | | prompt | ChatPromptTemplate | 是 | 控制 Agent 行为的提示模板,需包含 `tools` 和 `tool_names` 的占位符 | ##### 适用场景 * API 集成:如调用天气查询、支付接口等需要严格参数格式的场景。 * 多工具协作:模型需根据输入动态选择多个工具并传递参数。 * 高精度任务:如金融计算、医疗诊断等容错率低的场景。 ##### 案例实战: 个人AI助理智能体 ```python from langchain_openai import ChatOpenAI from langchain.agents import create_tool_calling_agent, Tool, AgentExecutor from langchain.tools import tool from datetime import datetime from langchain_core.prompts import ChatPromptTemplate # 定义获取当前日期的工具函数 @tool def get_current_date() -> str: """获取当前日期""" formatted_date = datetime.now().strftime("%Y-%m-%d") return f"The current date is {formatted_date}" # 定义搜索航班的工具函数 @tool def search_flights(from_city: str, to_city: str, date: str) -> str: """根据城市和日期搜索可用航班""" return f"找到航班:{from_city} -> {to_city},日期:{date},价格:¥1200" # 定义预订航班的工具函数 @tool def book_flight(flight_id: str, user: str) -> str: """预订指定航班""" return f"用户 {user} 成功预订航班 {flight_id}" # 定义获取股票价格的函数 def get_stock_price(symbol) -> str: return f"The price of {symbol} is $100." # 创建工具列表,包括获取股票价格、搜索航班、预订航班和获取当前日期的工具 tools = [ Tool( name="get_stock_price", func=get_stock_price, description="获取指定的股票价格" ), search_flights, book_flight, get_current_date ] # 初始化大模型 llm = ChatOpenAI( model_name="qwen-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", api_key="sk-005c3c25f6d042848b29d75f2f020f08", temperature=0.7 ) # 定义聊天提示模板 prompt = ChatPromptTemplate.from_messages( [ ("system", "你是一个AI助手,必要时可以调用工具回复问题"), ("human", "我叫老王,经常出差,身份证号是 4414231993210223213332"), #("placeholder", "{chat_history}"), ("human", "{input}"), ("placeholder", "{agent_scratchpad}"), ] ) # 创建代理 agent = create_tool_calling_agent(llm, tools, prompt) # 初始化代理执行器 , verbose=True可以看到思考明细, return_intermediate_steps返回中间结果 agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True,return_intermediate_steps=True) # 运行代理并获取结果 result = agent_executor.invoke({"input": "苹果股票是多少?根据我的行程,帮我查询下明天的航班,从广州去北京,并定机票"}) print(f"最终结果:{result}" ``` #### 旅游规划智能体之react_agent实战 ##### ReAct 框架 * **Re**asoning + **Act**ing 是一种结合推理和行动的智能体设计模式 * 由以下步骤循环组成: * **推理(Reason)**:分析当前状态,决定下一步行动(如调用工具或直接回答)。 * **行动(Act)**:执行选定的操作(如调用工具、查询数据)。 * **观察(Observe)**:获取行动结果,更新状态,进入下一轮循环。 ``` [Thought] <-- 推理阶段(分析当前状况) [Action] <-- 行动阶段(调用工具) [Observation] <-- 环境反馈(工具返回结果) ``` ##### create_react_agent * LangChain 提供的专用方法,用于创建基于 ReAct 框架的智能体 * 适合需要**多步动态决策**的任务(如复杂问答、数学问题求解)。 * 方法参数与语法 ```python from langchain.agents import create_react_agent agent = create_react_agent( llm: BaseLanguageModel, # 必须支持 ReAct 格式 tools: Sequence[BaseTool],# 工具集(需详细文档) prompt: ChatPromptTemplate # 必须包含 ReAct 特殊标记 ) -> Runnable ``` * 参考使用的提示模板结构 ```python # 官方推荐模板(从 hub 获取) prompt = hub.pull("hwchase17/react") # 模板核心内容示例: """ Answer the following questions using the following tools: {tools} Use the following format: Question: the input question Thought: 需要始终进行的思考过程 Action: 要执行的动作,必须是 [{tool_names}] 之一 Action Input: 动作的输入 Observation: 动作的结果 ...(重复思考/行动循环) Final Answer: 最终答案 """ ``` * 与其它方法的对比选型 | 场景特征 | 推荐方法 | 原因说明 | | :--------------: | :-----------------------: | :--------------------: | | 需要逐步推理 | create_react_agent | 显式思考链支持复杂逻辑 | | **严格参数传递** | create_tool_calling_agent | 结构化输入更可靠 | | 快速简单任务 | initialize_agent | 开箱即用最简配置 | | 需要自我修正 | create_react_agent | 错误后可重新推理 | | 与人类协作调试 | create_react_agent | 完整思考链易读性好 | * 适用场景 * 多步骤任务:例如:“查询北京的气温,并计算对应的华氏度。” * 动态工具选择:根据中间结果决定下一步调用哪个工具。 * 复杂推理任务:例如:“如果明天下雨,推荐室内活动;否则推荐户外活动。 ##### 案例实战:智能推荐助手 ```python from langchain_openai import ChatOpenAI from langchain.tools import tool from langchain_community.utilities import SearchApiAPIWrapper import os from langchain_core.prompts import PromptTemplate from langchain.agents import create_react_agent, AgentExecutor @tool def get_weather(city: str) -> str: """获取指定城市的天气""" # 模拟数据 weather_data = { "北京": "晴,25℃", "上海": "雨,20℃", "广州": "多云,28℃" } return weather_data.get(city, "暂不支持该城市") @tool def recommend_activity(weather: str) -> str: """根据天气推荐活动""" if "雨" in weather: return "推荐室内活动:博物馆参观。" elif "晴" in weather: return "推荐户外活动:公园骑行。" else: return "推荐一般活动:城市观光。" # 定义搜索工具 os.environ["SEARCHAPI_API_KEY"] = "qQBHMQo4Rk8SihmpJjCs7fML" @tool("web_search", return_direct=True) def web_search(query: str) -> str: """ 当需要获取实时信息、最新事件或未知领域知识时使用,输入应为搜索关键词 """ try: search = SearchApiAPIWrapper() results = search.results(query) # 获取前3条结果 return "\n\n".join([ f"来源:{res['title']}\n内容:{res['snippet']}" for res in results['organic_results'] ]) except Exception as e: return f"搜索失败:{str(e)}" tools = [get_weather, recommend_activity, web_search] # 初始化大模型 llm = ChatOpenAI( model_name="qwen-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", api_key="sk-005c3c25f6d042848b29d75f2f020f08", temperature=0.7 ) # 使用 LangChain 预定义的 ReAct 提示模板,https://smith.langchain.com/hub/hwchase17/react #from langchain import hub #prompt = hub.pull("hwchase17/react") # 模板内容示例: template = """ Answer the following questions as best you can. You have access to the following tools: {tools} Use the following format: Question: the input question you must answer Thought: you should always think about what to do Action: the action to take, should be one of [{tool_names}] Action Input: the input to the action Observation: the result of the action ... (this Thought/Action/Action Input/Observation can repeat N times) Thought: I now know the final answer Final Answer: the final answer to the original input question Begin! Question: {input} Thought:{agent_scratchpad} """ prompt = PromptTemplate.from_template(template) # 创建 ReAct 智能体 agent = create_react_agent(llm, tools, prompt) agent_executor = AgentExecutor( agent=agent, tools=tools, verbose=True, # 打印详细执行过程 max_iterations=3, # 限制最大迭代次数, handle_parsing_errors=lambda _: "请检查输入格式", # 错误处理 return_intermediate_steps=True # 保留中间步骤 ) # 执行查询 response = agent_executor.invoke({ "input": "我在北京玩3天,根据天气推荐活动, 顺便查询腾讯的股价是多少" }) print(response) ``` #### LLM综合实战-文档网络智能问答助手开发 ##### 需求说明 * 智能体核心功能 * **多模态知识整合** * 深度结合 **Milvus 向量数据库** 的本地文档知识与 **实时网络搜索能力**,实现对复杂问题的分步解析与回答。 * 支持同时处理 **结构化文档问答**(如技术框架详解)和 **实时信息查询**(如股价、日期等动态数据)。 * **智能工具决策** - 自动判断问题类型: - **文档相关问题**(如 "什么是Milvus?")调用 **Milvus 向量检索工具**,精准匹配本地知识库内容。 - **实时信息需求**(如 "腾讯股价")触发 **Web 搜索工具**,获取最新数据。 - 支持 **多问题串联回答**,例如一次性处理包含技术解释、时间查询、股价查询的复合任务。 * **交互式回答增强** - 通过 **LangChain Agent 框架** 的动态决策流程,展示问题拆解与工具调用的全过程(如中间思考步骤)。 - 提供 **结构化输出**,清晰标注每个答案的来源(如 "来自 Milvus 文档" 或 "来自实时搜索")。 ##### 技术亮点 * 工具链集成:无缝融合 Milvus 向量检索 + 网络搜索API + 大模型推理(如 Qwen-Plus)。 * 可视化流程:通过 LangSmith 追踪 Agent 的决策路径 * 自定义提示模板:支持灵活调整 Agent 的行为逻辑(如切换 create_tool_calling_agent 或 create_react_agent 模式)。 ##### 应用场景 * 技术文档问答:快速解析 Milvus 版本、功能、与 LangChain 的集成方法。 * 实时数据查询:动态获取股票价格、当前日期等时效性信息。 * 多步骤问题处理:如 "解释Milvus的工作原理,同时比较其与Faiss的优劣,最后给出GitHub最新教程链接"。 ##### 功能效果演示  ##### 编码实战 ```python from langchain_community.utilities import SearchApiAPIWrapper from langchain_core.tools import tool from langchain.agents import AgentExecutor, create_tool_calling_agent,create_react_agent from langchain.tools.retriever import create_retriever_tool from langchain_milvus import Milvus from langchain.prompts import PromptTemplate,ChatPromptTemplate from langchain_community.embeddings import DashScopeEmbeddings from langchain_openai import ChatOpenAI import os from pydantic import Field os.environ["LANGCHAIN_TRACING_V2"] = "true" os.environ["LANGCHAIN_API_KEY"] = "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" os.environ["LANGSMITH_ENDPOINT"] = "https://api.smith.langchain.com" os.environ["LANGSMITH_PROJECT"] = "agent_v1" # 配置搜索工具 os.environ["SEARCHAPI_API_KEY"] = "qQBHMQo4Rk8SihmpJjCs7fML" search = SearchApiAPIWrapper() @tool("web_search") def web_search(query: str) -> str: """当需要获取实时信息、最新事件或未知领域知识时使用,输入应为搜索关键词""" try: results = search.results(query) # 获取前3条结果 return "\n\n".join([ f"来源:{res['title']}\n内容:{res['snippet']}" for res in results['organic_results'] ]) except Exception as e: return f"搜索失败:{str(e)}" #初始化嵌入模型 embeddings = DashScopeEmbeddings( model="text-embedding-v2", # 第二代通用模型 max_retries=3, dashscope_api_key="sk-005c3c25f6d042848b29d75f2f020f08" ) vector_store = Milvus( embeddings, connection_args={"uri": "http://47.119.128.20:19530"}, collection_name='doc_qa_db', ) #获取检索器 retriever = vector_store.as_retriever() retriever_tool = create_retriever_tool( retriever, "milvus_retriever", "搜索有关 Milvus 的信息。对于任何有关 Milvus 的问题,你必须使用这个工具!", ) # 初始化大模型 llm = ChatOpenAI( model_name = "qwen-plus", base_url="https://dashscope.aliyuncs.com/compatible-mode/v1", api_key="sk-005c3c25f6d042848b29d75f2f020f08", temperature=0.7 ) tools = [web_search, retriever_tool] # #构建提示模板 ,采用create_tool_calling_agent的提示词模版 ``` * 编码实战 ```python # #构建提示模板 ,采用create_tool_calling_agent的提示词模版 # prompt = ChatPromptTemplate.from_messages([ # ("system", "你是一个AI文档助手,拥有多个工具,必要时可以利用工具来回答问题。"), # ("user", "{input}"), # ("placeholder", "{agent_scratchpad}") # ]) # # 创建Agent执行器 # agent = create_tool_calling_agent(llm, tools,prompt) #构建提示模板 ,采用create_react_agent的提示词模版 prompt = PromptTemplate.from_template('''Answer the following questions as best you can. You have access to the following tools: {tools} Use the following format: Question: the input question you must answer Thought: you should always think about what to do Action: the action to take, should be one of [{tool_names}] Action Input: the input to the action Observation: the result of the action ... (this Thought/Action/Action Input/Observation can repeat N times) Thought: I now know the final answer Final Answer: the final answer to the original input question Begin! Question: {input} Thought:{agent_scratchpad}''') agent = create_react_agent(llm, tools,prompt) #创建Agent执行器 agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True,handle_parsing_errors=True,return_intermediate_steps=True) def run_question(question: str): print(f"\n问题:{question}") result = agent_executor.invoke({"input": question}) print(f"\nllm-result:{result}") print(f"\n答案:{result['output']}\n{'='*50}") ``` ##### 案例测试 * 提问输入问题 ``` run_question("中文回答下面3个问题:第一个:什么是Milvus,最新的版本是多少,如何整合LangChain框架,其与Faiss的优劣,最后给出GitHub最新教程链接; 第二个:现在的日期是几号;第三个:腾讯的股价是多少") ``` * LangSmith调用链路分析  * 切换不同创建agent方法和提示词进行测试 * 打印输出中间思考步骤 * 使用 AgentExecutor 的 `return_intermediate_steps` 参数 ```python #print("最终结果:", result["output"]) #print("中间步骤:", result["intermediate_steps"]) def run_question(question: str): print(f"\n问题:{question}") result = agent_executor.invoke({"input": question}) print(f"\nllm-result:{result}") print(f"\n答案:{result['output']}\n{'='*50}") # 输出完整执行轨迹 print("=== 完整执行链 ===") for step in result["intermediate_steps"]: print(f"Action: {step[0].tool}") print(f"Input: {step[0].tool_input}") print(f"Observation: {step[1]}\n") ``` ##### 总结说明 * 在AI智能体开发中,不同的任务需要不同的交互逻辑,因此需要不同类型的智能体来高效处理不同任务。 * 例如: - 有些任务需要智能体先“思考”再行动(如解数学题)。 - 有些任务需要直接调用工具完成(如查天气、调用计算器) * **关键选择点**: * 任务是否需要分解步骤 → 选`create_react_agent`; * 任务是否单一明确 → 选`create_tool_calling_agent`。 * **进阶技巧**: * 混合使用两种智能体(如先用React分解任务,再调用Tool-Calling执行子任务) * 共同点 - 均基于大模型(如LLM大模型)驱动。 - 依赖预定义的工具集(Tools)。 * **底层关系**: * `create_tool_calling_agent` 可视为 `create_react_agent` 的简化版(跳过显式推理步骤)。
评论区