LangChain使用之Agents

1、理解Agents

  • 通用人工智能(AGI)将是AI的终极形态,几乎已成为业界共识。同样,构建智能体(Agent)则是AI工程应用当下的“终极形态”。

  • 将 AI 和人类协作的程度类比自动驾驶的不同阶段:

1.1 Agent与Chain的区别

  • Agent与传统的固定流程链(chain)不同,Agent具备一定的自主决策能力,更适合处理开放式、多步骤的问题。
  • 它可以根据任务动态决定
    • 如何拆解任务
    • 需要调用哪些工具
    • 什么顺序调用
    • 如何利用好中间结果推进任务

1.2 什么是Agent

  • Agent(智能体) 是一个通过动态协调大语言模型(LLM)工具(Tools)来完成复杂任务的智能系统。它让LLM充当”决策大脑”,根据用户输入自主选择和执行工具(如搜索、计算、数据库查询等),最终生成精准的响应。

1.3 Agent的核心能力/组件

  • 作为一个智能体,需要具备以下核心能力:

    • **大模型(LLM)**:作为大脑,提供推理、规划和知识理解能力。
      • 比如:OpenaAI()、ChatOpenAI()
    • **记忆(Memory)**:具备短期记忆(上下文)和长期记忆(向量存储),支持快速知识检索。
      • 比如:ConversationBufferMemory、ConversationSummaryMemory、ConversationBufferWindowMemory等。
    • **工具(Tools)**:调用外部工具(如API、数据库)的执行单元。
      • 比如:SearchTool、CalculatorTool
    • **规划(Planning)**:任务分解、反思与自省框架实现复杂任务处理。
    • **行动(Action)**:实际执行决策的能力。
      • 比如:检索、推理、编程。
    • 协作:通过与其他智能体交互合作,完成更复杂的任务目标。
  • 问题:为什么要调用第三方工具(比如:搜索引擎或者 数据库)或借助第三方库呢?

    • 因为大模型虽然非常强大,但是也具备一定的局限性。比如不能回答实时信息、处理复杂数学逻辑问题仍然非常初级等等。因此,可以借助第三方工具来辅助大模型的应用。
    • 以MCP工具为例说明:https://bailian.console.aliyun.com/?tab=mcp#/mcp-market

1.4 举例

我们期待它不仅仅是执行任务的工具,而是一个能够思考、自主分析需求、拆解任务并逐步实现目标的智能实体。这种形态的智能体才更接近于人工智能的终极目标——AGI(通用人工智能),它能让类似于托尼·斯塔克的贾维斯那样的智能助手成为现实,服务于每个人。

1.5 明确几个组件

  • Agents 模块有几个关键组件:

    • 工具 Tool
      • LangChain 提供了广泛的入门工具,但也支持自定义工具,包括自定义描述。
      • 在框架内,每个功能或函数被封装成一个工具(Tools),具有自己的输入、输出及处理方法。
      • 具体使用步骤
        • ① Agent 接收任务后,通过大模型推理选择适合的工具处理任务。
        • ② 一旦选定,LangChain将任务输入传递给该工具,工具处理输入生成输出。
        • ③ 输出经过大模型推理,可用于其他工具的输入或作为最终结果返回给用户。
    • 工具集 Toolkits
      • 在构建Agent时,通常提供给LLM的工具不仅仅只有一两个,而是一组可供选择的工具集(Tool列表),这样可以让 LLM 在完成任务时有更多的选择。
    • 智能体/代理 Agent
      • 智能体/代理(agent)可以协助我们做出决策,调用相应的 API。底层的实现方式是通过 LLM 来决定 下一步执行什么动作。
    • 代理执行器 AgentExecutor
      • AgentExecutor本质上是代理的运行时,负责协调智能体的决策和实际的工具执行。

    AgentExecutor是一个很好的起点,但是当你开始拥有更多定制化的代理时,它就不够灵活了。 为了解决这个问题,我们构建了LangGraph,使其成为这种灵活、高度可控的运行时。

2、Agent入门使用

2.1 Agent、AgentExecutor的创建

环节1:创建Agent 环节2:创建AgentExecutor
方式1:传统方式 使用AgentType指定 initialize_agent()
方式2:通用方式 create_xxx_agent() 比如:
create_react_agent()、create_tool_calling_agent()
调用AgentExecutor()构造方法

2.2 Agent的类型

代理类型:顾名思义就是某件事可以由不同的人去完成,最终结果可能是一样的,但是做的过程可能各有千秋。比如一个公司需求,普通开发可以编写,技术经理也可以编写,CTO也可以编写,虽然都能完成最后的需求,但是CTO做的过程可能更加直观,高效。

