LangChain内置工具包和联网搜索

目录

一、什么是智能体?工具包又是什么?

二、智能体(Agent)的出现是为了解决哪些问题?

三、LangChain里面创建工具方式

 3.1  @tool 装饰器:用来定义一个简单的工具函数,, 可以直接给函数加上这个装饰器,让函数成为可调用的工具

3.2 StructuredTool

3.3 继承BaseTool子类进行创建工具 

四、LangChain工具包

4.1 如何使用内置工具包【联网搜索例子】

4.2 内置工具包整合LLM

4.3工具包调用Log

五、LangChain智能体执行引擎AgentExecutor


导读:本文围绕如何利用LangChain构建一个能够通过自然语言与MySQL数据库交互的AI智能体展开,详细介绍了从问题理解到SQL生成、执行再到结果解析的完整流程。文章首先强调了该智能体的核心能力:将用户提出的自然语言问题转化为结构化查询语句(如“统计每个地区的销量”),并自动连接数据库执行查询。在此基础上,系统还能将原始数据以更易理解的方式呈现给用户(例如将数值结果转换为自然语言描述)。此外,智能体具备自动修正SQL语法错误的能力,提高了系统的鲁棒性和用户体验。技术实现上使用了LangChain中的SQLDatabaseToolkitcreate_sql_agent工具,结合LLM(如Qwen)进行推理与决策,实现了端到端的数据交互流程

一、什么是智能体?工具包又是什么?

  • 智能体是一种具备自主决策能力的AI系统,通过感知环境、分析信息、调用工具、执行动作的闭环过程完成任务

  • 智能体 = 大语言模型(LLM) + 工具(Tools) + 记忆(Memory)

智能体类比就是:一个具备自主决策能力的虚拟助手,能根据目标自主调用工具完成任务

二、智能体(Agent)的出现是为了解决哪些问题?

  • 大模型的短板:虽然大语言模型(LLM)擅长文本生成,但缺乏:

    • 实时数据获取能力(如天气/股票)、精确数学计算能力

    • 专业领域知识(如法律/医疗)、外部系统对接能力

  • Tool工具就是解决这类问题的,通过Tool机制,好比给大模型插入翅膀

大白话解释: 你可以把“工具”理解为你在写程序时定义的一个个方法或函数。比如在 Java 或 Python 中,你经常会封装一些功能,用来完成特定的任务。如果这个方法是用来调用外部服务的 API(比如高德地图的开放接口),那它就是一个“工具”。

以高德地图为例,如果你想获取某个地点的数据,可能需要向高德提供的 API 发送请求。这时候你就可以在 Python 中写一个方法,让它去调用这个 API,然后把结果返回给你。只要在这个方法上加上特定的注解(比如 @tool),它就会被识别为一个“工具”,可以在系统中被自动发现和使用。

简单来说,这个“工具”就是帮你干活的小助手,它可以联网、调用外部接口、执行任务,最终帮你拿到想要的信息或者完成某个操作。

三、LangChain里面创建工具方式

  • @tool装饰器

    • 通过简单的@tool装饰器或StructuredTool即可实现,适用于大多数用例,

    • @tool但不能同时有同步和异步的方法,只能单独使用

  • LangChain Runnables

    • 接受字符串或字典输入的LangChain Runnables使用as_tool方法转换为工具

    • 允许为参数指定名称、描述和其他模式信息;

  • 继承BaseTool类:

    • 通过从BaseTool进行子类化来定义自定义工具,提供了对工具定义的最大控制,但需要编写更多的代码。

 3.1  @tool 装饰器:用来定义一个简单的工具函数,, 可以直接给函数加上这个装饰器,让函数成为可调用的工具

from langchain_core.tools import tool@tool
def multiply(a: int, b: int) -> int:"""把传递的两个参数相乘"""return a * bprint("工具名称:", multiply.name)
print("工具描述:", multiply.description)
print("工具参数:", multiply.args)
print("工具返回值:", multiply.return_direct)
print("工具详细的schema:", multiply.args_schema.model_json_schema())print(multiply.invoke({"a": 2, "b": 3}))
# 定义了一个 `multiply` 工具,用于两个数字相乘,并在调用时显示该工具的名称、描述和参数列表。

