如何为LLM和聊天模型添加工具调用功能
引言
在自然语言处理和生成领域,大型语言模型(LLM)及其聊天模型已经展现了巨大的潜力。然而,这些模型在某些情况下需要调用外部工具来实现特定功能。虽然一些模型已经被调优以支持工具调用,但对于不具备这一原生支持的模型,我们可以通过编写合适的提示语(prompt)来实现这一功能。本文将详细介绍如何为LLM和聊天模型添加工具调用功能。
主要内容
安装必要的包
首先,我们需要安装LangChain以及相关工具包:
%pip install --upgrade --quiet langchain langchain-community
设置模型环境
我们将选择一些现有的模型,如OpenAI、Anthropic、Azure等,并设置相应的API密钥。在这里,我们以OpenAI的GPT-4为例:
pip install -qU langchain-openai
import getpass
import os
os.environ["OPENAI_API_KEY"] = getpass.getpass()
from langchain_openai import ChatOpenAI
model = ChatOpenAI(model="gpt-4")
创建自定义工具
接下来,我们将创建两个简单的工具:加法和乘法。
from langchain_core.tools import tool
@tool
def multiply(x: float, y: float) -> float:
"""Multiply two numbers together."""
return x * y
@tool
def add(x: int, y: int) -> int:
"Add two numbers."
return x + y
tools = [multiply, add]
# 查看工具描述
for t in tools:
print("--")
print(t.name)
print(t.description)
print(t.args)
创建提示语
我们需要编写一个提示语,明确模型可以使用的工具及其参数,并约定输出格式。
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.tools import render_text_description
rendered_tools = render_text_description(tools)
print(rendered_tools)
system_prompt = f"""\
You are an assistant that has access to the following set of tools.
Here are the names and descriptions for each tool:
{rendered_tools}
Given the user input, return the name and input of the tool to use.
Return your response as a JSON blob with 'name' and 'arguments' keys.
The `arguments` should be a dictionary, with keys corresponding
to the argument names and the values corresponding to the requested values.
"""
prompt = ChatPromptTemplate.from_messages([
("system", system_prompt),
("user", "{input}")
])
chain = prompt | model
message = chain.invoke({"input": "what's 3 plus 1132"})
if isinstance(message, str):
print(message)
else:
print(message.content)
添加输出解析器
我们将使用JsonOutputParser解析模型的输出。
from langchain_core.output_parsers import JsonOutputParser
chain = prompt | model | JsonOutputParser()
chain.invoke({"input": "what's thirteen times 4"})
调用工具函数
我们需要一个函数来执行工具调用,根据模型返回的工具名称和参数来调用对应的工具。
from typing import Any, Dict, Optional, TypedDict
from langchain_core.runnables import RunnableConfig
class ToolCallRequest(TypedDict):
name: str
arguments: Dict[str, Any]
def invoke_tool(tool_call_request: ToolCallRequest, config: Optional[RunnableConfig] = None):
tool_name_to_tool = {tool.name: tool for tool in tools}
name = tool_call_request["name"]
requested_tool = tool_name_to_tool[name]
return requested_tool.invoke(tool_call_request["arguments"], config=config)
invoke_tool({"name": "multiply", "arguments": {"x": 3, "y": 5}})
整合链式调用
最后,我们将所有步骤整合到一个链式调用中。
chain = prompt | model | JsonOutputParser() | invoke_tool
chain.invoke({"input": "what's thirteen times 4.14137281"})
返回工具输入
有时我们希望返回不仅是工具的输出,还有输入,可以通过RunnablePassthrough实现。
from langchain_core.runnables import RunnablePassthrough
chain = (
prompt | model | JsonOutputParser() | RunnablePassthrough.assign(output=invoke_tool)
)
chain.invoke({"input": "what's thirteen times 4.14137281"})
常见问题和解决方案
-
模型输出不符合预期格式
- 解决方案: 提供少量示例,增加提示语的明确性。
-
工具调用失败
- 解决方案: 添加错误处理机制,捕获异常并反馈给模型以纠正输出。
总结和进一步学习资源
通过本文的介绍,我们学习了如何为不具备原生支持工具调用的LLM和聊天模型添加工具调用功能。希望你能根据具体需求进行实验和调整。
参考资料
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
---END---