2.2.1 FUNCATION_CALL模式

  • 基于结构化函数调用(如 OpenAI Function Calling)

  • 直接生成工具调用参数(JSON 格式

  • 效率更高,适合工具明确的场景

  • 典型AgentType

    1
    2
    3
    4
    5
    #第1种:
    AgentType.OPENAI_FUNCTIONS

    #第2种:
    AgentType.OPENAI_MULTI_FUNCTIONS
  • 工作流程示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    1步:找到Search工具:{"tool": "Search", "args": {"query": "LangChain最新版本"}}

    2步:执行Search工具

    ======================================

    1步:找打scrape_website工具:{"tool": "Search", "args": {"target": "LangChain最新版本","url":"要抓取的网站地址"}}

    2步:执行scrape_website工具

2.2.2 ReAct模式

  • 基于 文本推理 的链式思考(Reasoning + Acting),具备反思和自我纠错能力。

    • 推理(Reasoning):分析当前状态,决定下一步行动
    • 行动(Acting):调用工具并返回结果
  • 通过自然语言描述决策过程

  • 适合需要明确推理步骤的场景。例如智能客服、问答系统、任务执行等。

  • 典型 AgentType

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #第1种:零样本推理(可以在没有预先训练的情况下尝试解决新的问题)
    AgentType.ZERO_SHOT_REACT_DESCRIPTION


    #第2种:无记忆对话
    AgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION


    #第3种:带记忆对话
    AgentType.CONVERSATIONAL_REACT_DESCRIPTION
  • 工作流程示例

    1
    2
    3
    4
    问题:我想要查询xxx
    思考:我需要先搜索最新信息 → 行动:调用Search工具 → 观察:获得3个结果 →
    思考:需要抓取第一个链接 → 行动:调用scrape_website工具...→ 观察:获得工具结果
    最后:获取结果
  • Agent两种典型类型对比表

    特性 Function 模式 ReAct 模式
    底层机制 结构化函数调用 自然语言推理
    输出格式 JSON/结构化数据 自由文本
    适合场景 需要高效工具调用 需要解释决策过程
    典型延迟 较低(直接参数化调用) 较高(需生成完整文本)
    LLM要求 需支持函数调用(如gpt-4) 通用模型即可

2.3 AgentExecutor创建方式

2.3.1 传统方式:initialize_agent()

  • 特点

    • 内置一些标准化模板(如ZERO_SHOT_REACT_DESCRIPTION
    • Agent的创建:使用AgentType
  • 优点:快速上手(3行代码完成配置)

  • 缺点:定制化能力较弱(如提示词固定)

  • 代码片段

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    from langchain.agents import initialize_agent

    #第1步:创建AgentExecutor
    agent_executor = initialize_agent(
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    tools=[search_tool],
    verbose=True
    )

    #第2步:执行
    agent_executor.invoke({"xxxx"})

2.3.2 通用方式:AgentExecutor构造方法

  • 特点

    • Agent的创建:使用create_xxx_agent
  • 优点

    • 可自定义提示词(如从远程hub获取或本地自定义)
    • 清晰分离Agent逻辑与执行逻辑
  • 缺点

    • 需要更多代码
    • 需理解底层组件关系
  • 代码片段

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    prompt = hub.pull("hwchase17/react")
    tools = [search_tool]

    #第1步:创建Agent实例
    agent = create_react_agent(
    llm=llm,
    prompt=prompt,
    tools=tools
    )

    #第2步:创建AgentExecutor实例
    agent_executor = AgentExecutor(
    agent=agent,
    tools=tools
    )

    #第3步:执行
    agent_executor.invoke({"input":"xxxxx"})

2.4 小结创建方式

组件 传统方式 通用方式
Agent创建 通过AgentType枚举选择预设 通过create_xxx_agent显式构建
AgentExecutor创建 通过initialize_agent()创建 通过AgentExecutor()创建
提示词 内置不可见 可以自定义
工具集成 AgentExecutor中显式传入 Agent/AgentExecutor中需显式传入

3、Agent中工具的使用

3.1 传统方式

3.1.1 案例1:单工具使用

  • 需求:今天北京的天气怎么样?
  • 使用Tavily搜索工具
    • Tavily的搜索API是一个专门为人工智能Agent(llm)构建的搜索引擎,可以快速提供实时、准确和真实的结果。
    • LangChain 中有一个内置工具,可以轻松使用 Tavily 搜索引擎作为工具。
    • TAVILY_API_KEY申请:https://tavily.com/,注册账号并登录,创建 API 密钥。

方式1:ReAct模式

  • AgentType是 ZERO_SHOT_REACT_DESCRIPTION

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    from langchain_core.tools import StructuredTool
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType
    from langchain.tools import Tool
    import os
    import dotenv
    from langchain_openai import ChatOpenAI
    from langchain_community.tools.tavily_search import TavilySearchResults
    dotenv.load_dotenv()

    # 读取配置文件的信息
    os.environ['TAVILY_API_KEY'] = os.getenv("TAVILY_API_KEY")

    # 获取Tavily搜索工具的实例
    search = TavilySearchResults(max_results=3)

    # 获取一个搜索的工具
    # 方式1:
    # search_tool = StructuredTool.from_function(
    # func=search.run,
    # name="Search",
    # description="用于检索互联网上的信息",
    # )

    # 方式2:使用Tool
    search_tool = Tool(
    func=search.run,
    name="Search",
    description="用于检索互联网上的信息",
    )

    # 获取大语言模型
    os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
    os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
    llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
    )

    # 获取Agent的实例
    agent = AgentType.ZERO_SHOT_REACT_DESCRIPTION

    # 获取AgentExecutor的实例
    agent_executor = initialize_agent(
    tools = [search_tool],
    llm = llm,
    agent = agent,
    verbose = True, # 显示详细的日志信息
    )

    # 通过AgentExecutor 调用invoke(),并得到响应
    result = agent_executor.invoke("查询北京今天的天气情况")

    # 处理响应数据
    print(result)
    # > Entering new AgentExecutor chain...
    # 我需要查找北京今天的天气情况。
    # Action: Search
    # Action Input: "北京今天的天气情况"
    # Observation: [{'title': '今天白天北京多云转晴最高气温11℃ 阵风6至7级警惕风寒效应', 'url': 'https://www.stdaily.com/web/gdxw/2025-10/19/content_417555.html', 'content': '气象部门提醒,目前北京处于寒潮蓝色和大风蓝色预警信号中,今天最高气温仅11℃,且风力较大,需警惕风寒效应。明后天,风力减小,但寒冷感仍旧在线,公众需持续做好保暖措施。\n\n责任编辑:陈可轩\n\n相关稿件:\n\n网友评论\n\n最热评论\n\n没有更多评论了\n\n热点\n\n痛别!杨振宁先生逝世\n\n中国民众追忆著名物理学家杨振宁\n\n“中国天眼”立新功 首次捕获恒星黑子区射电暴信号\n\n机器人如何越来越“像人”\n\n封面新闻\n\n 封面新闻丨第40个教师节,致敬这些良师益友\n 亮点纷呈 氛围感拉满!2024年国家网络安全宣传周开启\n 封面新闻丨共赴十年之约 2024数博会引领数字经济发展新潮流\n 全国生态日丨我国生态环境和质量持续改善\n\n精彩视频\n\n 重温杨振宁生前喜爱的一首诗(节选)\n 苍穹有颗杨振宁星\n 北大荒迎初雪,大马力拖拉机首秀上演黑白映画\n\n 深入贯彻中央八项规定精神学习教育\n 创新故事\n 科普一下\n 铭记历史 缅怀先烈\n\n### 友情链接 [...] 时政\n 热点\n 政务\n 深瞳\n 访谈\n 视频\n 国际\n 地方\n 专题\n English\n 滚动\n\n登录 -\n\n所在位置: 中国科技网首页 > 滚动 > 正文\n\n# 今天白天北京多云转晴最高气温11℃ 阵风6至7级警惕风寒效应\n\n2025-10-19 08:22:23 来源: 中国天气网 点击数:\n\n今天(10月19),北京大部晴天在线,最高气温11℃,最低气温接近冰点,风力较大,阵风可达6至7级,公众外出需厚装护体,警惕风寒效应。\n\n受高空槽影响,昨天下午至夜间,北京西部、北部出现小雨或零星小雨,高海拔山区为雪,城区局地短暂零星小雨。此外,受冷空气影响,西部北部地区风力已加大,阵风一度达到6至7级。\n\n今天北京风力较大,阵风可达6至7级,需警惕风寒效应。北京市气象台预计,今天早晨至白天,北京多云转晴,早晨山区有雨夹雪或零星小雪,偏北风3、4级,阵风6至7级,最高气温11℃,夜间晴天为主,最低气温可接近冰点。\n\n明后天,北京天气以晴天间多云为主,风力不大,但气温依旧低迷,最高气温维持在10℃出头,最低气温在5℃以下,仍需做好保暖工作。 [...] 京ICP备06005116号\n 违法和不良信息举报电话:010-58884152\n 京公网安备 110402500060\n\n#### 抱歉,您使用的浏览器版本过低或开启了浏览器兼容模式,这会影响您正常浏览本网页\n\n### 您可以进行以下操作:\n\n## 1.将浏览器切换回极速模式\n\n## 2.点击下面图标升级或更换您的浏览器\n\n## 3.暂不升级,继续浏览\n\n 继续浏览', 'score': 0.80771893}, {'title': '中国气象局-天气预报-城市预报- 北京', 'url': 'https://weather.cma.cn/web/weather/', 'content': '| 气压 | 1012.5hPa | 1011.9hPa | 1010.1hPa | 1008.7hPa | 1009.2hPa | 1009.7hPa | 1009.4hPa | 1008.9hPa |\n| 湿度 | 93.2% | 73.3% | 79.1% | 78.5% | 84.3% | 87% | 90.4% | 92% |\n| 云量 | 0% | 26.6% | 10.1% | 45.4% | 78.5% | 62.5% | 90% | 0% | [...] | | | | | | | | | |\n --- --- --- --- \n| 时间 | 08:00 | 11:00 | 14:00 | 17:00 | 20:00 | 23:00 | 02:00 | 05:00 |\n| 天气 | | | | | | | | |\n| 气温 | 25.9℃ | 27.7℃ | 30.8℃ | 29.4℃ | 27.4℃ | 26℃ | 24.2℃ | 25.4℃ |\n| 降水 | 无降水 | 2.3mm | 2.3mm | 2.3mm | 2.3mm | 无降水 | 无降水 | 1.9mm |\n| 风速 | 3.2m/s | 3.2m/s | 3.3m/s | 2.5m/s | 2.6m/s | 2.6m/s | 2.4m/s | 2.8m/s |\n| 风向 | 西南风 | 西南风 | 西南风 | 西南风 | 西南风 | 西南风 | 西南风 | 东南风 | [...] | | | | | | | | | |\n --- --- --- --- \n| 时间 | 11:00 | 14:00 | 17:00 | 20:00 | 23:00 | 02:00 | 05:00 | 08:00 |\n| 天气 | | | | | | | | |\n| 气温 | 24.2℃ | 28.3℃ | 28.8℃ | 26.1℃ | 23.8℃ | 23.4℃ | 22.2℃ | 25.3℃ |\n| 降水 | 2.3mm | 2.3mm | 2.3mm | 2.3mm | 0.9mm | 无降水 | 0.7mm | 无降水 |\n| 风速 | 3.1m/s | 3.3m/s | 3.3m/s | 2.6m/s | 2.8m/s | 3m/s | 3.3m/s | 3.3m/s |\n| 风向 | 东北风 | 西南风 | 东南风 | 西南风 | 西南风 | 东南风 | 东北风 | 东南风 |', 'score': 0.7811474}, {'title': '2025年10月19日天气预报', 'url': 'https://www.bjmy.gov.cn/sy/tqyb/202510/t20251019_516213.html', 'content': '10月19日07时发布天气预报:今天白天:晴,偏北风3、4级,阵风6级左右,最高气温11℃;今天夜间:晴,偏北风2级左右,最低气温-3℃。\n\n扫一扫在手机上打开页面\n\n打印)\n关闭;window.close();)\n\n 关于我们\n 站点地图\n 建议意见\n 法律声明\n\n 网站二维码\n 邮箱:[email protected]\n\n 政务服务热线:12345\n 官方微信\n\n 官方微博\n\n 宜居密云app\n\n主办:北京市密云区人民政府办公室\n\n承办:北京市密云区政务服务和数据管理局\n\n政府网站标识码 1102280002\n\n京公网安备 11022802010001\n\n您访问的链接即将离开“北京市密云区人民政府”门户网站 是否继续?', 'score': 0.76596165}]
    # Thought:我现在知道了北京今天的天气情况。
    # Final Answer: 今天(10月19日),北京白天多云转晴,最高气温11℃,最低气温接近冰点,风力较大,阵风可达6至7级,公众外出需注意保暖,警惕风寒效应。
    #
    # > Finished chain.
    # {'input': '查询北京今天的天气情况', 'output': '今天(10月19日),北京白天多云转晴,最高气温11℃,最低气温接近冰点,风力较大,阵风可达6至7级,公众外出需注意保暖,警惕风寒效应。'}

    上述示例也可以写为:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    from langchain_core.tools import StructuredTool
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType
    from langchain.tools import Tool
    import os
    import dotenv
    from langchain_openai import ChatOpenAI
    from langchain_community.tools.tavily_search import TavilySearchResults
    dotenv.load_dotenv()

    # 读取配置文件的信息
    os.environ['TAVILY_API_KEY'] = os.getenv("TAVILY_API_KEY")

    # 获取Tavily搜索工具的实例
    search = TavilySearchResults(max_results=3)

    # 获取大语言模型
    os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
    os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
    llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
    )

    # 获取Agent的实例
    agent = AgentType.ZERO_SHOT_REACT_DESCRIPTION

    # 获取AgentExecutor的实例
    agent_executor = initialize_agent(
    tools = [search],
    llm = llm,
    agent = agent,
    verbose = True, # 显示详细的日志信息
    )

    # 通过AgentExecutor 调用invoke(),并得到响应
    result = agent_executor.invoke("查询北京今天的天气情况")

    # 处理响应数据
    print(result)