3.2 StructuredTool

  • 是LangChain中用于定义结构化参数工具的基类,相比普通@tool装饰器,它支持:

    • 严格的参数模式定义(基于Pydantic模型)

    • 多参数输入校验

    • 自动生成工具调用示例

  • 适用场景:需要多个输入参数或复杂参数类型的工具

from pydantic import BaseModel, Field
from langchain_core.tools import StructuredTool# 定义输入参数的数据结构
class CalculatorInput(BaseModel):a: int = Field(description="第一个数字")b: int = Field(description="第二个数字")# 定义计算函数
def multiply(a: int, b: int) -> int:"""Multiply two numbers."""return a * b
# 封装工具
calculator = StructuredTool.from_function(func=multiply,name="Calculator",description="用于计算两个数字的乘积",args_schema=CalculatorInput,return_direct=True,
)
print("工具名称:", calculator.name)
print("工具描述:", calculator.description)
print("工具参数:", calculator.args)
print("工具返回值:", calculator.return_direct)
print("工具详细的schema:", calculator.args_schema.model_json_schema())# 调用工具
print("工具调用结果:", calculator.invoke({"a": 2, "b": 3}))

3.3 继承BaseTool子类进行创建工具 

from pydantic import BaseModel, Field
from typing import Type
from langchain_core.tools import BaseTool
from pydantic import BaseModelclass CalculatorInput(BaseModel):a: int = Field(description="第一个参数")b: int = Field(description="第二个参数")class CustomCalculatorTool(BaseTool):name: str = "Calculator"description: str = "当你需要计算数学问题时候使用"args_schema: Type[BaseModel] = CalculatorInputreturn_direct: bool = Truedef _run(self, a: int, b: int) -> str:"""使用工具."""return a * bcalculator = CustomCalculatorTool()
print("工具名称:", calculator.name)
print("工具描述:", calculator.description)
print("工具参数:", calculator.args)
print("工具返回值:", calculator.return_direct)
print("工具详细的schema:", calculator.args_schema.model_json_schema())
print(calculator.invoke({"a": 2, "b": 3}))

@tool 用的会多一些~

四、LangChain工具包

为了方便开发者快速使用各种主流工具,LangChain官方加入了很多内置工具,开箱即用

所有工具都是 BaseTool 的子类,且工具是 Runnable可运行组件,支持 invoke、stream 等方法进行调用
也可以通过 name、 description、args、 returu_direct 等属性来获取到工具的相关信息
如果内置工具包不满足,即可以自定义工具
地址:https://python.langchain.com/docs/integrations/tools/

4.1 如何使用内置工具包【联网搜索例子】

选择对应的工具->安装依赖包->编写代码实战

搜索工具:选择 SearchApi,注册时100次免费搜索,注册账号获取 APIKEY

代码实操:

import os# 从langchain_community.utilities模块中导入SearchApiAPIWrapper类,用于封装搜索API
from langchain_community.utilities import SearchApiAPIWrapper# 设置环境变量SEARCHAPI_API_KEY,用于认证搜索API的密钥
os.environ["SEARCHAPI_API_KEY"] = "UVWAsik11111111"# 实例化SearchApiAPIWrapper对象,用于调用搜索API
search = SearchApiAPIWrapper()# 调用run方法执行搜索操作,参数为查询腾讯股价的中文字符串
result = search.run("今天腾讯的股价是多少")# 输出搜索结果
print(result)

4.2 内置工具包整合LLM

这种是相对原始调用工具方式,下面章节会讲经常用的简便方式.这种是方便理解工具调用的底层方式

