-正文-
-
工具(Tool)
-
通过参数自定义工具
-
通过解析文档字符串配置定义工具
-
通过大模型的 Tool calling 调用工具
-
代码示例
-
完整日志
近年来大模型发展过程中面临的几个核心挑战:静态知识的局限性、执行能力的缺失、与外部系统的割裂。为了应对这些挑战,推动大模型从单纯的语言生成工具演变为真正的任务执行引擎,Function calling 诞生了,成为大模型一项不可或缺的核心能力。
概念 Function calling 和 Tool Calling 会混用
我们在做应用开发的时候,大部分时候尽量避免直接耦合到OpenAI,会使得程序兼容性不好,这时只要面向 LangChain 开发就可以了
LangChain 是一个灵活的框架,它提供了与多种大模型进行交互的能力
它的设计允许集成和使用来自不同源的多种模型,包括但不限于OpenAl、Cohere和 Hugging Face 等模型库中的模型。这样,你不必拘泥于某种模型,而是为自己的应用选择最合适的模型。对于Tool Calling能力来说,LangChain 也做了抽象
调用其他工具的 API(如:Database Tool) 通常需要特定的有效负载格式。可以使用 Tool Calling 来向模型请求与特定格式匹配的响应。随后可以使用这个响应作为负载去做“工具(Tool)实际的执行”
通俗来将就是:让大模型通过理解用户的提示词,来决定是否需要调用工具(如上图),
如果需要调用工具,会返回需要调用的工具名称和调用参数(不是直接执行工具),后续由代码去执行对应的工具(Tool)
如果不需要调用工具,那么就直接回复自然语言(如:How can I assist you?)
工具(Tool)
tool抽象 在 LangChain 中将 Python函数 与 定义“函数名称、描述和预期参数”的schema 关联起来。
工具(Tool) 可以传给支持 tool calling 的 聊天模型,允许模型使用特定输入执行特定函数。
创建工具的推荐方法是使用@tool 装饰器。此装饰器旨在简化工具创建过程,在大多数情况下应使用它。定义函数后,可以使用@tool 对其进行装饰,以创建实现工具接口 的工具。
代码如:
from langchain_core.tools import tool @tool def multiply(a: int, b: int) -> int: """两个数字相乘.""" return a * b
默认情况下,装饰器使用函数名称作为工具名称
装饰器将使用函数的文档字符串作为工具的描述 —— 因此必须提供文档字符串。
定义工具后,可以通过调用直接使用它
result = multiply.invoke({"a": 2, "b": 3}) print(result) # Output: 6
也能直接看到工具的具体信息
print(multiply.name) print(multiply.description) print(multiply.args) # 输出 multiply 两个数字相乘. {'a': {'title': 'A', 'type': 'integer'}, 'b': {'title': 'B', 'type': 'integer'}}
通过参数自定义工具
@tool("multiplication-tool", args_schema=CalculatorInput, return_direct=True)
代码如:
from pydantic import BaseModel, Field class CalculatorInput(BaseModel): a: int = Field(description="第一个数字") b: int = Field(description="第二个数字") # 通过参数自定义 @tool("multiplication-tool", args_schema=CalculatorInput, return_direct=True) def multiply(a: int, b: int) -> int: """两个数字相乘.""" return a * b # 查看工具的具体信息 print(multiply.name) print(multiply.description) print(multiply.args) print(multiply.return_direct)
输出:
# 输出 multiplication-tool 两个数字相乘. {'a': {'description': '第一个数字', 'title': 'A', 'type': 'integer'}, 'b': {'description': '第二个数字', 'title': 'B', 'type': 'integer'}} True
通过解析文档字符串配置定义工具
@tool 可以选择性地解析Google Style 文档字符串,并将文档字符串组件(例如参数描述)与工具schame的相关部分关联起来。使用这种方法,需要指定 parse_docstring
代码如:
@tool(parse_docstring=True) # 解析文档字符串 def multiply(a: int, b: int) -> int: """两个数字相乘. Args: a: 第一个数字 b: 第二个数字 Returns: 两个数字相乘的结果 """ return a * b # 查看工具的具体信息 print(multiply.name) print(multiply.description) print(multiply.args) print(multiply.return_direct)
结果:
# 输出 multiply 两个数字相乘. {'a': {'description': '第一个数字', 'title': 'A', 'type': 'integer'}, 'b': {'description': '第二个数字', 'title': 'B', 'type': 'integer'}} False
通过大模型的 Tool calling 调用工具
Tool calling 允许聊天模型通过“Tool calling”来响应给定的提示词。
虽然“Tool calling”这个名字暗示模型正在直接执行某些操作,但实际上并非如此!模型仅生成工具的参数,而是否运行工具(或不运行)取决于用户。
Tool calling 可以从模型生成结构化输出,即使您不打算调用任何工具,也可以使用它。该技术是从非结构化文本中提取信息
如下图,把用户输入的文本,通过大模型的Tool calling提取出了符合工具get_weather的信息
代码示例
第一步:定义工具
from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage model = ChatOpenAI( api_key='hk-iwtb1e427', base_url='https://api.openai-hk.com/v1', temperature=0 ) print("第一步 :定义工具") @tool def multiply(a: int, b: int) -> int: """两个数字相乘.""" return a * b tools = [multiply]
第二步:把工具绑定到大模型
# Tool binding print("第二步 :把工具绑定到大模型") model_with_tools = model.bind_tools(tools)
第三步:大模型 Tool calling
# Tool calling print("第三步 :大模型Tool calling") query = "2乘以3" messages = [HumanMessage(query)] ai_msg = model_with_tools.invoke(messages) print(ai_msg) # 获取返回的response中工具名称和调用参数 print("大模型 Tool calling 返回结果 : ",ai_msg.tool_calls) # [{'name': 'multiplication-tool', 'args': {'a': 2, 'b': 3}, 'id': 'call_2bJbBe74qhuDfg3ZGCu7p9e3', 'type': 'tool_call'}] messages.append(ai_msg)
第四步:工具的执行(Tool calling 返回需要执行的工具)
print("第四步 :工具的执行") # 定义所有的工具字典 all_tools = { "multiply": multiply } for tool_call in ai_msg .tool_calls: selected_tool = all_tools[tool_call["name"].lower()] tool_msg = selected_tool.invoke(tool_call) print("工具的执行 返回结果 : ",tool_msg) messages.append(tool_msg) # content='6' name='multiply' tool_call_id='call_CTCJAFlibfN3zhM9jMMStBlp' print("聊天上下文 :") print(messages)
第五步:大模型处理工具的返回结果
print("第五步:大模型处理工具的返回结果") response = model_with_tools.invoke(messages) print("大模型返回 :",response.content) # 大模型返回 : 2乘以3的结果是6。
用户输入 :2乘以3
大模型返回 : 2乘以3的结果是6。
日志:
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。