方式2:FUNCATION_CALL模式

  • AgentType是OPENAI_FUNCTIONS。提示:只需要修改前面代码中的initialize_agent中的agent参数值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    from langchain_core.tools import StructuredTool
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType
    from langchain.tools import Tool
    import os
    import dotenv
    from langchain_openai import ChatOpenAI
    from langchain_community.tools.tavily_search import TavilySearchResults
    dotenv.load_dotenv()

    # 读取配置文件的信息
    os.environ['TAVILY_API_KEY'] = os.getenv("TAVILY_API_KEY")

    # 获取Tavily搜索工具的实例
    search = TavilySearchResults(max_results=3)

    # 获取一个搜索的工具
    # 方式1:
    # search_tool = StructuredTool.from_function(
    # func=search.run,
    # name="Search",
    # description="用于检索互联网上的信息",
    # )

    # 方式2:使用Tool
    search_tool = Tool(
    func=search.run,
    name="Search",
    description="用于检索互联网上的信息",
    )

    # 获取大语言模型
    os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
    os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
    llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
    )

    # 获取Agent的实例 (使用function_call模型)
    agent = AgentType.OPENAI_FUNCTIONS

    # 获取AgentExecutor的实例
    agent_executor = initialize_agent(
    tools = [search_tool],
    llm = llm,
    agent = agent,
    verbose = True, # 显示详细的日志信息
    )

    # 通过AgentExecutor 调用invoke(),并得到响应
    result = agent_executor.invoke("查询北京今天的天气情况")

    # 处理响应数据
    print(result)
    # > Entering new AgentExecutor chain...
    #
    # Invoking: `Search` with `北京今天的天气情况`
    #
    #
    # [{'title': '今天白天北京多云转晴最高气温11℃ 阵风6至7级警惕风寒效应', 'url': 'https://www.stdaily.com/web/gdxw/2025-10/19/content_417555.html', 'content': '气象部门提醒,目前北京处于寒潮蓝色和大风蓝色预警信号中,今天最高气温仅11℃,且风力较大,需警惕风寒效应。明后天,风力减小,但寒冷感仍旧在线,公众需持续做好保暖措施。\n\n责任编辑:陈可轩\n\n相关稿件:\n\n网友评论\n\n最热评论\n\n没有更多评论了\n\n热点\n\n痛别!杨振宁先生逝世\n\n中国民众追忆著名物理学家杨振宁\n\n“中国天眼”立新功 首次捕获恒星黑子区射电暴信号\n\n机器人如何越来越“像人”\n\n封面新闻\n\n 封面新闻丨第40个教师节,致敬这些良师益友\n 亮点纷呈 氛围感拉满!2024年国家网络安全宣传周开启\n 封面新闻丨共赴十年之约 2024数博会引领数字经济发展新潮流\n 全国生态日丨我国生态环境和质量持续改善\n\n精彩视频\n\n 重温杨振宁生前喜爱的一首诗(节选)\n 苍穹有颗杨振宁星\n 北大荒迎初雪,大马力拖拉机首秀上演黑白映画\n\n 深入贯彻中央八项规定精神学习教育\n 创新故事\n 科普一下\n 铭记历史 缅怀先烈\n\n### 友情链接 [...] 时政\n 热点\n 政务\n 深瞳\n 访谈\n 视频\n 国际\n 地方\n 专题\n English\n 滚动\n\n登录 -\n\n所在位置: 中国科技网首页 > 滚动 > 正文\n\n# 今天白天北京多云转晴最高气温11℃ 阵风6至7级警惕风寒效应\n\n2025-10-19 08:22:23 来源: 中国天气网 点击数:\n\n今天(10月19),北京大部晴天在线,最高气温11℃,最低气温接近冰点,风力较大,阵风可达6至7级,公众外出需厚装护体,警惕风寒效应。\n\n受高空槽影响,昨天下午至夜间,北京西部、北部出现小雨或零星小雨,高海拔山区为雪,城区局地短暂零星小雨。此外,受冷空气影响,西部北部地区风力已加大,阵风一度达到6至7级。\n\n今天北京风力较大,阵风可达6至7级,需警惕风寒效应。北京市气象台预计,今天早晨至白天,北京多云转晴,早晨山区有雨夹雪或零星小雪,偏北风3、4级,阵风6至7级,最高气温11℃,夜间晴天为主,最低气温可接近冰点。\n\n明后天,北京天气以晴天间多云为主,风力不大,但气温依旧低迷,最高气温维持在10℃出头,最低气温在5℃以下,仍需做好保暖工作。 [...] 京ICP备06005116号\n 违法和不良信息举报电话:010-58884152\n 京公网安备 110402500060\n\n#### 抱歉,您使用的浏览器版本过低或开启了浏览器兼容模式,这会影响您正常浏览本网页\n\n### 您可以进行以下操作:\n\n## 1.将浏览器切换回极速模式\n\n## 2.点击下面图标升级或更换您的浏览器\n\n## 3.暂不升级,继续浏览\n\n 继续浏览', 'score': 0.80771893}, {'title': '中国气象局-天气预报-城市预报- 北京', 'url': 'https://weather.cma.cn/web/weather/', 'content': '| 气压 | 1012.5hPa | 1011.9hPa | 1010.1hPa | 1008.7hPa | 1009.2hPa | 1009.7hPa | 1009.4hPa | 1008.9hPa |\n| 湿度 | 93.2% | 73.3% | 79.1% | 78.5% | 84.3% | 87% | 90.4% | 92% |\n| 云量 | 0% | 26.6% | 10.1% | 45.4% | 78.5% | 62.5% | 90% | 0% | [...] | | | | | | | | | |\n --- --- --- --- \n| 时间 | 08:00 | 11:00 | 14:00 | 17:00 | 20:00 | 23:00 | 02:00 | 05:00 |\n| 天气 | | | | | | | | |\n| 气温 | 25.9℃ | 27.7℃ | 30.8℃ | 29.4℃ | 27.4℃ | 26℃ | 24.2℃ | 25.4℃ |\n| 降水 | 无降水 | 2.3mm | 2.3mm | 2.3mm | 2.3mm | 无降水 | 无降水 | 1.9mm |\n| 风速 | 3.2m/s | 3.2m/s | 3.3m/s | 2.5m/s | 2.6m/s | 2.6m/s | 2.4m/s | 2.8m/s |\n| 风向 | 西南风 | 西南风 | 西南风 | 西南风 | 西南风 | 西南风 | 西南风 | 东南风 | [...] | | | | | | | | | |\n --- --- --- --- \n| 时间 | 11:00 | 14:00 | 17:00 | 20:00 | 23:00 | 02:00 | 05:00 | 08:00 |\n| 天气 | | | | | | | | |\n| 气温 | 24.2℃ | 28.3℃ | 28.8℃ | 26.1℃ | 23.8℃ | 23.4℃ | 22.2℃ | 25.3℃ |\n| 降水 | 2.3mm | 2.3mm | 2.3mm | 2.3mm | 0.9mm | 无降水 | 0.7mm | 无降水 |\n| 风速 | 3.1m/s | 3.3m/s | 3.3m/s | 2.6m/s | 2.8m/s | 3m/s | 3.3m/s | 3.3m/s |\n| 风向 | 东北风 | 西南风 | 东南风 | 西南风 | 西南风 | 东南风 | 东北风 | 东南风 |', 'score': 0.7811474}, {'title': '2025年10月19日天气预报', 'url': 'https://www.bjmy.gov.cn/sy/tqyb/202510/t20251019_516213.html', 'content': '10月19日07时发布天气预报:今天白天:晴,偏北风3、4级,阵风6级左右,最高气温11℃;今天夜间:晴,偏北风2级左右,最低气温-3℃。\n\n扫一扫在手机上打开页面\n\n打印)\n关闭;window.close();)\n\n 关于我们\n 站点地图\n 建议意见\n 法律声明\n\n 网站二维码\n 邮箱:[email protected]\n\n 政务服务热线:12345\n 官方微信\n\n 官方微博\n\n 宜居密云app\n\n主办:北京市密云区人民政府办公室\n\n承办:北京市密云区政务服务和数据管理局\n\n政府网站标识码 1102280002\n\n京公网安备 11022802010001\n\n您访问的链接即将离开“北京市密云区人民政府”门户网站 是否继续?', 'score': 0.76596165}]今天(10月19日),北京的天气情况如下:
    #
    # - **白天气温**:最高气温11℃,最低气温接近冰点。
    # - **天气状况**:白天多云转晴,夜间晴天为主。
    # - **风力**:偏北风3-4级,阵风可达6-7级,需警惕风寒效应。
    # - **夜间气温**:最低气温可接近-3℃。
    #
    # 气象部门提醒,外出时需注意保暖,尤其是在风大的情况下。
    #
    # 更多详细信息可以参考[中国天气网](https://www.stdaily.com/web/gdxw/2025-10/19/content_417555.html)。
    #
    # > Finished chain.
    # {'input': '查询北京今天的天气情况', 'output': '今天(10月19日),北京的天气情况如下:\n\n- **白天气温**:最高气温11℃,最低气温接近冰点。\n- **天气状况**:白天多云转晴,夜间晴天为主。\n- **风力**:偏北风3-4级,阵风可达6-7级,需警惕风寒效应。\n- **夜间气温**:最低气温可接近-3℃。\n\n气象部门提醒,外出时需注意保暖,尤其是在风大的情况下。\n\n更多详细信息可以参考[中国天气网](https://www.stdaily.com/web/gdxw/2025-10/19/content_417555.html)。'}
  • 二者对比:ZERO_SHOT_REACT_DESCRIPTION和OPENAI_FUNCTIONS

    对比维度 ZERO_SHOT_REACT_DESCRIPTION OPENAI_FUNCTIONS
    底层机制 模型生成文本指令,系统解析后
    调用工具
    模型直接返回JSON格式工具调用
    执行效率 🐢 较低(需多轮文本交互) ⚡️ 更高(单步完成)
    输出可读性 直接显示人类可读的思考过程 需查看结构化日志
    工具参数处理 依赖模型文本描述准确性 自动匹配工具参数结构
    兼容模型 所有文本生成模型 仅GPT-4/Claude 3等新模型
    复杂任务表现 可能因文本解析失败出错 更可靠(结构化保证)

3.1.2 案例2:多工具使用

  • 需求:
    • 计算特斯拉当前股价是多少?
    • 比去年上涨了百分之几?(调用PythonREPL实例的run方法)
  • 多个(两个)工具的选择