# 基于LangChain 0.3.x的SearchApi工具实战(需安装依赖)
# pip install langchain-core langchain-openai langchain-communityfrom langchain_community.utilities import SearchApiAPIWrapper
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langchain_core.messages import ToolMessage
from langchain_core.runnables import RunnablePassthrough
from langchain_core.prompts import ChatPromptTemplateimport os
from langchain_core.tools import tool
from pydantic import Field
import loggingos.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "lsv2_pt_da11ddbcbb1111111111"
os.environ["LANGSMITH_ENDPOINT"] = "https://api.smith.langchain.com"
os.environ["LANGSMITH_PROJECT"] = "nnw_agent-search-llm"
logging.basicConfig(level=logging.DEBUG)
# ======================
# 第一步:配置搜索工具
# ======================
# 注册SearchAPI获取密钥:https://www.searchapi.io/# 设置SearchAPI的API密钥
os.environ["SEARCHAPI_API_KEY"] = "UVWAs1111111111"
# 实例化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)}"# ======================
# 第三步:绑定LLM创建Agent
# ======================
# 初始化大模型
llm = ChatOpenAI(model_name="qwen-plus",base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",api_key="sk-005c3c25f6d0111111111",temperature=0.7,
)# 创建聊天提示模板
prompt = ChatPromptTemplate.from_messages([("system","你是一个AI助手,名称叫老王,请根据用户输入的查询问题,必要时可以调用工具帮用户解答",),("human", "{query}"),]
)# 定义工具字典
tool_dict = {"web_search": web_search}# 从字典中提取工具列表
tools = [tool_dict[tool_name] for tool_name in tool_dict]# 绑定工具到大模型
llm_with_tools = llm.bind_tools(tools=tools)# 创建运行链
chain = {"query": RunnablePassthrough()} | prompt | llm_with_tools# 定义查询
query = "今天北京天气如何?"# 执行链并获取响应
resp = chain.invoke({"query": query})
print(resp)# 判断是否需要调用工具 content=''不一定需要调用,根据tool_calls进行判断
# ======================
# 第四步:获取工具调用
# ======================
tool_calls = resp.tool_calls
if len(tool_calls) <= 0:print(f"不需要调用工具:{resp.content}")
else:# 将历史消息合并,包括用户输入和AI输出history_messages = prompt.invoke(query).to_messages()history_messages.append(resp)print(f"历史消息:{history_messages}")# 循环调用工具for tool_call in tool_calls:tool_name = tool_call.get("name")tool_args = tool_call.get("args")tool_resp = tool_dict[tool_name].invoke(tool_args)print(f"一次调用工具:{tool_name},参数:{tool_args},结果:{tool_resp}")# 将工具调用结果添加到历史消息中history_messages.append(ToolMessage(tool_call_id=tool_call.get("id"), name=tool_name, content=tool_resp))print(f"历史消息:{history_messages}")resp = llm_with_tools.invoke(history_messages)print(f"最终结果:{resp}")print(f"调用工具后的结果:{resp.content}")

4.3工具包调用Log

工具调用输入和输出

将用户输入的自然语言和工具列表一起输送给大模型 --> 让大模型进行语义理解 --> 然后大模型将需要调用的工具发送给agent -->agent进行工具调用 --> 工具调用结果同输入的自然语言问题和提示词等一起再送给大模型-->大模型经过最终整理后返回处理结果

五、LangChain智能体执行引擎AgentExecutor

为什么需要 AgentExecutor?

问题:当智能体(Agent)需要执行多步操作(如多次调用工具、循环推理)时,开发者需手动处理:
执行循环:根据模型输出决定是否继续调用工具。
错误处理:捕获工具调用或模型解析中的异常。
流程控制:限制最大迭代次数,防止无限循环。
日志记录:追踪每一步的输入、输出和中间状态。

痛点:
代码冗余:重复编写循环和错误处理逻辑。
维护成本高:复杂任务中难以保证流程稳定性。
可观测性差:难以调试多步骤执行过程

通过上面的例子就可以知道 写起来很麻烦 还要手动调用工具。

