我们更需要一个能够根据用户提示词,自动选择对应工具的大模型,而不是在一个链里一次只能使用一个工具。这里用代码实现了,在langchian中如何从多个可选工具中,动态的使用工具。
注意事项:大模型生成的工具入参arguments结构可能会不稳定,导致出错。需要通过提示词去强化。比如代码中,我强化了“"arguments"键对应的值应该是所选函数的输入,必须是dict格式”这句提示词,之后就稳定了。
from langchain_core.output_parsers import JsonOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.tools import tool, render_text_description
from langchain_community.chat_models import ChatTongyi
from operator import itemgetter
@tool
def add(first_int: int, second_int: int) -> int:
"""将两个数相加。"""
return first_int + second_int
@tool
def exponentiate(base: int, exponent: int) -> int:
"""对底数求指数幂"""
return base ** exponent
@tool
def multiply(first_int: int, second_int: int) -> int:
"""将两个数相乘"""
return first_int * second_int
# 添加到工具列表
tools = [add, exponentiate, multiply]
rendered_tools = render_text_description(tools)
system_template = f"""
你是一名助理,可以使用以下工具集,以下是每个工具的名称和说明:
{rendered_tools}
根据用户输入,返回要使用的工具的名称和输入,将您的响应作为带有'name'和'arguments'键的JSON blob返回。不要有其他任何文字。
"arguments"键对应的值应该是所选函数的输入,必须是dict格式。JSON样例如下:
```json```
"""
# 创建提示模板
prompt = ChatPromptTemplate.from_messages(
[("system", system_template), ("user", "{input}")]
)
# 关键方法,动态选择链的工具
def tool_chain(model_output):
# 创建一个工具名称为键,工具本身为值的一个Map
tool_map = {tool.name: tool for tool in tools}
# 根据工具描述的工具名称确定工具
chosen_tool = tool_map[model_output["name"]]
# 把工具的入参传递给工具
return itemgetter("arguments") | chosen_tool
llm = ChatTongyi()
chain = prompt | llm | JsonOutputParser() | tool_chain
res = chain.invoke({"input": "124+33等于?"})
print(res)