方式1:ReAct模式

  • AgentType是 ZERO_SHOT_REACT_DESCRIPTION

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    # 1.导入相关依赖
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType
    from langchain.tools import Tool
    from langchain_community.tools.tavily_search import TavilySearchResults
    from langchain_experimental.utilities.python import PythonREPL

    # 2. 设置 TAVILY_API 密钥
    os.environ['TAVILY_API_KEY'] = os.getenv("TAVILY_API_KEY")

    # 3.定义搜索工具
    search = TavilySearchResults(max_results=3)

    search_tool = Tool(
    name="Search",
    func=search.run,
    description="用于搜索互联网上的信息,特别是股票价格和新闻"
    )

    # 4.定义计算工具
    python_repl = PythonREPL() # LangChain封装的工具类可以进行数学计算

    calc_tool = Tool(
    name="Calculator",
    func=python_repl.run,
    description="用于执行数学计算,例如计算百分比变化"
    )

    # 5. 定义LLM
    llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
    )

    # 6. 创建AgentExecutor执行器对象
    agent_executor = initialize_agent(
    tools=[search_tool, calc_tool],
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True
    )


    # 7. 测试股票价格查询
    query = "比亚迪当前股价是多少?比去年上涨了百分之几?"
    result=agent_executor.invoke(query)
    print(f"查询结果: {result}")
    # > Entering new AgentExecutor chain...
    # 我需要先查找比亚迪当前的股价,然后再查找去年的股价,以计算其上涨的百分比。
    # Action: Search
    # Action Input: "比亚迪当前股价"
    # Observation: [{'title': '比亚迪(002594)_股票价格_行情_走势图—东方财富网', 'url': 'https://quote.eastmoney.com/sz002594.html', 'content': '| | | | | | | | | | | | | | |\n --- --- --- --- --- --- --- |\n| 今开: | 105.40 | 最高: | 106.43 | 涨停: | 116.07 | 换手: | 0.90% | 成交量: | 31.22万 | 市盈(动) ·动态市盈率:26.31 总市值除以全年预估净利润,例如当前一季度净利润1000万,则预估全年净利润4000万 ·静态市盈率:23.93 总市值除以上一年度净利润 ·滚动市盈率:21.49 最新价除以最近4个季度的每股收益 : | 26.31 | 总市值: | 9634亿 |\n| 昨收: | 105.52 | 最低: | 104.70 | 跌停: | 94.97 | 量比: | 0.89 | 成交额: | 33.03亿 | 市净: | 4.56 | 流通市值: | 3685亿 |\n\n比亚迪股份 H股行情\n\n111.300\n\n-0.200 -0.18% [...] 行情报价\n 资金流向\n\n委比:25.43% 委差:1016\n\n| | | | |\n --- --- |\n| 卖五 - \n| 卖四 - \n| 卖三 - \n| 卖二 - \n| 卖一 | 105.68 | 289 | |\n| DK点自动提示涨跌信号! | | | |\n| 买一 | 105.67 | 1053 | |\n| 买二 - \n| 买三 - \n| 买四 - \n| 买五 - \n\n| | |\n --- |\n| 最新:105.67 | 均价:105.79 |\n| 涨幅:0.14% | 涨跌:0.15 |\n| 总手:31.22万 | 金额:33.03亿 |\n| 换手:0.90% | 量比:0.89 |\n| 最高:106.43 | 最低:104.70 |\n| 今开:105.40 | 昨收:105.52 |\n| 涨停:116.07 | 跌停:94.97 |\n| 外盘:15.49万 | 内盘:15.73万 |\n\n分时成交\n\n更多 [...] | | |\n --- |\n| 收益(一):1.004 | PE(动):26.31 |\n| 每股净资产:23.16 | 市净率:4.56 |\n| 总营收:1704亿 | 同比:36.35% |\n| 净利润:91.55亿 | 同比:100.38% |\n| 毛利率:20.07% | 净利率:5.54% |\n| ROE:4.37% | 负债率:70.71% |\n| 总股本: 91.17亿 | 总值:9634亿 |\n| 流通股: 34.87亿 | 流值:3685亿 |\n| 每股未分配利润:11.04元 | |\n| 上市时间:2011-06-30 | |\n\n利润趋势\n\n更多\n\n十大流通股东\n\n更多\n\n| | | | |\n --- --- |\n| 公募 | 私募 | 社保 | QFII |\n| 2家(2) | 0家(0) | 0家(0) | 0家(0) |\n\n| | | |\n --- \n| 股东情况 | 25-03-31 | 25-02-28 |\n| 股东户数 | 20.37万 | 19.93万 |\n| 较上期(%) | 2.22 | -26.55 |', 'score': 0.8800674}, {'title': '比亚迪股份(1211)股票最新价格行情,实时走势图,股价分析预测', 'url': 'https://cn.investing.com/equities/byd-co.', 'content': '| 名称 | 最新价 | 看涨 | 公允价值 |\n --- --- |\n| Aaaaaa Aaaaa Aaaa | 12.24 | +60.67% | 19.67 |\n| Aaaaaaaa Aaaaaaaaaa | 25.25 | +59.67% | 40.32 |\n| Aa Aaaa Aaaa | 6.88 | +58.94% | 10.94 |\n| Aaaaa Aaaa A | 14.46 | +57.31% | 22.75 |\n| Aa Aaa Aaaaaa | 22.33 | +55.41% | 34.70 |\n| Aaa Aaaaaaaaaa | 19.08 | +54.75% | 29.53 |\n| Aaaaa Aaaa Aaaa Aa | 17.16 | +54.60% | 26.53 | [...] 0941\n\n+0.23%\n\nShopify\n\n106.74\n\nSHOP\n\n+5.15%\n\n超微电脑\n\n41.57\n\nSMCI\n\n+3.69%\n\nMicroStrategy\n\n372.20\n\nMSTR\n\n+0.73%\n\n常见问题\n\n### 比亚迪股份(1211)现在的股价是多少?\n\n比亚迪股份现在的股价报407.00\n\n### 比亚迪股份的股票在哪间交易所挂牌交易?\n\n比亚迪股份的股票在香港证券交易所挂牌交易。\n\n### 比亚迪股份的股票代码是什么?\n\n比亚迪股份的股票代码是“1211。”\n\n### 比亚迪股份有分红吗?当前的股息收益率是多少?\n\n比亚迪股份的股息收益率是0.95%。\n\n### 比亚迪股份的市值是多少?\n\n截至今天,比亚迪股份的市值是1.23T。\n\n### 比亚迪股份的每股收益(TTM)是多少?\n\n比亚迪股份的每股收益(TTM)是15.38。\n\n### 比亚迪股份的下一财报日是哪天?\n\n比亚迪股份会在2025年8月31日公布下一份财报。\n\n查找股票交易商\n\n货币 指数 期货 股票\n\n1日\n\n1周\n\n1个月\n\n6个月\n\n1年\n\n5年\n\n最大值\n\n\n\n23,228.00 [...] | 名称 | 最新价 | 看涨 | 公允价值 |\n --- --- |\n| Aaaaaa Aaaaa Aaaa | 12.24 | +60.67% | 19.67 |\n| Aaaaaaaa Aaaaaaaaaa | 25.25 | +59.67% | 40.32 |\n| Aa Aaaa Aaaa | 6.88 | +58.94% | 10.94 |\n| Aaaaa Aaaa A | 14.46 | +57.31% | 22.75 |\n| Aa Aaa Aaaaaa | 22.33 | +55.41% | 34.70 |\n| Aaa Aaaaaaaaaa | 19.08 | +54.75% | 29.53 |\n| Aaaaa Aaaa Aaaa Aa | 17.16 | +54.60% | 26.53 |\n查看完整列表\n\nProPicks AI\n\nAI实力助阵,我们的 优选股票一路领跑,轻松超越标普500\n\n科技巨头\n\n该策略中的股票\n\naaa aaaaaaa aaaa aaa\n\naaa aaaaaaa aaaa aaa\n\naaa aaaaaaa aaaa aaa\n\n解锁策略', 'score': 0.8627572}, {'title': '比亚迪(sz002594)股票价格_股票实时行情_走势图-新浪财经', 'url': 'https://quotes.sina.cn/hs/company/quotes/view/sz002594?from=redirect', 'content': '流通股本\n : 34.87亿\n\n 总股本\n : 91.17亿\n\n 分时\n 五日\n B/S点\n 日K\n 周K\n 月K\n 更多\n + 年线\n + 5分\n + 15分\n + 30分\n + 60分\n\n 成交量\n\n 无\n 成交量\n 量比\n MACD\n BOLL\n RSI\n BBIBOLL\n ROC\n TRIX\n DMA\n EXPMA\n BIAS\n VR\n\n 前复权\n 不复权\n 后复权\n\n 成交量\n MA\n BBIBOLL\n BOLL\n EXPMA\n SAR\n\n 无\n 成交量\n ASI\n BIAS\n BRAR\n CCI\n DMA\n DMI\n EMV\n KDJ\n MACD\n OBV\n PSY\n ROC\n RSI\n SAR\n TRIX\n VR\n WR\n WVAD\n EMV\n\n▲▼\n\nVOL: 7477.20MA10: 2722.14\n\n| | |\n --- |\n| | |\n| 价格 | |\n| 均价 | |\n| 涨跌 | |\n| 成交 | |\n\n五档\n\n明细\n\n卖5\n\n111.66\n\n71\n\n卖4\n\n111.65\n\n80\n\n卖3\n\n111.64\n\n35 [...] +0.95\n+0.86%\n\n未开盘\n08-25\n15:00:00\n\n 今开\n : 111.31\n\n 换手\n : 1.75%\n\n 总值\n : 1.02万亿\n 最高\n : 112.49\n\n 量\n : 61.16万\n\n 流值\n : 3892.11亿\n 最低\n : 110.31\n\n 额\n : 68.03亿\n\n 市盈率TTM\n : 22.69\n 均价\n : 111.23\n\n 量比\n : 1.17\n\n 市盈率静\n : 25.28\n 振幅\n : 1.97%\n\n 内盘\n : 32.33万\n\n 市盈率动\n : 27.79\n 涨停\n : 121.73\n\n 外盘\n : 28.83万\n\n 市净率\n : 4.66\n 跌停\n : 99.59\n\n 委比\n : 66.77%\n\n 市销率TTM\n : 1.24\n 昨收\n : 110.66\n\n 52周最高\n : 137.67\n\n 52周最低\n : 75.78\n 每股收益\n : 1.0041', 'score': 0.838376}]
    # Thought:我找到了比亚迪当前的股价,最新价格为105.67元。接下来,我需要查找去年的股价,以便计算其上涨的百分比。
    # Action: Search
    # Action Input: "比亚迪去年股价"
    # Observation: [{'title': '比亚迪(002594) - 历史行情- 股票行情中心- 搜狐证券', 'url': 'https://q.stock.sohu.com/cn/002594/lshq.shtml', 'content': '| 2025-07-03 | 330.98 | 334.56 | 3.90 | 1.18% | 330.67 | 335.25 | 123498 | 412373.25 | 1.06% |\n| 2025-07-02 | 332.00 | 330.66 | -0.68 | -0.21% | 328.93 | 333.86 | 93270 | 308334.25 | 0.80% |\n| 2025-07-01 | 330.30 | 331.34 | -0.57 | -0.17% | 328.79 | 333.35 | 88518 | 293130.34 | 0.76% |\n| 2025-06-30 | 334.24 | 331.91 | -2.33 | -0.70% | 328.59 | 334.24 | 144003 | 476827.03 | 1.24% |\n| 2025-06-27 | 334.00 | 334.24 | -3.20 | -0.95% | 333.44 | 336.72 | 138617 | 463346.19 | 1.19% | [...] | 2025-08-21 | 107.80 | 107.10 | -1.15 | -1.06% | 107.00 | 108.83 | 449464 | 484367.00 | 1.29% |\n| 2025-08-20 | 107.18 | 108.25 | 0.62 | 0.58% | 106.01 | 108.26 | 385053 | 413045.91 | 1.10% |\n| 2025-08-19 | 108.67 | 107.63 | -0.74 | -0.68% | 107.18 | 108.92 | 389735 | 420534.94 | 1.12% |\n| 2025-08-18 | 105.66 | 108.37 | 2.30 | 2.17% | 105.66 | 109.49 | 619252 | 668076.19 | 1.78% |\n| 2025-08-15 | 105.85 | 106.07 | -0.30 | -0.28% | 105.32 | 106.64 | 361353 | 383104.72 | 1.04% | [...] | 2025-08-14 | 107.37 | 106.37 | -0.46 | -0.43% | 105.79 | 107.50 | 419548 | 447811.91 | 1.20% |\n| 2025-08-13 | 106.29 | 106.83 | 1.16 | 1.10% | 105.84 | 107.65 | 459830 | 490874.47 | 1.32% |\n| 2025-08-12 | 105.40 | 105.67 | 0.15 | 0.14% | 104.70 | 106.43 | 312195 | 330263.91 | 0.90% |\n| 2025-08-11 | 103.88 | 105.52 | 1.59 | 1.53% | 103.23 | 105.66 | 356698 | 374132.97 | 1.02% |\n| 2025-08-08 | 105.00 | 103.93 | -1.40 | -1.33% | 103.91 | 105.03 | 326615 | 340531.75 | 0.94% |', 'score': 0.83549726}, {'title': '比亚迪(002594)股票历史数据:历史行情,价格,走势图表 - 英为财情', 'url': 'https://cn.investing.com/equities/byd-a-historical-data', 'content': '| | 113.90 | 111.67 | 114.00 | 111.07 | 64.25M | +2.27% |\n| | 111.37 | 109.33 | 111.37 | 109.09 | 46.18M | +1.52% |\n| | 109.70 | 109.71 | 109.83 | 108.42 | 41.06M | +0.33% |\n| | 109.34 | 108.33 | 109.57 | 108.03 | 47.07M | +1.33% |\n| | 107.91 | 107.69 | 108.64 | 107.69 | 33.23M | +0.21% |\n| | 107.68 | 106.07 | 108.33 | 106.00 | 48.84M | +1.43% |\n| | 106.16 | 107.97 | 107.97 | 105.85 | 51.69M | -1.67% | [...] | | | | | | | |\n --- --- --- \n| | 105.67 | 105.40 | 106.43 | 104.70 | 31.22M | +0.14% |\n| | 105.52 | 103.88 | 105.66 | 103.23 | 35.67M | +1.53% |\n| | 103.93 | 105.00 | 105.03 | 103.91 | 32.66M | -1.33% |\n| | 105.33 | 104.27 | 106.43 | 104.16 | 42.88M | +0.94% |\n| | 104.35 | 104.86 | 105.00 | 103.90 | 30.56M | -0.49% |\n| | 104.86 | 104.88 | 105.21 | 103.78 | 33.83M | -0.02% |\n| | 104.88 | 104.00 | 105.14 | 102.57 | 41.29M | -0.87% | [...] | 名称 | 最新价 | 看涨 | 公允价值 |\n --- --- |\n| Aaaaaaaa Aaaaaaaa | 8.29 | +62.58% | 13.48 |\n| Aaaaaa Aaaaaaaaaaa | 55.42 | +56.60% | 86.79 |\n| A Aaaaa Aaa | 13.08 | +55.40% | 20.33 |\n| Aaaaaaaaaa | 21.30 | +54.77% | 32.97 |\n| A Aaaaaa Aa | 41.80 | +53.12% | 64.00 |\n| Aaaaaaaa Aaaa Aa | 7.91 | +50.64% | 11.92 |\n| A Aaa Aaaaaaaa Aaa | 23.05 | +50.47% | 34.68 |', 'score': 0.81347597}, {'title': '比亚迪(002594)股本变动历史 - 新浪', 'url': 'https://vip.stock.finance.sina.com.cn/corp/go.php/vCI_StockStructureHistory/stockid/002594/stocktype/LiuTongH.phtml', 'content': '2016年变动日期 | 持有股数 | | 2016-07-01 | 91500万股 | | 2016-07-25 | 91500万股 | | 2016-12-31 | 91500万股 | | 2017年变动日期 | 持有股数 | | 2017-07-03 | 91500万股 | | 2017-07-25 | 91500万股 | | 2018年变动日期 | 持有股数 | | 2018-06-30 | 91500万股 | | 2018-12-31 | 91500万股 | | 2019年变动日期 | 持有股数 | | 2019-06-30 | 91500万股 | | 2019-12-31 | 91500万股 | | 2020年变动日期 | 持有股数 | | 2020-06-30 | 91500万股 | | 2020-12-31 | 91500万股 | | 2021年变动日期 | 持有股数 | | 2021-01-28 | 104800万股 || 2021年变动日期 | 持有股数 | --- | | 2021-06-30 | 104800万股 | | 2021-11-08 |', 'score': 0.80771893}]
    # Thought:我找到了比亚迪去年的股价。根据历史数据,去年(2022年)比亚迪的股价在某个时间点为75.78元。现在我可以计算比亚迪的股价上涨百分比。
    #
    # 当前股价为105.67元,去年的股价为75.78元。计算公式为:
    #
    # \[
    # \text{上涨百分比} = \left( \frac{\text{当前股价} - \text{去年股价}}{\text{去年股价}} \right) \times 100\%
    # \]
    #
    # 将数值代入公式进行计算。
    #
    # Action: Calculator
    # Action Input: "(105.67 - 75.78) / 75.78 * 100"
    # Observation:
    # Thought:我已经计算出比亚迪的股价上涨百分比。
    # Final Answer: 比亚迪当前股价为105.67元,相比去年上涨了39.48%。
    #
    # > Finished chain.
    # 查询结果: {'input': '比亚迪当前股价是多少?比去年上涨了百分之几?', 'output': '比亚迪当前股价为105.67元,相比去年上涨了39.48%。'}

