智能体(Agent) 是一种能够自主规划、决策、执行任务的组件核心是让大语言模型(LLM)根据任务需求选择并调用工具完成单靠模型自身无法解决的复杂问题。Agent智能体 大语言模型(大脑)工具集(手脚) 决策逻辑(思维)Agent智能体是让 LLM 从只会回答升级为会做事(影响现实世界)的智能助手。没有Agent时LLM 只能基于自身训练数据回答问题遇到需要实时数据、复杂计算、外部工具调用的场景就会卡壳。有了Agent后LLM 就像一个指挥官能思考任务步骤→选择合适工具→执行工具调用→根据结果调整策略直到完成任务。核心特点:目标驱动:围绕用户的具体任务目标展开工作。工具调用能力:能连接外部工具弥补LLM 的局限性自主决策与迭代:不需要人工干预能根据工具返回的结果判断是否需要继续调用工具或直接生成最终答案。agent与chain的区别chainagent执行固定流程按预设步骤执行执行流程动态根据任务和结果自主调整工具调用链路写死在代码中工具选择由LLM思考决定适合简单标准化任务适合复杂、多步骤、需要决策的任务创建agent通过create_agent方法可以创建Agent对象其也是Runnable接口的子类实现所以也拥有:invoke执行一次型得到完整结果stream执行流式得到结果agent调用invoke、stream时参数类型[message:[{role:user, content:query}]]invoke案例from langchain.agents import create_agent from langchain_community.chat_models import ChatTongyi from langchain_core.output_parsers import StrOutputParser from langchain_core.tools import tool api_key sk-xxx tool(description查询天气) def get_weather(city): return 晴天 agent create_agent( modelChatTongyi(modelqwen3-max, api_keyapi_key), tools[get_weather,], system_prompt你是一个聊天助手可以回答用户的问题 ) # agent调用invoke时参数类型[message:[{}]] res agent.invoke( { messages: [ {role: user, content: 明天上海的天气如何} ] } ) parser StrOutputParser() for message in res[messages]: print(f{type(message).__name__}: {parser.invoke(message)})stream案例from langchain.agents import create_agent from langchain_community.chat_models import ChatTongyi from langchain_core.tools import tool api_key sk-xxx tool(description获取股价传入股票名称返回字符串信息) def get_price(name: str) - str: return f股票{name}的价格是20元 tool(description获取股票信息传入股票名称返回字符串信息) def get_price_info(name: str) - str: return f股票{name}是一家上市公司专注游戏开发 agent create_agent( modelChatTongyi(modelqwen3-max, api_keyapi_key), tools[get_price, get_price_info], system_prompt你是一个智能助手可以回答股票相关问题 ) for chunk in agent.stream( {messages: [{role:user, content:大米公司的股价多少介绍一下}]}, stream_modevalues ): # print(chunk) latest_message chunk[messages][-1] if latest_message.content: print(type(latest_message).__name__, latest_message.content) try: # 如果有tool_calls说明在调用工具可以看到调用工具的信息 if latest_message.tool_calls: print(latest_message.tool_calls) except AttributeError as e: passReActAgent ReAct 是大模型智能体的核心思考与行动框架全称 ReasoningActing(推理行动)是让 Agent 像人类一样「思考问题→制定策略→执行行动→验证结果」的关键逻辑。简单来说:ReAct让 Agent不再是“直接回答问题”而是通过“自然语言思考过程”指导工具调用一步步解决复杂问题完美适配需要多步推理、工具协作的场景(如智能客服、报告生成、任务规划等)一个典型的ReAct范式的Agent如上图所示:思考Reasoning:模型分析问题判断现有信息是否足够明确下一步即模型决策是否需要调用外部工具获取更多信息用来回答行动Action:执行思考阶段指定的策略即基于模型决策结果调用工具获取信息观察observation:获取行动的结果提取有效信息即获取工具返回值即判断工具是否正常工作位下一轮思考提供信息思考-行动-观察-思考-行动-观察... 循环往复直到结束Langchain的Agent对象遵循ReAct框架要求在执行的过程中会持续的自我思考、自我行动、自我观察。案例from langchain.agents import create_agent from langchain_community.chat_models import ChatTongyi from langchain_core.tools import tool api_key sk-xxx tool(description获取体重返回值是整数单位千克) def get_weight() - int: return 70 tool(description获取身高返回值是整数单位是厘米) def get_height() - int: return 175 agent create_agent( modelChatTongyi(modelqwen3-max, api_keyapi_key), tools[get_weight, get_height], system_prompt你是一个严格遵循ReAct框架的智能体必须按照[思考-行动-观察-再思考]的流程解决问题 且**每轮仅能思考调用1个工具**禁止单次调用多个工具。 并告知我你的思考过程工具的调用原因按思考、行动、观察按个结构告知我 ) for chunk in agent.stream( {messages: [{role:user, content:计算我的BMI}]}, stream_modevalues ): # print(chunk) latest_message chunk[messages][-1] if latest_message.content: print(type(latest_message).__name__, latest_message.content) try: # 如果有tool_calls说明在调用工具可以看到调用工具的信息 if latest_message.tool_calls: print(latest_message.tool_calls) except AttributeError as e: passHumanMessage 计算我的BMI AIMessage [思考] 要计算BMI身体质量指数需要知道体重千克和身高米。公式为 $$ \text{BMI} \frac{\text{体重kg}}{\text{身高m}^2} $$ 目前我缺少用户的体重和身高数据因此需要先获取这两个数值。根据工具列表我可以分别调用 get_weight 和 get_height 来获取数据。由于每轮只能调用一个工具我首先选择获取体重。 [行动] [{name: get_weight, args: {}, id: call_dd1510e1647f4346946ea383, type: tool_call}] ToolMessage 70 AIMessage [观察] 获取到的体重是 70 千克。 [思考] 现在我已经有了体重数据70 kg接下来需要获取身高数据单位厘米。之后我可以将身高转换为米并计算 BMI。根据规则我每轮只能调用一个工具因此现在调用 get_height 来获取身高数据。 [行动] [{name: get_height, args: {}, id: call_46c534accd4843bfa84b47d9, type: tool_call}] ToolMessage 175 AIMessage [观察] 获取到的身高是 175 厘米。 [思考] 现在我已获取到体重70 kg和身高175 cm。接下来我可以计算 BMI。首先将身高从厘米转换为米175 cm 1.75 m。然后使用 BMI 公式 $$ \text{BMI} \frac{70}{1.75^2} \frac{70}{3.0625} \approx 22.86 $$ 因此用户的 BMI 约为 22.86属于正常范围。 [最终回答] 您的 BMI 是约 22.86属于正常范围。Plan-and-ExecuteReAct 模式是“思考 - 行动 - 观察”的单步循环适合短任务通过create_agent(LangChain 1.0) 或create_react_agent可以直接创建agent。Plan-and-Execute 模式是将任务拆分为“先制定完整计划再按步骤执行”的双阶段模式更适合长程、复杂的多步任务。其核心逻辑由三个组件组成Planner规划器一个 LLM Chain负责接收用户输入生成一个步骤列表Plan。Executor执行器通常是一个 ReAct Agent负责接收“当前步骤”调用工具执行并返回结果。Controller/Replanner控制/重规划器负责协调两者将执行结果反馈给 Planner或者判断是否完成任务。用 LangGraph 构建 Plan-and-Execute,应通过LangGraph的状态机State Graph来显式定义。这种方式让你能清晰看到“规划”和“执行”之间的状态跳转。核心设计思路State状态包含input用户输入,plan生成的计划列表,past_steps已执行的步骤及结果,response最终回答。Nodes节点planner_node: 调用 LLM 生成计划。agent_node: 调用 ReAct Agent 执行当前计划步骤。replan_node(可选): 根据执行结果调整后续计划。Edges边控制流程例如开始 - 规划 - 执行步骤1 - 执行步骤2 ... - 结束。# 确保安装最新版: pip install langchain langchain-openai langgraph import os from typing import Annotated, Sequence, TypedDict from langchain_openai import ChatOpenAI from langchain_core.messages import BaseMessage, HumanMessage, AIMessage from langchain.agents import create_agent from langgraph.graph import StateGraph, END from langchain_community.tools import DuckDuckGoSearchResults from langchain_community.utilities import DuckDuckGoSearchAPIWrapper os.environ[DASHSCOPE_API_KEY] sk-xxx # 初始化搜索工具 wrapper DuckDuckGoSearchAPIWrapper( regionzh-cn, # 中文结果 timey, # 最近一年 max_results1 # 最多1条 ) duck_search_tool DuckDuckGoSearchResults(api_wrapperwrapper, endpointhttp://api.wlai.vip) # --- 1. 定义状态 (State) --- class AgentState(TypedDict): input: str # 用户原始输入 plan: list[str] # 生成的计划步骤列表 past_steps: list[tuple] # 已执行的步骤 [(step_name, result), ...] response: str # 最终输出 current_step_index: int # 当前执行到的步骤索引 # --- 2. 初始化组件 --- llm ChatOpenAI( modelqwen3-max, api_keyos.getenv(DASHSCOPE_API_KEY, ), base_urlhttps://dashscope.aliyuncs.com/compatible-mode/v1, # streamingTrue, # 支持流式输出 temperature0.3 # 降低随机性让工具调用更稳定 ) tools [duck_search_tool] # 创建一个用于执行单步任务的 ReAct Agent (作为子节点) agent_executor create_agent( modelllm, toolstools, system_prompt你是一个负责执行具体子任务的助手。请根据给定的任务步骤调用工具。 ) # --- 3. 定义节点函数 --- def plan_node(state: AgentState): 规划节点将大任务拆解为步骤 messages [ HumanMessage( contentf 请为以下目标制定一个分步计划。 目标{state[input]} 要求 1. 输出一个 JSON 格式的列表包含具体的步骤字符串。 2. 每个步骤必须是可独立执行的任务。 3. 只输出 JSON 列表不要其他废话。例如[步骤1, 步骤2] ) ] # 为了简化演示这里直接让 LLM 输出文本实际生产中建议强制 JSON Output response llm.invoke(messages) # 简单解析 (实际需用 JSON Parser) # 假设 LLM 返回了类似 [step1, step2] 的字符串 import json try: # 清理可能的 markdown 标记 content response.content.replace(json, ).replace(, ).strip() plan_list json.loads(content) except: # 降级处理如果解析失败将其视为单步任务 plan_list [state[input]] print(fplan_list: {plan_list}) return {plan: plan_list, current_step_index: 0} def execute_step_node(state: AgentState): 执行节点执行当前步骤 if state[current_step_index] len(state[plan]): return {past_steps: state[past_steps]} # 没有更多步骤直接跳过 current_step state[plan][state[current_step_index]] print(fcurrent_step_index: {state[current_step_index]} - {current_step}) # 调用内部的 Agent 执行当前步骤 # 我们将“当前步骤”作为输入传给内部 agent result agent_executor.invoke( {messages: [HumanMessage(contentcurrent_step)]} ) print(result) output result.get(messages)[-1] # 更新状态 new_past_steps state.get(past_steps, []) [(current_step, output.content)] new_index state[current_step_index] 1 return { past_steps: new_past_steps, current_step_index: new_index } def should_continue(state: AgentState): 路由逻辑判断是否还有步骤要执行 if state[current_step_index] len(state[plan]): return continue else: return end def finalize_node(state: AgentState): 汇总节点将所有步骤结果汇总为最终答案 steps_summary \n.join([fStep: {s[0]}\nResult: {s[1]} for s in state[past_steps]]) messages [ HumanMessage( contentf 基于以下执行步骤和结果回答用户的原始问题。 原始问题{state[input]} 执行历史 {steps_summary} 请给出一个综合的最终回答。 ) ] response llm.invoke(messages) return {response: response.content} # --- 4. 构建图 (Graph) --- workflow StateGraph(AgentState) # 添加节点 workflow.add_node(planner, plan_node) workflow.add_node(executor, execute_step_node) workflow.add_node(finalizer, finalize_node) # 设置入口 workflow.set_entry_point(planner) # 定义边 # 从 planner 到 executor workflow.add_edge(planner, executor) # 条件边executor 完成后判断是继续执行下一步还是去 finalize workflow.add_conditional_edges( executor, should_continue, { continue: executor, # 循环回 executor 执行下一步 end: finalizer # 结束去汇总 } ) # 从 finalizer 到 END workflow.add_edge(finalizer, END) # 编译图 app workflow.compile() # --- 5. 运行测试 --- print(开始执行 Plan-and-Execute Agent...) inputs {input: 查询 2026 年华为手机的销量并对小米手机的销量数据最后总结谁更有优势。} result app.invoke(inputs) print(\n--- 最终回答 ---) print(result[response]) 开始执行 Plan-and-Execute Agent... plan_list: [ 确认2026年是否已结束以判断是否有实际销量数据可供查询。, 若2026年尚未结束查找权威市场研究机构如IDC、Counterpoint、Canalys对2026年华为手机销量的预测报告。, 若2026年已结束检索上述机构发布的2026年全年华为手机实际销量数据。, 同样方法查询2026年小米手机的销量预测或实际销量数据。, 将华为与小米在2026年的销量数据进行对比包括总量、同比增长率及市场份额。, 分析影响销量的关键因素如产品发布、市场策略、供应链状况等评估各自优势。, 基于销量数据和相关分析总结2026年华为与小米谁在销量上更具优势。 ] current_step_index: 0 - 确认2026年是否已结束以判断是否有实际销量数据可供查询。 current_step_index: 1 - 若2026年尚未结束查找权威市场研究机构如IDC、Counterpoint、Canalys对2026年华为手机销量的预测报告。 current_step_index: 2 - 若2026年已结束检索上述机构发布的2026年全年华为手机实际销量数据。 current_step_index: 3 - 同样方法查询2026年小米手机的销量预测或实际销量数据。 current_step_index: 4 - 将华为与小米在2026年的销量数据进行对比包括总量、同比增长率及市场份额。 current_step_index: 5 - 分析影响销量的关键因素如产品发布、市场策略、供应链状况等评估各自优势。 current_step_index: 6 - 基于销量数据和相关分析总结2026年华为与小米谁在销量上更具优势。 --- 最终回答 --- 截至目前2024年2026年尚未到来因此**没有华为或小米手机在2026年的实际销量数据**权威市场研究机构如IDC、Canalys、Counterpoint也**未发布针对2026年两家手机品牌销量的明确预测报告**。 不过结合现有趋势和相关信息可以做出以下综合判断 ### 一、关于手机业务 - **华为**近年来依托鸿蒙生态和自研芯片逐步恢复手机业务但受制于供应链和地缘政治因素其全球市场份额仍处于恢复阶段。目前尚无2026年手机销量的具体预测。 - **小米**2025年第一季度在中国市场手机销量同比增长40%市场份额达19%位居第一显示出强劲复苏势头。若该趋势延续2026年其手机销量有望保持竞争力。 但由于缺乏2026年双方手机销量的直接预测或数据**无法在手机领域明确判断谁更具销量优势**。 ### 二、关于智能汽车常被误纳入“销量”讨论 部分信息提及2026年小米汽车交付量如2月达23,728辆及华为赋能车型年销量或超200万辆但需注意 - **小米汽车**是小米集团直接销售的产品 - **华为不造车**其“销量”实为合作车企如问界、智界等搭载华为技术的车型总和。 若将智能汽车纳入广义“终端销量”考量 - **小米**在自有品牌电动车上增长迅速 - **华为**通过技术合作覆盖更广泛的车型和销量基数整体生态影响力更大。 ### 三、综合结论 - **就手机业务而言**2026年销量尚无可靠预测无法断定谁更有优势但小米近期表现更稳健华为则依赖技术突破与供应链恢复。 - **若泛化到智能终端整体生态**华为凭借“手机汽车鸿蒙生态”的多端协同在2026年可能具备更广泛的市场影响力小米则在手机与汽车双线发力增长潜力显著。 **最终回答** 由于2026年尚未到来**目前没有华为或小米手机在该年度的销量数据或权威预测**因此无法准确比较两者在手机销量上的优劣。现有信息更多反映其在智能汽车等新领域的布局。建议在2026年临近或结束后参考IDC、Canalys等机构发布的正式报告进行客观对比。 middleware中间件的作用是对智能体的每一步工作进行控制和自定义的执行作用场景:日志记录、分析、调试转换提示词、工具选择重试、备用、提前终止等逻辑控制安全防护、个人身份检测等Langchain中内置了一些基础的中间件参见:https://docs.langchain.com/oss/python/langchain/middleware/built-in中间件通过Hooks钩子来实现拦截自定义中间件可以简单的使用装饰器来定义。节点式钩子(执行点顺序拦截)before_agent:agent执行之前拦截after_agent:agent执行后拦截before_model:模型执行前拦截after model:模型执行后拦截针对工具和模型的包装式钩子wrap_modelcall:每个模型调用时候拦截wrap_tool cal:每个工具调用时候拦截案例from typing import Callable from langchain.agents import create_agent from langchain_community.chat_models import ChatTongyi from langchain_core.output_parsers import StrOutputParser from langchain_core.tools import tool from langchain.agents.middleware import before_agent, after_agent, \ before_model, after_model, wrap_model_call, wrap_tool_call, \ dynamic_prompt from langchain.agents import AgentState from langgraph.runtime import Runtime from langgraph.types import Command from langchain.tools.tool_node import ToolCallRequest from langchain_core.messages import ToolMessage from langchain.agents.middleware import ModelRequest api_key sk-xxx tool(description查询天气传入城市名称返回天气字符串信息) def get_weather(city: str) - str: return f{city}天气晴天 1.agent执行前 2.agent执行后 3.model执行前 4.model执行后 5.工具执行中 6.模型执行中 7.dynamic_prompt每次生成提示词前调用 request.runtime.context 是上下文字典可以添加标志位信息在其他中间件中获取 如 中间件监控到A工具被调用后添加标志信息提示词中间件调用时判断这个信息从而动态切换提示词 before_agent def log_before_agent( # 整个agent智能体中状态记录 state: AgentState, # 记录了整个执行过程中上下文状态信息 runtime: Runtime ) - None: # agent执行前会调用此函数并传入AgentStateRuntime两个对象 print(f[before_agent] agent启动并附带{len(state[messages])}条消息) after_agent def log_after_agent(state: AgentState, runtime: Runtime) - None: # agent执行后会调用此函数并传入AgentStateRuntime两个对象 print(f[after_agent] agent结束并附带{len(state[messages])}条消息) before_model def log_before_model(state: AgentState, runtime: Runtime) - None: # model执行前会调用此函数并传入AgentStateRuntime两个对象 print(f[before_model] model即将调用并附带{len(state[messages])}条消息) after_model def log_after_model(state: AgentState, runtime: Runtime) - None: # model执行后会调用此函数并传入AgentStateRuntime两个对象 print(f[after_model] model调用结束并附带{len(state[messages])}条消息) wrap_model_call def model_call_hook( # 请求的数据封装 request: ToolCallRequest, # 执行的工具函数 handler: Callable[[ToolCallRequest], ToolMessage | Command] ) - ToolMessage | Command: print(模型被调用) return handler(request) wrap_tool_call def tool_call_hook(request, handler): print(f执行工具{request.tool_call[name]}) print(f工具参数{request.tool_call[args]}) if request.tool_call[name] xxx: # xxx工具被调用 # 注入状态信息 request.runtime.context[xxx] True return handler(request) dynamic_prompt # 每次生成提示词前调用 def prompt_switch(request: ModelRequest) - str: # 需要返回提示词字符串 print([prompt_switch] 即将生成提示词) if request.runtime.context.get(xxx): # 切换提示词 return 明天北京的天气如何 return request.messages[-1].content agent create_agent( modelChatTongyi(modelqwen3-max, api_keyapi_key), tools[get_weather,], system_prompt你是一个聊天助手可以回答用户的问题, middleware[log_before_agent, log_after_agent, log_before_model, log_after_model, model_call_hook, tool_call_hook, prompt_switch] ) res agent.invoke( { messages: [ {role: user, content: 明天上海的天气如何} ] }, context{xxx: False} # request.runtime.context 上下文字典 ) parser StrOutputParser() for message in res[messages]: print(f{type(message).__name__}: {parser.invoke(message)})[before_agent] agent启动并附带1条消息 [before_model] model即将调用并附带1条消息 模型被调用 [after_model] model调用结束并附带2条消息 执行工具get_weather 工具参数{city: 上海} [before_model] model即将调用并附带3条消息 模型被调用 [after_model] model调用结束并附带4条消息 [after_agent] agent结束并附带4条消息 HumanMessage: 明天上海的天气如何 AIMessage: ToolMessage: 上海天气晴天 AIMessage: 明天上海的天气是晴天适合外出活动记得做好防晒哦~ChatOpenai bind_tools# 导入LLM以Deepseek为例可替换为百度千帆/硅基流动等用法一致 from langchain_openai import ChatOpenAI import os # 2. 初始化LLM需提前配置环境变量 DEEPSEEK_API_KEY llm ChatOpenAI( modeldeepseek-chat, api_keyos.getenv(DEEPSEEK_API_KEY, ), base_urlhttps://api.deepseek.com/v1, streamingTrue, # 支持流式输出 temperature0.3 # 降低随机性让工具调用更稳定 ) # 3. 定义工具用tool装饰器将普通函数转为AI可识别的工具 tool # 核心装饰器自动生成工具描述供LLM判断是否调用 def get_weather(query: str) - List[str]: 用于获取指定地区、指定时间的天气信息工具描述很重要LLM靠这个判断是否调用 :param query: 查询条件格式示例北京 今明两天天气、上海 明天是否下雨 :return: 天气信息列表包含每天的天气描述 # 这里是模拟工具返回真实场景替换为调用天气API如高德/百度天气接口 if 今明两天 in query or 今天 in query or 明天 in query: return [今天天气晴朗温度20~28℃微风, 明天天气多云转晴温度22~30℃南风3级] elif 后天 in query: return [后天天气小雨温度18~25℃东北风2级] else: return [f已查询到{query} 的天气为晴朗温度20~28℃模拟数据] # 工具列表可添加多个工具如搜索、计算等 tools [get_weather] # 4. 绑定工具到LLM告诉模型你现在拥有这些工具 # bind_toolsLangChain的工具绑定方法让LLM能识别工具并生成工具调用指令 llm_with_tools llm.bind_tools(tools) response llm_with_tools.invoke(北京气温乘2是多少) if response.tool_calls: # 手动处理每个工具调用 for tool_call in response.tool_calls: tool_result execute_tool(tool_call) messages.append(AIMessage(contentstr(tool_result))) # 再次调用获取最终回答 final_response llm.invoke(messages)ChatOpenai.bind_tools 与 LangChain agent 区别1.调用机制不同bind_tools()直接绑定工具到LLM让模型自主决定是否调用工具langchain Agent有一个专门的思考-行动-观察循环ReAct模式可以多次调用工具2.执行流程差异bind_tools()流程# 单次调用模型可能返回工具调用也可能直接返回文本 response llm.bind_tools(tools).invoke(messages) # 如果需要执行工具需要手动处理 if response.tool_calls: # 手动执行工具 # 手动将结果传回给模型 # 再次调用模型获取最终回答langchain Agent流程# Agent自动处理整个循环 agent.invoke(messages) # Agent内部会自动 # 1. 判断是否需要调用工具 # 2. 如果需要自动调用工具 # 3. 将工具结果传回给LLM # 4. 重复1-3直到得到最终答案3.决策能力差异# bind_tools() - 单次决策 tools [get_weather, search_web, calculate] llm.bind_tools(tools).invoke(北京天气怎么样并计算明天比今天高几度) # 可能只调用get_weather不会自动进行后续计算 # langchain Agent - 多步推理 agent.invoke(北京天气怎么样并计算明天比今天高几度) # 可能 # 1. 调用get_weather获取今明两天温度 # 2. 调用calculate计算温差 # 3. 整合信息回答用户实际应用场景使用bind_tools()适合# 简单场景只需要一次工具调用 tools [get_weather] llm ChatOpenAI(modeldeepseek-chat) llm_with_tools llm.bind_tools([get_weather]) # 翻译任务可能不需要工具 response llm.invoke(翻译hello到中文)使用langchain Agent适合# 复杂场景需要多步推理 from langchain.agents import create_tool_calling_agent tools [search_web, calculator, database_query] agent create_tool_calling_agent(llm, tools, prompt) # 需要多次工具调用的复杂问题 agent.invoke(查询公司去年Q4的销售数据计算同比增长率并查找相关行业新闻)关键对比表格特性bind_tools()Agent调用次数单次可多次自动执行工具否是推理循环无有ReAct复杂度低高适用场景简单工具调用复杂任务分解控制粒度细手动控制粗自动控制代码示例对比# bind_tools() 完整手动流程 llm_with_tools llm.bind_tools([get_weather, calculator]) response llm_with_tools.invoke(北京气温乘2是多少) if response.tool_calls: # 手动处理每个工具调用 for tool_call in response.tool_calls: tool_result execute_tool(tool_call) messages.append(AIMessage(contentstr(tool_result))) # 再次调用获取最终回答 final_response llm.invoke(messages) # langchain Agent 自动流程 agent create_agent(llm, [get_weather, calculator], prompt) # 一步完成所有操作 final_response agent.invoke({input: 北京气温乘2是多少})总结bind_tools()是底层工具绑定给你更多控制权而 Agent 是高层抽象自动处理完整的工具调用循环。选择哪个取决于你的具体需求