create_tool_calling_agent 

  • 是 LangChain 0.3 新增的智能体创建方法, 要求模型直接返回工具调用参数(如 JSON 格式),减少中间解析错误。

  • 结构化工具调用:显式调用工具并传递结构化参数(支持复杂数据类型)

  • 多步骤任务处理:适合需要按顺序调用多个工具的场景

  • 精准控制:通过自定义 Prompt 模板指导 Agent 行为

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-005cxxxxxx",temperature=0.7,
)# 定义聊天提示模板
prompt = ChatPromptTemplate.from_messages([("system", "你是一个AI助手,必要时可以调用工具回复问题"),("human", "我叫老王,经常出差,身份证号是 33333333333333"),# ("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}")

LLM大模型访问MySQL业务数据库文章浏览阅读1k次,点赞25次,收藏16次。创建能通过自然语言与SQL数据库交互的AI智能体,自动生成/执行SQL查询并解析结果核心能力:将用户问题(如“统计每个地区的销量”)转化为 SQL 查询语句。连接数据库执行 SQL,默认只读模式防止数据误修改。将数据库返回的原始数据(如)转换为用户友好的回答(如“总销售额为 $3500”)。自动修正 SQL 语法错误或逻辑问题(如字段名拼写错误)。LangChain 中专门用于连接 SQL 数据库并集成相关操作工具的模块包#使用 SQLDatabase.from_uri 连接数据库,自动读取表结构。_大模型 读取 mysql数据库 回答 https://blog.csdn.net/wnn654321/article/details/148933263 这是一个完整的例子,使用的create_sql_agent SQLDatabaseToolkit(langchain定义的工具)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/87867.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/87867.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用c++做游戏开发至少要掌握哪些知识?

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于用C做游戏开发的相关内容&#xff01; 关…

vue3使用summernote

一、安装 npm install summernote-vue jquery summernote bootstrap popperjs/core二、summernoteEditor.vue <template><div ref"editorRef"></div> </template><script setup> import {ref, onMounted, onBeforeUnmount, watch} f…

低代码平台的性能测试实践与挑战

一、引言 近年来&#xff0c;低代码平台&#xff08;Low-Code Platform&#xff09;正在快速改变企业软件开发方式。Gartner 预测&#xff0c;到 2025 年&#xff0c;超过 70% 的应用开发将基于低代码或无代码技术。通过“拖拉拽建模 图形化逻辑 一键发布”&#xff0c;企业…

Stereolabs ZED系列与ZED X立体相机系列对比:如何根据项目需求选择?

Stereolabs是全球领先的三维视觉技术公司&#xff0c;专注于为机器人、自动化和空间感知等领域提供高性能视觉解决方案。其ZED立体相机系列包括ZED和ZED X两大系列&#xff0c;分别针对多场景三维感知和工业级应用设计&#xff0c;为企业和开发者提供了丰富的选择。ZED系列&…

Spring Boot登录认证实现学习心得:从皮肤信息系统项目中学到的经验

前言 最近通过一个皮肤信息管理系统的项目实践&#xff0c;深入学习了Spring Boot框架中登录认证功能的实现方式。这个项目涵盖了从后端配置到前端集成的完整流程&#xff0c;让我对现代Web应用的安全机制有了更深刻的理解。本文将分享我在这个过程中的学习心得和技术要点。 …

【初阶数据结构】双向链表

文章目录 双向链表1.申请节点2.链表初始化3.尾插4.打印链表5.头插6.尾删7.头删8.查找9.指定位置插入10.删除pos节点11.链表的销毁12.程序源码 双向链表 链表分类 8种 (带头/不带头 单向/双向 循环/循环) 最常用两种 单链表(不带头单向不循环链表) 双向链表&#xff08;带头双向…

从 Prompt 管理到人格稳定:探索 Cursor AI 编辑器如何赋能 Prompt 工程与人格风格设计(下)

六、引入 Cursor AI 编辑器的开发流程革新 在整个系统开发过程中&#xff0c;我大量采用了 Cursor 编辑器作为主要的开发环境&#xff0c;并获得以下关键收益&#xff1a; 具备 AI 补全与代码联想功能&#xff1a;支持通过内置 Copilot 模型对 Python、FastAPI、YAML、JSON 等…

Spark运行架构

Spark框架的核心是一个计算引擎&#xff0c;整体来说&#xff0c;它采用了标准master-slave的结构  如下图所示&#xff0c;它展示了一个Spark执行时的基本结构&#xff0c;图形中的Driver表示master&#xff0c;负责管理整个集群中的作业任务调度&#xff0c;图形中的Executo…

基于未合入PR创建增量patch的git管理方法

目录前言准备操作步骤精准移植基础PR到本地分支修改代码鸿蒙编译、调试、测试具体编译指令、测试步骤这里带过&#xff0c;这不是本文论述重点创建diff文件工作仓库应用最新patch总结前言 作为程序员&#xff0c;多人协同开发同一个需求是正常的。即使是自己一个人搞需求&…

git真正更新项目

背景 Fetch all remote后flutter代码都拉下来&#xff0c;都是Android项目应用不上&#xff1b;git–>update project才生效&#xff01;&#xff01;&#xff01;

AI时代如何拓展Web前端开发的边界

文章目录 1 从“页面仔”到“智能体验构建者”——前端的变与不变2 AI 如何重塑 Web 前端&#xff1a;从开发到用户体验的革命2.1 AI 赋能开发效率&#xff1a;前端工程师的“超级外挂”2.1.1 智能代码辅助与生成2.1.2 自动化测试与 Bug 定位 2.2 AI 提升用户体验&#xff0c;构…

chrome webdrive异常处理-session not created falled opening key——仙盟创梦IDE

注册表错误 :EKKOK:chromeinstallerut1 Lgoogle update settings.cc:26b falled opening key .( e\Update\ClientStateMedium 8A69D345-D564-463c-AFF1-A69D9E530F96} to set usagestats 连接超时 disconnected: received Inspector.detached eventfailed to check if windo…

【Java EE初阶 --- 多线程(进阶)】JUC

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 &#xff0c;Java 欢迎大家访问~ 创作不易&#xff0c;大佬们点赞鼓励下吧~ 文章目录 JUC组件ReentrantLock与s…

免费静态网站搭建

免费静态网站搭建 内容简介搭建步骤GitHub仓库创建Jekyll安装使用Jekyll安装指南Jekyll快速搭建测试Jekyll后续玩法 内容简介 &#x1f6a9;Tech Contents&#xff1a;GithubPage/Jekyll/Custom URLs &#x1f431;GitHub Pages&#xff1a;静态网站托管服务&#xff0c;自动将…

MySQL 8.0 OCP 1Z0-908 题目解析(21)

题目81 Choose two. Examine the modified output: mysql> SHOW SLAVE STATUS\G *************************** 1. row ***************************Slave_IO_Running: YesSlave_SQL_Running: YesSeconds_Behind_Master: 1612Seconds_Behind_Master value is steadily gro…

Web前端开发-HTML、CSS

文章目录是什么&#xff1f;HTML快速入门VS Code开发工具基础标签&样式新浪新闻-标题标题排版标题样式标题样式-1标题样式-2超链接新浪新闻-正文新浪新闻-正文排版新浪新闻-页面布局表格标签表单标签表单标签-表单项是什么&#xff1f; HTML快速入门 VS Code开发工具 基础标…

Vue.js状态管理: Vuex在大型项目中的实际应用

# Vue.js状态管理: Vuex在大型项目中的实际应用 ## 一、Vuex核心架构与大型项目适配 ### 1.1 状态管理&#xff08;State Management&#xff09;的本质需求 在复杂前端系统中&#xff0c;组件间的数据传递成本随项目规模呈指数级增长。根据Vue官方统计&#xff0c;超过500个组…

C++开发:结构体作为函数形参的值传递与引用传递

笔者定义了一个结构体变量&#xff0c;用于作为函数的形参&#xff0c;定义如下&#xff1a;struct CardParameters {float* Average nullptr;int averageSize 0; }; 需求描述&#xff1a;结构体变量作为函数的形参&#xff0c;在函数体中给指针变量分配内存空间并赋值&#…

【unity小技巧】在 Unity 中将 2D 精灵添加到 3D 游戏中,并实现阴影投射效果,实现类《八分旅人》《饥荒》等等的2.5D游戏效果

注意&#xff1a;考虑到unity小技巧的内容比较多&#xff0c;我将该内容分开&#xff0c;并全部整合放在【unity小技巧】专栏里&#xff0c;感兴趣的小伙伴可以前往逐一查看学习。 文章目录 前言实战1、在3D场景中&#xff0c;新建一些不同形状的2D图片2、我们新建一个Lit材质3…

Rust 内存结构:深入解析

Rust 的内存管理系统是其核心特性之一&#xff0c;结合了手动内存管理的效率与自动内存管理的安全性。以下是 Rust 内存结构的全面解析&#xff1a; 内存布局概览 ----------------------- | 代码段 (Text) | 只读&#xff0c;存储可执行指令 ----------------------…