方式2:FUNCATION_CALL模式

  • AgentType是FUNCATION_CALL

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    # 1.导入相关依赖
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType
    from langchain.tools import Tool
    from langchain_community.tools.tavily_search import TavilySearchResults
    from langchain_experimental.utilities.python import PythonREPL

    # 2. 设置 TAVILY_API 密钥
    os.environ['TAVILY_API_KEY'] = os.getenv("TAVILY_API_KEY")

    # 3.定义搜索工具
    search = TavilySearchResults(max_results=3)

    search_tool = Tool(
    name="Search",
    func=search.run,
    description="用于搜索互联网上的信息,特别是股票价格和新闻"
    )

    # 4.定义计算工具
    python_repl = PythonREPL() # LangChain封装的工具类可以进行数学计算

    calc_tool = Tool(
    name="Calculator",
    func=python_repl.run,
    description="用于执行数学计算,例如计算百分比变化"
    )

    # 5. 定义LLM
    llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
    )

    # 6. 创建AgentExecutor执行器对象
    agent_executor = initialize_agent(
    tools=[search_tool, calc_tool],
    llm=llm,
    agent=AgentType.OPENAI_FUNCTIONS, #唯一需要修改的位置
    verbose=True
    )


    # 7. 测试股票价格查询
    query = "比亚迪当前股价是多少?比去年上涨了百分之几?"
    result=agent_executor.invoke(query)
    print(f"查询结果: {result}")
    # > Entering new AgentExecutor chain...
    #
    # Invoking: `Search` with `比亚迪当前股价`
    #
    #
    # [{'title': '比亚迪(002594)_股票价格_行情_走势图—东方财富网', 'url': 'https://quote.eastmoney.com/sz002594.html', 'content': '| | | | | | | | | | | | | | |\n --- --- --- --- --- --- --- |\n| 今开: | 105.40 | 最高: | 106.43 | 涨停: | 116.07 | 换手: | 0.90% | 成交量: | 31.22万 | 市盈(动) ·动态市盈率:26.31 总市值除以全年预估净利润,例如当前一季度净利润1000万,则预估全年净利润4000万 ·静态市盈率:23.93 总市值除以上一年度净利润 ·滚动市盈率:21.49 最新价除以最近4个季度的每股收益 : | 26.31 | 总市值: | 9634亿 |\n| 昨收: | 105.52 | 最低: | 104.70 | 跌停: | 94.97 | 量比: | 0.89 | 成交额: | 33.03亿 | 市净: | 4.56 | 流通市值: | 3685亿 |\n\n比亚迪股份 H股行情\n\n111.300\n\n-0.200 -0.18% [...] 行情报价\n 资金流向\n\n委比:25.43% 委差:1016\n\n| | | | |\n --- --- |\n| 卖五 - \n| 卖四 - \n| 卖三 - \n| 卖二 - \n| 卖一 | 105.68 | 289 | |\n| DK点自动提示涨跌信号! | | | |\n| 买一 | 105.67 | 1053 | |\n| 买二 - \n| 买三 - \n| 买四 - \n| 买五 - \n\n| | |\n --- |\n| 最新:105.67 | 均价:105.79 |\n| 涨幅:0.14% | 涨跌:0.15 |\n| 总手:31.22万 | 金额:33.03亿 |\n| 换手:0.90% | 量比:0.89 |\n| 最高:106.43 | 最低:104.70 |\n| 今开:105.40 | 昨收:105.52 |\n| 涨停:116.07 | 跌停:94.97 |\n| 外盘:15.49万 | 内盘:15.73万 |\n\n分时成交\n\n更多 [...] | | |\n --- |\n| 收益(一):1.004 | PE(动):26.31 |\n| 每股净资产:23.16 | 市净率:4.56 |\n| 总营收:1704亿 | 同比:36.35% |\n| 净利润:91.55亿 | 同比:100.38% |\n| 毛利率:20.07% | 净利率:5.54% |\n| ROE:4.37% | 负债率:70.71% |\n| 总股本: 91.17亿 | 总值:9634亿 |\n| 流通股: 34.87亿 | 流值:3685亿 |\n| 每股未分配利润:11.04元 | |\n| 上市时间:2011-06-30 | |\n\n利润趋势\n\n更多\n\n十大流通股东\n\n更多\n\n| | | | |\n --- --- |\n| 公募 | 私募 | 社保 | QFII |\n| 2家(2) | 0家(0) | 0家(0) | 0家(0) |\n\n| | | |\n --- \n| 股东情况 | 25-03-31 | 25-02-28 |\n| 股东户数 | 20.37万 | 19.93万 |\n| 较上期(%) | 2.22 | -26.55 |', 'score': 0.8800674}, {'title': '比亚迪股份(1211)股票最新价格行情,实时走势图,股价分析预测', 'url': 'https://cn.investing.com/equities/byd-co.', 'content': '| 名称 | 最新价 | 看涨 | 公允价值 |\n --- --- |\n| Aaaaaa Aaaaa Aaaa | 12.24 | +60.67% | 19.67 |\n| Aaaaaaaa Aaaaaaaaaa | 25.25 | +59.67% | 40.32 |\n| Aa Aaaa Aaaa | 6.88 | +58.94% | 10.94 |\n| Aaaaa Aaaa A | 14.46 | +57.31% | 22.75 |\n| Aa Aaa Aaaaaa | 22.33 | +55.41% | 34.70 |\n| Aaa Aaaaaaaaaa | 19.08 | +54.75% | 29.53 |\n| Aaaaa Aaaa Aaaa Aa | 17.16 | +54.60% | 26.53 | [...] 0941\n\n+0.23%\n\nShopify\n\n106.74\n\nSHOP\n\n+5.15%\n\n超微电脑\n\n41.57\n\nSMCI\n\n+3.69%\n\nMicroStrategy\n\n372.20\n\nMSTR\n\n+0.73%\n\n常见问题\n\n### 比亚迪股份(1211)现在的股价是多少?\n\n比亚迪股份现在的股价报407.00\n\n### 比亚迪股份的股票在哪间交易所挂牌交易?\n\n比亚迪股份的股票在香港证券交易所挂牌交易。\n\n### 比亚迪股份的股票代码是什么?\n\n比亚迪股份的股票代码是“1211。”\n\n### 比亚迪股份有分红吗?当前的股息收益率是多少?\n\n比亚迪股份的股息收益率是0.95%。\n\n### 比亚迪股份的市值是多少?\n\n截至今天,比亚迪股份的市值是1.23T。\n\n### 比亚迪股份的每股收益(TTM)是多少?\n\n比亚迪股份的每股收益(TTM)是15.38。\n\n### 比亚迪股份的下一财报日是哪天?\n\n比亚迪股份会在2025年8月31日公布下一份财报。\n\n查找股票交易商\n\n货币 指数 期货 股票\n\n1日\n\n1周\n\n1个月\n\n6个月\n\n1年\n\n5年\n\n最大值\n\n\n\n23,228.00 [...] | 名称 | 最新价 | 看涨 | 公允价值 |\n --- --- |\n| Aaaaaa Aaaaa Aaaa | 12.24 | +60.67% | 19.67 |\n| Aaaaaaaa Aaaaaaaaaa | 25.25 | +59.67% | 40.32 |\n| Aa Aaaa Aaaa | 6.88 | +58.94% | 10.94 |\n| Aaaaa Aaaa A | 14.46 | +57.31% | 22.75 |\n| Aa Aaa Aaaaaa | 22.33 | +55.41% | 34.70 |\n| Aaa Aaaaaaaaaa | 19.08 | +54.75% | 29.53 |\n| Aaaaa Aaaa Aaaa Aa | 17.16 | +54.60% | 26.53 |\n查看完整列表\n\nProPicks AI\n\nAI实力助阵,我们的 优选股票一路领跑,轻松超越标普500\n\n科技巨头\n\n该策略中的股票\n\naaa aaaaaaa aaaa aaa\n\naaa aaaaaaa aaaa aaa\n\naaa aaaaaaa aaaa aaa\n\n解锁策略', 'score': 0.8627572}, {'title': '比亚迪(sz002594)股票价格_股票实时行情_走势图-新浪财经', 'url': 'https://quotes.sina.cn/hs/company/quotes/view/sz002594?from=redirect', 'content': '流通股本\n : 34.87亿\n\n 总股本\n : 91.17亿\n\n 分时\n 五日\n B/S点\n 日K\n 周K\n 月K\n 更多\n + 年线\n + 5分\n + 15分\n + 30分\n + 60分\n\n 成交量\n\n 无\n 成交量\n 量比\n MACD\n BOLL\n RSI\n BBIBOLL\n ROC\n TRIX\n DMA\n EXPMA\n BIAS\n VR\n\n 前复权\n 不复权\n 后复权\n\n 成交量\n MA\n BBIBOLL\n BOLL\n EXPMA\n SAR\n\n 无\n 成交量\n ASI\n BIAS\n BRAR\n CCI\n DMA\n DMI\n EMV\n KDJ\n MACD\n OBV\n PSY\n ROC\n RSI\n SAR\n TRIX\n VR\n WR\n WVAD\n EMV\n\n▲▼\n\nVOL: 7477.20MA10: 2722.14\n\n| | |\n --- |\n| | |\n| 价格 | |\n| 均价 | |\n| 涨跌 | |\n| 成交 | |\n\n五档\n\n明细\n\n卖5\n\n111.66\n\n71\n\n卖4\n\n111.65\n\n80\n\n卖3\n\n111.64\n\n35 [...] +0.95\n+0.86%\n\n未开盘\n08-25\n15:00:00\n\n 今开\n : 111.31\n\n 换手\n : 1.75%\n\n 总值\n : 1.02万亿\n 最高\n : 112.49\n\n 量\n : 61.16万\n\n 流值\n : 3892.11亿\n 最低\n : 110.31\n\n 额\n : 68.03亿\n\n 市盈率TTM\n : 22.69\n 均价\n : 111.23\n\n 量比\n : 1.17\n\n 市盈率静\n : 25.28\n 振幅\n : 1.97%\n\n 内盘\n : 32.33万\n\n 市盈率动\n : 27.79\n 涨停\n : 121.73\n\n 外盘\n : 28.83万\n\n 市净率\n : 4.66\n 跌停\n : 99.59\n\n 委比\n : 66.77%\n\n 市销率TTM\n : 1.24\n 昨收\n : 110.66\n\n 52周最高\n : 137.67\n\n 52周最低\n : 75.78\n 每股收益\n : 1.0041', 'score': 0.838376}]
    # Invoking: `Search` with `比亚迪去年股价`
    #
    #
    # [{'title': '比亚迪(002594) - 历史行情- 股票行情中心- 搜狐证券', 'url': 'https://q.stock.sohu.com/cn/002594/lshq.shtml', 'content': '| 2025-07-03 | 330.98 | 334.56 | 3.90 | 1.18% | 330.67 | 335.25 | 123498 | 412373.25 | 1.06% |\n| 2025-07-02 | 332.00 | 330.66 | -0.68 | -0.21% | 328.93 | 333.86 | 93270 | 308334.25 | 0.80% |\n| 2025-07-01 | 330.30 | 331.34 | -0.57 | -0.17% | 328.79 | 333.35 | 88518 | 293130.34 | 0.76% |\n| 2025-06-30 | 334.24 | 331.91 | -2.33 | -0.70% | 328.59 | 334.24 | 144003 | 476827.03 | 1.24% |\n| 2025-06-27 | 334.00 | 334.24 | -3.20 | -0.95% | 333.44 | 336.72 | 138617 | 463346.19 | 1.19% | [...] | 2025-08-21 | 107.80 | 107.10 | -1.15 | -1.06% | 107.00 | 108.83 | 449464 | 484367.00 | 1.29% |\n| 2025-08-20 | 107.18 | 108.25 | 0.62 | 0.58% | 106.01 | 108.26 | 385053 | 413045.91 | 1.10% |\n| 2025-08-19 | 108.67 | 107.63 | -0.74 | -0.68% | 107.18 | 108.92 | 389735 | 420534.94 | 1.12% |\n| 2025-08-18 | 105.66 | 108.37 | 2.30 | 2.17% | 105.66 | 109.49 | 619252 | 668076.19 | 1.78% |\n| 2025-08-15 | 105.85 | 106.07 | -0.30 | -0.28% | 105.32 | 106.64 | 361353 | 383104.72 | 1.04% | [...] | 2025-08-14 | 107.37 | 106.37 | -0.46 | -0.43% | 105.79 | 107.50 | 419548 | 447811.91 | 1.20% |\n| 2025-08-13 | 106.29 | 106.83 | 1.16 | 1.10% | 105.84 | 107.65 | 459830 | 490874.47 | 1.32% |\n| 2025-08-12 | 105.40 | 105.67 | 0.15 | 0.14% | 104.70 | 106.43 | 312195 | 330263.91 | 0.90% |\n| 2025-08-11 | 103.88 | 105.52 | 1.59 | 1.53% | 103.23 | 105.66 | 356698 | 374132.97 | 1.02% |\n| 2025-08-08 | 105.00 | 103.93 | -1.40 | -1.33% | 103.91 | 105.03 | 326615 | 340531.75 | 0.94% |', 'score': 0.83549726}, {'title': '比亚迪(002594)股票历史数据:历史行情,价格,走势图表 - 英为财情', 'url': 'https://cn.investing.com/equities/byd-a-historical-data', 'content': '| | 113.90 | 111.67 | 114.00 | 111.07 | 64.25M | +2.27% |\n| | 111.37 | 109.33 | 111.37 | 109.09 | 46.18M | +1.52% |\n| | 109.70 | 109.71 | 109.83 | 108.42 | 41.06M | +0.33% |\n| | 109.34 | 108.33 | 109.57 | 108.03 | 47.07M | +1.33% |\n| | 107.91 | 107.69 | 108.64 | 107.69 | 33.23M | +0.21% |\n| | 107.68 | 106.07 | 108.33 | 106.00 | 48.84M | +1.43% |\n| | 106.16 | 107.97 | 107.97 | 105.85 | 51.69M | -1.67% | [...] | | | | | | | |\n --- --- --- \n| | 105.67 | 105.40 | 106.43 | 104.70 | 31.22M | +0.14% |\n| | 105.52 | 103.88 | 105.66 | 103.23 | 35.67M | +1.53% |\n| | 103.93 | 105.00 | 105.03 | 103.91 | 32.66M | -1.33% |\n| | 105.33 | 104.27 | 106.43 | 104.16 | 42.88M | +0.94% |\n| | 104.35 | 104.86 | 105.00 | 103.90 | 30.56M | -0.49% |\n| | 104.86 | 104.88 | 105.21 | 103.78 | 33.83M | -0.02% |\n| | 104.88 | 104.00 | 105.14 | 102.57 | 41.29M | -0.87% | [...] | 名称 | 最新价 | 看涨 | 公允价值 |\n --- --- |\n| Aaaaaaaa Aaaaaaaa | 8.29 | +62.58% | 13.48 |\n| Aaaaaa Aaaaaaaaaaa | 55.42 | +56.60% | 86.79 |\n| A Aaaaa Aaa | 13.08 | +55.40% | 20.33 |\n| Aaaaaaaaaa | 21.30 | +54.77% | 32.97 |\n| A Aaaaaa Aa | 41.80 | +53.12% | 64.00 |\n| Aaaaaaaa Aaaa Aa | 7.91 | +50.64% | 11.92 |\n| A Aaa Aaaaaaaa Aaa | 23.05 | +50.47% | 34.68 |', 'score': 0.81347597}, {'title': '比亚迪(002594)股本变动历史 - 新浪', 'url': 'https://vip.stock.finance.sina.com.cn/corp/go.php/vCI_StockStructureHistory/stockid/002594/stocktype/LiuTongH.phtml', 'content': '2016年变动日期 | 持有股数 | | 2016-07-01 | 91500万股 | | 2016-07-25 | 91500万股 | | 2016-12-31 | 91500万股 | | 2017年变动日期 | 持有股数 | | 2017-07-03 | 91500万股 | | 2017-07-25 | 91500万股 | | 2018年变动日期 | 持有股数 | | 2018-06-30 | 91500万股 | | 2018-12-31 | 91500万股 | | 2019年变动日期 | 持有股数 | | 2019-06-30 | 91500万股 | | 2019-12-31 | 91500万股 | | 2020年变动日期 | 持有股数 | | 2020-06-30 | 91500万股 | | 2020-12-31 | 91500万股 | | 2021年变动日期 | 持有股数 | | 2021-01-28 | 104800万股 || 2021年变动日期 | 持有股数 | --- | | 2021-06-30 | 104800万股 | | 2021-11-08 |', 'score': 0.80771893}]
    # Invoking: `Calculator` with `(105.67 - 75.78) / 75.78 * 100`
    #
    #
    # 比亚迪当前股价为 **105.67 元**。根据去年最低价 **75.78 元** 计算,比亚迪的股价上涨了约 **39.4%**。
    #
    # > Finished chain.
    # 查询结果: {'input': '比亚迪当前股价是多少?比去年上涨了百分之几?', 'output': '比亚迪当前股价为 **105.67 元**。根据去年最低价 **75.78 元** 计算,比亚迪的股价上涨了约 **39.4%**。'}

