之前给大家介绍了对大语言模型知识助力的一种方式RAG,大家可以回顾
AI菜鸟向前飞 — LangChain系列之十 - RAG(上篇)
AI菜鸟向前飞 — LangChain系列之十一 - RAG(中篇)
AI菜鸟向前飞 — LangChain系列之十二 - RAG(下篇)
接下来 介绍如何使用Tool为大语言模型助力。
同时,Tool也是学会Agent和LangGraph的重要基础哈
Tool三要素
实现方式(三种)
Class定义
class CustomToolClass(BaseTool):
name = "Custom tool"
description = "这是一个处理XXX问题的工具"
def _run(self, text: str) -> str:
…………………………
return "你好啊,我的处理结果是xxxxxx"
async def _arun(self, text: str) -> str:
return "你好啊,我的处理结果是xxxxxx"
StructuredTool
def dealwithX(text: str) -> str:
'''这是一个处理XXX问题的工具'''
…………………………
return "你好啊,我的处理结果是xxxxx"
CustomTool = StructuredTool.from_function(
func=dealwithX,
name = "处理函数",
description="你好啊,我是一个处理函数",
)
装饰器Decorater
@tool
def dealwithX(text1: str) -> str:
'''这是一个处理XXX问题的工具'''
…………………………
return "你好啊,我的处理结果是xxxxx"
与大语言模型交互
先看一段代码
@tool
def get_citations(docs: str):
''' 这是一个询问文章出处的处理函数 '''
return f"{docs}的文章出自于 Song榆钱儿公众号,欢迎关注。"
@tool
def contain_docs(series: str):
"""查询包含多少篇文章的函数"""
return f"这个{series}里面已包含20多篇文章。"
tools = [get_citations, contain_docs]
model_with_tool = model.bind_tools(tools=tools)
res = model_with_tool.invoke("你正在阅读的'AI菜鸟系列'文章出自哪里?这个公众号一共有多少篇文章?")
print(res)
返回的内容很多很多,我挑两个个重点内容介绍下
-
additional_kwargs
包含了tool_calls,即:把上面写的那两个Tool(函数)转成json格式返回
-
Tool_calls
一个单独的tool_calls列表,此处划重点,后面会用到它
[{'name': 'get_citations', 'args': {'docs': 'AI菜鸟系列'}, 'id': 'a8ff6f2f78c84bc3a3999ae2b0356c0a'},
{'name': 'contain_docs', 'args': {'series': 'AI菜鸟系列'}, 'id': 'ff4beda02a61404a922affae5aff5099'}]
聪明的小伙伴能想到,我们也可以把上面的程序改成这种形式,就不会看那么多繁琐的内容
print(res.tool_calls)
函数还没被真正调用起来
因为还没开始介绍Agent和LangGraph,这里我们可以“曲线救国”,用最原始的方式,代码如下:
func_with_args = res.tool_calls
# 映射
func_map = {"get_citations": get_citations, "contain_docs": contain_docs}
# 挨个调用
for each in func_with_args:
func_res = func_map[each["name"]].invoke(input=each["args"])
print(func_res)
输出结果
AI菜鸟系列的文章出自于 Song榆钱儿公众号,欢迎关注。
这个AI菜鸟系列里面已包含20多篇文章。
如果这么做,那要LangChain有何用...后面讲到Agent你就懂了:)
扩展知识
在早期的版本中(直接用OpenAI)在bind函数时(上面例子我们直接用的bind_tools),需要把函数转成json才能“绑”成功,这里就扩展一个这方面的知识点,使用
from langchain_core.utils.function_calling import convert_to_openai_function
convert_to_openai_function(get_citations)
让我们看看返回结果,有没有觉得跟上面的additional_kwargs很像
{'name': 'get_citations',
'description': '这是一个询问文章出处的处理函数',
'parameters': {
'type': 'object',
'properties': {
'docs': {
'type': 'string'}
},
'required': ['docs']
}
}
聪明的小伙伴会想到,上面bind_tool是不是可以用bind替换掉, 那...当然没问题
# model_with_tool = model.bind_tools(tools=[get_citations, contain_docs])
model_with_tool = model.bind(tools=[convert_to_openai_function(get_citations), convert_to_openai_function(contain_docs)])
基础打牢了之后,下一篇将开始介绍Agent :)