Jean's Blog

一个专注软件测试开发技术的个人博客

0%

LangChain组件Tools

简介

  • 工具是应用开发者提供的函数,供语言模型在特定情境中调用,用于完成模型本身无法直接完成的任务。
  • 模型会基于上下文生成调用某个工具的结构化请求,LangChain 会识别调用请求,执行函数并返回结果。
  • 工具是 LangChain 智能体构建中的重要一环,扩展了模型的“行动能力”。

流程:

graph LR
    A["用户输入"] --> B["模型生成工具调用"]
    B --> C["执行工具函数"]
    C --> D["返回结果给模型"]
    D --> E["生成最终响应"]

使用原理

大语言模型根据当下应用场景进行判断,是否应该使用此工具。所以工具的描述至关重要,如果工具描述不清晰,则可能会导致大语言模型无法很好的将这些工具应用在适用的场景之上。

Tools需要包含的信息

作用 对应字段名
工具名称。 name
该工具是什么的描述。 description
工具输入内容的 JSON 架构。 args_schema
工具的结果是否应直接返回给用户。 return_direct
要调用的函数。

Tool的使用

LangChain中的工具(Tool)是一个封装了特定功能的类,它包含四个核心组成部分:

  • 名称(name):名称是工具在工具集合中的唯一标识符,必须确保在同一工具集中不重复
  • 描述(description):描述用于说明工具的功能,为LLM或代理提供上下文信息,帮助模型理解何时以及如何调用该工具
  • 参数模式(args_schema):是使用Pydantic BaseModel定义的输入参数结构,用于验证和解析工具调用的参数
  • 是否直接返回(return_direct):布尔值属性,当设置为True时,智能体会在调用工具后立即返回结果给用户,而不继续调用其他工具

将工具函数转为LangChain Tool对象的两种方式

  1. 使用Tool.from_function生成

    1
    2
    3
    4
    5
    add_tools = Tool.from_function(
    func=add,
    name="add",
    description="计算两个数相加"
    )
  1. 使用@tool装饰器生成(推荐),使用该方式,函数必须要有函数的注释信息
    1
    2
    3
    4
    @tool
    def add(a, b):
    """add two numbers"""
    return a + b

直接上代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# @Time:2025/9/16 08:56
# @Author:jinglv
from langchain_core.prompts import ChatPromptTemplate, ChatMessagePromptTemplate
from langchain_core.tools import Tool


# 开发工具函数
def add(a, b):
return a + b


# 将工具函数转为LangChain Tool对象, 使用Tool.from_function生成
add_tools = Tool.from_function(
func=add,
name="add",
description="add two numbers"
)

tools_dict = {
"add": add
}

# 设置大模型
import os
from dotenv import load_dotenv

# 加载 .env 文件中的变量
load_dotenv()

from langchain_openai import ChatOpenAI

qv_llm = ChatOpenAI(
model=os.getenv("LLM_MODEL"),
base_url=os.getenv("LLM_BASE_URL"),
api_key=os.getenv("LLM_API_KEY"),
streaming=True,
)

# 将大模型和Tool对象绑定,注意传入的是一个数组
llm_with_tools = qv_llm.bind_tools([add_tools])

# 大模型调用工具
system_message_template = ChatMessagePromptTemplate.from_template(
template="你是一位{role}专家,擅长回答{domain}领域的问题",
role="system",
)

human_message_template = ChatMessagePromptTemplate.from_template(
template="用户问题:{question}",
role="user",
)

# 创建提示词模板
chat_prompt_template = ChatPromptTemplate.from_messages([
system_message_template,
human_message_template,
])

chain = chat_prompt_template | llm_with_tools

response = chain.invoke(input={"role": "计算", "domain": "数学计算", "question": "100+100=?"})

print('-----------------------------response-------------------------')
print(response)

# 调用工具
for tool_calls in response.tool_calls:
print('-----------------------------tool_calls-------------------------')
print(tool_calls)