3.1.3 案例3:自定义函数与工具

  • 需求:计算3的平方,Agent自动调用工具完成

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    from langchain.agents import initialize_agent, AgentType, Tool
    from langchain_openai import ChatOpenAI
    import langchain


    # 1. 定义工具 - 计算器(要求字符串输入)
    def simple_calculator(expression: str) -> str:
    """
    基础数学计算工具,支持加减乘除和幂运算
    参数:
    expression: 数学表达式字符串,如 "3+5" 或 "2**3"
    返回:
    计算结果字符串或错误信息
    """
    print(f"\n[工具调用] 计算表达式: {expression}")

    print("只因为在人群中多看了你一眼,确认下你调用了我^_^")
    return str(eval(expression))


    # 2. 创建工具对象
    math_calculator_tool = Tool(
    name="Math_Calculator", # 工具名称(Agent将根据名称选择工具)
    func=simple_calculator, # 工具调用的函数
    description="用于数学计算,输入必须是纯数学表达式(如'3+5'或'3**2'表示平方)。不支持字母或特殊符号" # 关键:明确输入格式要求
    )

    # 3. 初始化大模型
    llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
    )

    # 4. 初始化AgentExecutor(使用零样本React模式、增加超时设置)
    agent_executor = initialize_agent(
    tools=[math_calculator_tool], # 可用的工具列表
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, # 简单指令模式
    verbose=True # 关键参数!在控制台显示详细的推理过程
    )

    # 5. 测试工具调用(添加异常捕获)
    print("=== 测试:正常工具调用 ===")
    response = agent_executor.invoke("计算3的平方") # 向Agent提问
    print("最终答案:", response)

