2.LangChain--聊天模型工具篇
tooldef add (a:int, b:int)->int: #加法工具"""两数相加Args:a : 一个整数b : 另一个整数"""# 方式二class AddInput(BaseModel): #类中定义函数描述和参数描述"""两数相加"""a: int = Field(..., description="第一个整数")#...表示必填字段b: int = Field(..., desc
一、聊天模型--定义工具
LLM本身是封闭的知识系统,为解决直接计算、查询实时信息、操作数据库或调⽤任何外部 API等问题可以进行工具调用实现与外界交互
1.1创建工具
(1)@tool+python函数
注:
#定义时要有函数名、类型提⽰和⽂档字符串,相当于工具的三个属性:工具名称、工具参数、工具描述
#这些信息会传给工具schema进行相关内容的匹配和校验
#Schema 就是描述其他数据结构的声明格式,⽤于⾃动验证数据⽽存在。
#为什么要有这些属性字段:
#相当于在调用LLM时给大模型的提示词,使调用更加高效准确
#工具名称:让LLM知道有哪些工具可以调用
#工具描述:相当于提示词,告诉模型工具具备哪些能力,让LLM知道调谁
#工具参数:让LLM知道怎么调用工具a.定义工具属性1--常规
@tool def add (a:int, b:int)->int: #加法工具 """ 两数相加 Args: a : 一个整数 b : 另一个整数 """ return a + b print(add.invoke({"a": 2, "b": 3})) print(add.description) print(add.name) print(add.args)b.定义工具属性2--Pydantic类(分离描述、参数)
# 方式二 class AddInput(BaseModel): #类中定义函数描述和参数描述 """两数相加""" a: int = Field(..., description="第一个整数")#...表示必填字段 b: int = Field(..., description="第二个整数") @tool(args_schema=AddInput) def add(a: int, b: int) -> int: return a + bc.定义工具属性3 -- 依赖Annotated(参数类型与描述)
@tool def add( a : Annotated[int, ..., "第一个整数"], #...表示必填字段 b : Annotated[int, ..., "第二个整数"], ) -> int: """两数相加 Args: a: 第一个整数 b: 第二个整数 """ return a + b注:工具属性在任何方式定义都不能省略
(2)使⽤ StructuredTool 类提供的函数创建⼯具
用法:
classmethod from_function( func: Callable | None = None, coroutine: Callable[[...], Awaitable[Any]] | None = None, name: str | None = None, description: str | None = None, return_direct: bool = False, args_schema: type[BaseModel] | dict[str, Any] | None = None, infer_schema: bool = True, *, response_format: Literal['content', 'content_and_artifact'] = 'content', parse_docstring: bool = False, error_on_invalid_docstring: bool = False, **kwargs: Any, ) → StructuredTool参数:
a.定义1--常规
# 方式一: def add(a: int, b: int) -> int: """两数相加""" return a + b add_tool = StructuredTool.from_function(func=add)b.定义2 --Pydantic类
#方式二: class AddInput(BaseModel): a:int = Field(description="第一个整数") b:int = Field(description="第二个整数") def add(a: int, b: int) -> int: return a + b add_tool = StructuredTool.from_function( func=add, name="ADD", # 工具名 description="两数相加", # 工具描述 args_schema=AddInput, # 工具参数 )c.加⼊ response_format 配置,调整回复方式
对于想要追求看过程的问题我们就必须在回复上加上过程
class AddInput(BaseModel): a:int = Field(description="第一个整数") b:int = Field(description="第二个整数") #调整回复方式,改为结果 + 过程元组 def add(a: int, b: int) -> Tuple[str, List[int]]: nums = [a, b] content = f"{nums}相加的结果是{a + b}" return content, nums # response_format将结果与过程元组分离 add_tool = StructuredTool.from_function( func=add, name="ADD", # 工具名 description="两数相加", # 工具描述 args_schema=AddInput, # 工具参数 response_format="content_and_artifact" ) # 模拟大模型调用姿势 print(add_tool.invoke( { "name": "ADD", "args": {"a": 3, "b": 4}, "type": "tool_call", # 必填 "id": "111", # 必填, 用来将工具调用请求和结果关联起来。 } ))
1.2绑定工具.bind_tools()
为了实际将这些⼯具绑定到聊天模型,可以使⽤聊天模型的 .bind_tools() ⽅法
from langchain_openai import ChatOpenAI
# 定义⼤模型
model = ChatOpenAI(model="gpt-4o-mini")
...
# 绑定⼯具,返回⼀个 Runnable 实例
tools = [add, multiply]
model_with_tools = model.bind_tools(tools)
定义:
bind_tools(
tools: Sequence[dict[str, Any] | type | Callable | BaseTool],
*,
tool_choice: dict | str | Literal['auto', 'none', 'required', 'any'] | bool
| None = None,
) → Runnable
参数:
返回值:
1.3调用工具
通过 .bind_tools() ⽅法我们可知,它返回了⼀个 Runnable 实例,因此我们可以使⽤该 Runnable 实例,调⽤ .invoke() ⽅法,完成⼯具调⽤。
⼯具调⽤的⼀个关键原则是,模型根据输⼊的相关性决定何时使⽤⼯具。模型并不总是需要调⽤⼯具
本质工具的调用其实分为工具的选择和工具的使用。
(1)绑定好的工具返回一个Runnable实例在.invoke输出后返回的是AIMessage,(并没有输出的结果)
from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage from langchain_core.tools import tool from typing_extensions import Annotated # 定义⼤模型 model = ChatOpenAI(model="gpt-4o-mini") @tool def add( a: Annotated[int, ..., "First integer"], b: Annotated[int, ..., "Second integer"] ) -> int: """Add two integers.""" return a + b @tool def multiply( a: Annotated[int, ..., "First integer"], b: Annotated[int, ..., "Second integer"] ) -> int: """Multiply two integers.""" return a * b # 绑定⼯具 tools = [add, multiply] model_with_tools = model.bind_tools(tools) # 调⽤⼯具 result = model_with_tools.invoke("9乘6等于多少?") print(result)
(2)该返回结果包含一个tool_calls属性,包含要调用的工具名称,工具参数等信息
model_with_tools = model.bind_tools(tools, tool_choice="any") result = model_with_tools.invoke("9乘6等于多少?") print(result.tool_calls)
根据该属性进行选择后再进行.invoke()返回一个ToolMessage(包含结果)将我们的问题HumanMessage,AIMessage,ToolMessage集体再传给大模型输出后才是我们想要的形式输出
#HumanMessage messages = [ HumanMessage("9乘6等于多少?5加3等于多少?") ] #AIMessage ai_msg = model_with_tools.invoke(messages) messages.append(ai_msg) #选择进行使用工具返回ToolMessage for tool_call in ai_msg.tool_calls: # 根据⼯具名选择对应⼯具函数(不区分⼤⼩写) selected_tool = {"add": add, "multiply": multiply}[tool_call["name"].lower()] # 执⾏⼯具调⽤,返回 ToolMessage tool_msg = selected_tool.invoke(tool_call) # 将 ToolMessage 加⼊消息 messages.append(tool_msg) print(messages) result = model.invoke(messages) print(result)
1.4LangChain提供的工具
angChain 官⽅也已经给我们提供了很多现成的⼯具(Tool)和⼯具包(Toolkit)。
LangChain 提供的⼯具⻅这⾥。写好的⼯具⼀般都是为了使⽤ LangChain 中集成的三⽅组件或⼯具⽽创造的,有搜索、数据库、⽹⻚浏览器等相关的⼯具。示例:TavilySearch 类可以⽀持我们进⾏搜索,Tavily 是⼀个专⻔为 AI 设计的搜索引擎,专为智能体检索与推理需求量⾝打造的⼯具
注:需要pip安装所需的包pip install -U langchain-tavily
并在官网申请API添加到环境变量中
from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage from langchain_tavily import TavilySearch # 定义⼤模型 model = ChatOpenAI(model="gpt-4o-mini") # 绑定⼯具 tool = TavilySearch(max_results=4) # max_results 返回的最⼤搜索结果 model_with_tools = model.bind_tools([tool]) # 添加AIMessage到消息中去 messages = [ HumanMessage("中国西安今天的天⽓怎么样?") ] ai_msg = model_with_tools.invoke(messages) messages.append(ai_msg) for tool_call in ai_msg.tool_calls: # 执⾏⼯具调⽤,返回 ToolMessage tool_msg = tool.invoke(tool_call) # 将 ToolMessage 加⼊消息 messages.append(tool_msg) result = model_with_tools.invoke(messages) print(result.content)
更多推荐












所有评论(0)