当大型语言模型(LLM)原生不支持函数调用功能时,如何实现智能工具调度?本文通过自然语言解析+结构化输出控制的方法来实现。
核心实现步骤
- 定义工具函数
使用@tool装饰器声明可调用工具:
python
from langchain_core.tools import tool
@tool
def multiply_by_max(
a: int,
b: list[int]
) -> int:
"""将a乘以b列表中的最大值"""
return a * max(b)
@tool
def divide_by(a: float, b: float) -> float:
"""将a除以b"""
return a / b
- 构建响应模型
使用Pydantic定义结构化响应格式:
python
from pydantic import BaseModel, Field
class Response(BaseModel):
name: str = Field(None, description="调用的函数名称")
args: dict = Field(None, description="函数参数")
- 创建输出解析器
python
from langchain_core.output_parsers import PydanticOutputParser
parser = PydanticOutputParser(pydantic_object=Response)
- 设计提示模板
python
from langchain_core.prompts import ChatPromptTemplate
prompt = ChatPromptTemplate.from_messages([
("human", """
请根据需求从下列函数中选择合适的工具:
可用工具:\n{functions}\n
输出格式:\n{format_instructions}
问题:{query}
""")
]).partial(
functions=[tool.args_schema.model_json_schema() for tool in [multiply_by_max, divide_by]],
format_instructions=parser.get_format_instructions()
)
工作原理
- 自然语言解析:LLM分析用户query的语义
- 工具匹配:根据函数描述自动选择最合适的工具
- 参数提取:从自然语言中提取结构化参数
- 格式化输出:生成符合预定格式的JSON响应
示例演示
示例1:数学计算
python
chain = prompt | ChatOpenAI(model="qwen-max") | parser
result = chain.invoke("请将3乘以一至九的最大值")
# 输出:
# name='multiply_by_max', args={'a':3, 'b':[1,2,3,4,5,6,7,8,9]}
示例2:无匹配工具
python
result = chain.invoke("查询北京天气")
# 输出:
# name=None, args=None