3.2 通用方式

  • 需求:今天北京的天气怎么样??

方式1:FUNCATION_CALL模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
# 获取Tavily搜索的实例
from langchain_openai import ChatOpenAI
from langchain.agents import initialize_agent, AgentType, create_tool_calling_agent, AgentExecutor
from langchain.tools import Tool
import os
import dotenv
from langchain_openai import ChatOpenAI
from langchain_community.tools.tavily_search import TavilySearchResults
dotenv.load_dotenv()

# 读取配置文件的信息
os.environ['TAVILY_API_KEY'] = os.getenv("TAVILY_API_KEY")

# 获取Tavily搜索工具的实例
search = TavilySearchResults(max_results=3)

# 获取一个搜索的工具
# 使用Tool
search_tool = Tool(
func=search.run,
name="Search",
description="用于检索互联网上的信息",
)


# 获取大语言模型
os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
llm = ChatOpenAI(
model="gpt-4o-mini",
temperature=0,
)
# 提供提示词模板(以ChatPromptTemplate为例)
prompt_template = ChatPromptTemplate.from_messages([
("system","你是一个乐于助人的ai助手,根据用户的提问,必要时调用Search工具,使用互联网检索数据"),
("human","{input}"),
("system","{agent_scratchpad}"),
# ("placeholder","{agent_scratchpad}")
])

# 获取Agent的实例:create_tool_calling_agent()
agent = create_tool_calling_agent(
llm=llm,
prompt=prompt_template,
tools=[search_tool]
)

# 获取AgentExecutor的实例
agent_executor = AgentExecutor(
agent=agent,
tools=[search_tool],
verbose=True,
)


# 通过AgentExecutor的实例调用invoke(),得到响应
result = agent_executor.invoke({"input":"查询今天北京的天气情况"})

# 处理响应
print(result)

注意:agent_scratchpad必须声明,它用于存储和传递Agent的思考过程。比如,在调用链式工具时(如先搜索天气再推荐行程),agent_scratchpad 保留所有历史步骤,避免上下文丢失。format方法会将intermediate_steps转换为特定格式的字符串,并赋值给agent_scratchpad变量。如果不传递intermediate_steps参数,会导致KeyError: ‘intermediate_steps’错误。