args = tool_calls["args"]
print('-----------------------------args-------------------------')
print(args)
func_name = tool_calls['name']
print('-----------------------------func_name-------------------------')
print(func_name)

tool_func = tools_dict[func_name]
tool_content = tool_func(int(args["__arg1"]), int(args["__arg2"]))
print('-----------------------------tool_content-------------------------')
print(tool_content)

@tool装饰器的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# @Time:2025/9/16 09:03
# @Author:jinglv
from langchain_core.prompts import ChatPromptTemplate, ChatMessagePromptTemplate
from langchain_core.tools import tool


# 开发工具函数,使用@tool注册转换为LangChain的工具
# 使用@tool,工具的注释是必须要有
@tool
def add(a, b):
"""add two numbers"""
return a + b


tools_dict = {
"add": add
}

# 设置大模型
import os
from dotenv import load_dotenv

# 加载 .env 文件中的变量
load_dotenv()

from langchain_openai import ChatOpenAI

qv_llm = ChatOpenAI(
model=os.getenv("LLM_MODEL"),
base_url=os.getenv("LLM_BASE_URL"),
api_key=os.getenv("LLM_API_KEY"),
streaming=True,
)

# 将大模型和Tool对象绑定,注意传入的是一个数组
llm_with_tools = qv_llm.bind_tools([add])

# 大模型调用工具
system_message_template = ChatMessagePromptTemplate.from_template(
template="你是一位{role}专家,擅长回答{domain}领域的问题",
role="system",
)

human_message_template = ChatMessagePromptTemplate.from_template(
template="用户问题:{question}",
role="user",
)

# 创建提示词模板
chat_prompt_template = ChatPromptTemplate.from_messages([
system_message_template,
human_message_template,
])

chain = chat_prompt_template | llm_with_tools

response = chain.invoke(input={"role": "计算", "domain": "数学计算", "question": "使用工具计算:100+100=?"})

print('-----------------------------response-------------------------')
print(response)

# 调用工具
for tool_calls in response.tool_calls:
print('-----------------------------tool_calls-------------------------')
print(tool_calls)

args = tool_calls["args"]
print('-----------------------------args-------------------------')
print(args)
func_name = tool_calls['name']
print('-----------------------------func_name-------------------------')
print(func_name)

tool_func = tools_dict[func_name]
tool_content = tool_func.invoke(args)
print('-----------------------------tool_content-------------------------')
print(tool_content)

使用args_schema精确控制工具入参,@tools装饰器定义的工具如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from pydantic import BaseModel

class AddInputArgs(BaseModel):
a: str = Field(description="first number")
b: str = Field(description="second number")

@tool(
description="add two numbers",
args_schema=AddInputArgs,
return_direct=True,
)
def add(a, b):
"""add two numbers"""
return a + b

LangChain内置工具

Langchain内置了一些常用的工具,供我们使用,具体内置了哪些工具,可以详细的到官方文档上查看

Tool使用方法:https://python.langchain.com/docs/integrations/tools/

内置Tooltiks:https://api.python.langchain.com/en/latest/community/agent_toolkits.html

示例一:使用内置的维基百科工具进行搜索操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
api_wrapper = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=100)
tool = WikipediaQueryRun(api_wrapper=api_wrapper)
# 工具的名称
# tool.name
# 描述
# tool.description
# 输入参数
# tool.args
# 我们可以看到该工具是否应该直接返回给用户
# tool.return_direct

tool.run({"query": "langchain"})

示例二:Python REPL执行python代码

工具介绍,查看官网:https://python.langchain.com/docs/integrations/tools/python/

需要安装依赖:pip install langchain_experimental,结合智能体开发使用

1
2
3
4
5
from langchain_experimental.utilities import PythonREPL

python_repl = PythonREPL() # 是可以直接运行Python代码的,会存在安全隐患,执行时会提示:Python REPL can execute arbitrary code. Use with caution.
res = python_repl.run("print(1+1)")
print(res)