方式2:REACT模式

  • 体会:使用PromptTemplate,提示词要体现可以使用的工具、用户输入和agent_scratchpad。

  • 远程的提示词模版通过https://smith.langchain.com/hub/hwchase17获取。举例:https://smith.langchain.com/hub/hwchase17/react,这个模板是专为ReAct模式设计的提示模板。这个模板中已经有聊天对话键**tools** 、 tool_namesagent_scratchpad

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    from langchain.agents import create_react_agent
    from langchain_core.prompts import ChatPromptTemplate
    # 获取Tavily搜索的实例
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType, create_tool_calling_agent, AgentExecutor
    from langchain.tools import Tool
    import os
    import dotenv
    from langchain_openai import ChatOpenAI
    from langchain_community.tools.tavily_search import TavilySearchResults
    dotenv.load_dotenv()

    # 读取配置文件的信息
    os.environ['TAVILY_API_KEY'] = os.getenv("TAVILY_API_KEY")

    # 获取Tavily搜索工具的实例
    search = TavilySearchResults(max_results=3)

    # 获取一个搜索的工具
    # 使用Tool
    search_tool = Tool(
    func=search.run,
    name="Search",
    description="用于检索互联网上的信息",
    )


    # 获取大语言模型
    os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
    os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
    llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
    )
    # 提供提示词模板(以PromptTemplate为例)
    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_template = PromptTemplate.from_template(
    template=template,
    )

    # 获取Agent的实例:create_react_agent()
    agent = create_react_agent(
    llm=llm,
    prompt=prompt_template,
    tools=[search_tool]
    )

    # 获取AgentExecutor的实例
    agent_executor = AgentExecutor(
    agent=agent,
    tools=[search_tool],
    verbose=True,
    )


    # 通过AgentExecutor的实例调用invoke(),得到响应
    result = agent_executor.invoke({"input":"查询今天北京的天气情况"})

    # 处理响应
    print(result)

    上述也可以改写为:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    from langchain import hub
    from langchain.agents import create_react_agent
    from langchain_core.prompts import ChatPromptTemplate
    # 获取Tavily搜索的实例
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType, create_tool_calling_agent, AgentExecutor
    from langchain.tools import Tool
    import os
    import dotenv
    from langchain_openai import ChatOpenAI
    from langchain_community.tools.tavily_search import TavilySearchResults
    dotenv.load_dotenv()

    # 读取配置文件的信息
    os.environ['TAVILY_API_KEY'] = os.getenv("TAVILY_API_KEY")

    # 获取Tavily搜索工具的实例
    search = TavilySearchResults(max_results=3)

    # 获取一个搜索的工具
    # 使用Tool
    search_tool = Tool(
    func=search.run,
    name="Search",
    description="用于检索互联网上的信息",
    )


    # 获取大语言模型
    os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
    os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
    llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
    )
    # 使用LangChain Hub中的官方ReAct提示模板
    prompt_template = hub.pull("hwchase17/react")


    # 获取Agent的实例:create_react_agent()
    agent = create_react_agent(
    llm=llm,
    prompt=prompt_template,
    tools=[search_tool]
    )

    # 获取AgentExecutor的实例
    agent_executor = AgentExecutor(
    agent=agent,
    tools=[search_tool],
    verbose=True,
    )


    # 通过AgentExecutor的实例调用invoke(),得到响应
    result = agent_executor.invoke({"input":"查询今天北京的天气情况"})

    # 处理响应
    print(result)
  • 体会2:使用ChatPromptTemplate。提示词中需要体现使用的工具、用户输入和agent_scratchpad。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    from langchain.agents import create_react_agent
    from langchain_core.prompts import ChatPromptTemplate
    # 获取Tavily搜索的实例
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType, create_tool_calling_agent, AgentExecutor
    from langchain.tools import Tool
    import os
    import dotenv
    from langchain_openai import ChatOpenAI
    from langchain_community.tools.tavily_search import TavilySearchResults
    dotenv.load_dotenv()

    # 读取配置文件的信息
    os.environ['TAVILY_API_KEY'] = os.getenv("TAVILY_API_KEY")

    # 获取Tavily搜索工具的实例
    search = TavilySearchResults(max_results=3)

    # 获取一个搜索的工具
    # 使用Tool
    search_tool = Tool(
    func=search.run,
    name="Search",
    description="用于检索互联网上的信息",
    )


    # 获取大语言模型
    os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
    os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
    llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
    )
    # 提供提示词模板(以ChatPromptTemplate为例)
    system_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!"""

    prompt_template = ChatPromptTemplate.from_messages([
    ("system",system_template),
    ("human","{input}"),
    ("system","{agent_scratchpad}"),
    ])

    # 获取Agent的实例:create_react_agent()
    agent = create_react_agent(
    llm=llm,
    prompt=prompt_template,
    tools=[search_tool]
    )

    # 获取AgentExecutor的实例
    agent_executor = AgentExecutor(
    agent=agent,
    tools=[search_tool],
    verbose=True,
    )


    # 通过AgentExecutor的实例调用invoke(),得到响应
    result = agent_executor.invoke({"input":"查询今天北京的天气情况"})

    # 处理响应
    print(result)
  • 小结:

    • 传统方式,相较于通用方式来讲,不用提供提示词模板。
    • 对于通用方式来讲
      • FUNCTION_CALL模式:在创建Agent时,推荐大家使用ChatPromptTemplate
      • ReAct模式:在创建Agent时,大家可以使用ChatPromptTemplate、PromptTemplate。但相较来讲,推荐大家使用PromptTemplate

4、Agent嵌入记忆组件

4.1 传统方式

  • 比如:北京明天的天气怎么样?上海呢? (通过两次对话实现)

  • 举例:以REACT模式为例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    from langchain.memory import ConversationBufferMemory
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType
    from langchain.tools import Tool
    import os
    import dotenv
    from langchain_openai import ChatOpenAI
    from langchain_community.tools.tavily_search import TavilySearchResults
    dotenv.load_dotenv()

    # 读取配置文件的信息
    os.environ['TAVILY_API_KEY'] = os.getenv("TAVILY_API_KEY")

    # 获取Tavily搜索工具的实例
    search = TavilySearchResults(max_results=3)

    # 获取一个搜索的工具
    search_tool = Tool(
    func=search.run,
    name="Search",
    description="用于检索互联网上的信息",
    )


    # 获取大语言模型
    os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
    os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
    llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
    )

    # 获取一个记忆的实例:ConversationBufferMemory
    memory = ConversationBufferMemory(
    return_messages=True,
    memory_key="chat_history" #此时必须设置memory_key,且值为chat_history。因为提示词模板中使用的是chat_history。二者必须一致!
    )

    # 获取Agent的实例
    agent = AgentType.CONVERSATIONAL_REACT_DESCRIPTION

    # 获取AgentExecutor的实例
    agent_executor = initialize_agent(
    tools = [search_tool],
    llm = llm,
    agent = agent,
    verbose = True, # 显示详细的日志信息
    memory = memory,
    )


    # 通过AgentExecutor 调用invoke(),并得到响应
    result = agent_executor.invoke("查询北京今天的天气情况")


    # 处理响应数据
    print(result)

    result = agent_executor.invoke("上海呢?")
    # 处理响应数据
    print(result)
  • 上述执行可能会报错。错误原因:

    • 使用 AgentType.CONVERSATIONAL_REACT_DESCRIPTION,它要求 LLM 的响应必须遵循严格的格式(如包含 Thought:Action: 等标记)。
    • 但 LLM 直接返回了自由文本(非结构化),导致解析器无法识别。
    • 修改:任务不变,添加handle_parsing_errors=True
    场景 handle_parsing_errors=True handle_parsing_errors=False
    解析成功 正常执行 正常执行
    解析失败 自动修复或降级响应 直接抛出异常
    适用场景 生产环境(保证鲁棒性) 开发调试(快速发现问题)

4.2 通用方式

  • 通用方式,相较于传统方式,可以提供自定义的提示词模板。

举例1:FUNCATION_CALL模式

  • 如果使用的是FUNCTION_CALL方式,则创建Agent时,推荐使用ChatPromptTemplate。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    from langchain.memory import ConversationBufferMemory
    from langchain_core.prompts import ChatPromptTemplate, PromptTemplate
    # 获取Tavily搜索的实例
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType, create_tool_calling_agent, AgentExecutor
    from langchain.tools import Tool
    import os
    import dotenv
    from langchain_openai import ChatOpenAI
    from langchain_community.tools.tavily_search import TavilySearchResults
    dotenv.load_dotenv()

    # 读取配置文件的信息
    os.environ['TAVILY_API_KEY'] = os.getenv("TAVILY_API_KEY")

    # 获取Tavily搜索工具的实例
    search = TavilySearchResults(max_results=3)

    # 获取一个搜索的工具
    # 使用Tool
    search_tool = Tool(
    func=search.run,
    name="Search",
    description="用于检索互联网上的信息",
    )


    # 获取大语言模型
    os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
    os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
    llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
    )


    # 提供提示词模板(以ChatPromptTemplate为例)
    prompt_template = ChatPromptTemplate.from_messages([
    ("system","你是一个乐于助人的ai助手,根据用户的提问,必要时调用Search工具,使用互联网检索数据"),
    ("system","{agent_scratchpad}"),
    ("system","{chat_history}"), #添加一个chat_history的变量,用于记录上下文的记忆
    ("human","{input}"),
    # ("placeholder","{agent_scratchpad}")
    ])

    # 提供记忆的实例:ConversationBufferMemory
    memory = ConversationBufferMemory(
    return_messages=True,
    memory_key="chat_history", #此值需要与提示词模板中的记录记忆的变量同名
    )

    # 获取Agent的实例:create_tool_calling_agent()
    agent = create_tool_calling_agent(
    llm=llm,
    prompt=prompt_template,
    tools=[search_tool]
    )

    # 获取AgentExecutor的实例
    agent_executor = AgentExecutor(
    agent=agent,
    tools=[search_tool],
    verbose=True,
    memory=memory,
    )


    # 通过AgentExecutor的实例调用invoke(),得到响应
    result = agent_executor.invoke({"input":"查询今天北京的天气情况"})

    # 处理响应
    print(result)

举例2:ReAct模式

  • 举例1:使用网络上现成的提示词模板结构

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    from langchain import hub
    from langchain.agents import create_react_agent
    from langchain_core.prompts import ChatPromptTemplate
    # 获取Tavily搜索的实例
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType, create_tool_calling_agent, AgentExecutor
    from langchain.tools import Tool
    import os
    import dotenv
    from langchain_openai import ChatOpenAI
    from langchain_community.tools.tavily_search import TavilySearchResults
    dotenv.load_dotenv()

    # 读取配置文件的信息
    os.environ['TAVILY_API_KEY'] = os.getenv("TAVILY_API_KEY")

    # 获取Tavily搜索工具的实例
    search = TavilySearchResults(max_results=3)

    # 获取一个搜索的工具
    # 使用Tool
    search_tool = Tool(
    func=search.run,
    name="Search",
    description="用于检索互联网上的信息",
    )


    # 获取大语言模型
    os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
    os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
    llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
    )
    # 使用LangChain Hub中的官方ReAct提示模板
    prompt_template = hub.pull("hwchase17/react-chat")

    # 提供记忆的实例
    memory = ConversationBufferMemory(
    return_messages=True,
    memory_key="chat_history",
    )

    # 获取Agent的实例:create_react_agent()
    agent = create_react_agent(
    llm=llm,
    prompt=prompt_template,
    tools=[search_tool]
    )

    # 获取AgentExecutor的实例
    agent_executor = AgentExecutor(
    agent=agent,
    tools=[search_tool],
    verbose=True,
    memory=memory,
    )


    # 通过AgentExecutor的实例调用invoke(),得到响应
    result = agent_executor.invoke({"input":"查询2025年9月9日北京的天气情况"})

    # 处理响应
    print(result)

    result = agent_executor.invoke({"input":"上海的呢?"})

    print(result)
  • 举例2:自定义提示词模板

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    from langchain import hub
    from langchain.agents import create_react_agent
    from langchain_core.prompts import ChatPromptTemplate
    # 获取Tavily搜索的实例
    from langchain_openai import ChatOpenAI
    from langchain.agents import initialize_agent, AgentType, create_tool_calling_agent, AgentExecutor
    from langchain.tools import Tool
    import os
    import dotenv
    from langchain_openai import ChatOpenAI
    from langchain_community.tools.tavily_search import TavilySearchResults
    dotenv.load_dotenv()

    # 读取配置文件的信息
    os.environ['TAVILY_API_KEY'] = os.getenv("TAVILY_API_KEY")

    # 获取Tavily搜索工具的实例
    search = TavilySearchResults(max_results=3)

    # 获取一个搜索的工具
    # 使用Tool
    search_tool = Tool(
    func=search.run,
    name="Search",
    description="用于检索互联网上的信息",
    )


    # 获取大语言模型
    os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
    os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
    llm = ChatOpenAI(
    model="gpt-4o-mini",
    temperature=0,
    )
    # 自定义提示词模板
    template = """Assistant is a large language model trained by OpenAI.

    Assistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.

    Assistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.

    Overall, Assistant is a powerful tool that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist.

    TOOLS:
    ------

    Assistant has access to the following tools:

    {tools}

    To use a tool, please use the following format:

    ```
    Thought: Do I need to use a tool? Yes
    Action: the action to take, should be one of [{tool_names}]
    Action Input: the input to the action
    Observation: the result of the action
    ```

    When you have a response to say to the Human, or if you do not need to use a tool, you MUST use the format:

    ```
    Thought: Do I need to use a tool? No
    Final Answer: [your response here]
    ```

    Begin!

    Previous conversation history:
    {chat_history}

    New input: {input}
    {agent_scratchpad}
    """
    prompt_template = PromptTemplate.from_template(
    template=template,
    )

    # 提供记忆的实例
    memory = ConversationBufferMemory(
    return_messages=True,
    memory_key="chat_history",
    )

    # 获取Agent的实例:create_react_agent()
    agent = create_react_agent(
    llm=llm,
    prompt=prompt_template,
    tools=[search_tool]
    )

    # 获取AgentExecutor的实例
    agent_executor = AgentExecutor(
    agent=agent,
    tools=[search_tool],
    verbose=True,
    memory=memory,
    handle_parsing_errors=True,
    )


    # 通过AgentExecutor的实例调用invoke(),得到响应
    result = agent_executor.invoke({"input":"查询2025年9月9日北京的天气情况"})

    # 处理响应
    print(result)

    result = agent_executor.invoke({"input":"上海的呢?"})

    print(result)