【LangChain】langchain_core.tools 模块:创建、配置和管理工具

langchain_core.tools 模块详解

langchain_core.tools 是 LangChain 框架中用于定义和管理工具的核心模块,工具是代理(Agents)、链(Chains)或大语言模型(LLMs)与外部世界交互的接口。本文结合前文内容,详细介绍该模块的功能、主要组件、使用方法、实际应用及注意事项,确保内容条理清晰、易于理解。

1. 概述

1.1 什么是 langchain_core.tools

langchain_core.tools 模块提供了一套类和函数,用于创建、配置和管理工具。工具是封装特定功能的组件,例如数据检索、数学计算或 API 调用,允许语言模型通过调用工具与外部系统交互。该模块通过标准化的接口和灵活的配置选项,确保工具与 LangChain 的可运行对象(Runnable)生态系统无缝集成。

工具的核心作用是为模型提供结构化的调用接口,结合名称、描述和 JSON 模式,指导模型选择和使用工具。模块在 langchain-core 0.2.14 版本中引入,工件支持在 0.2.19 版本添加。

1.2 与其他组件的关系

  • BaseTool:前文讨论的 BaseTool 是模块中的核心抽象基类,所有工具都继承自它。
  • @tool 装饰器tool 装饰器是模块的实用函数,简化工具创建,自动将函数转换为 BaseTool 实例。
  • InjectedToolArg:模块支持通过 InjectedToolArg 标记运行时注入参数,增强安全性。
  • chain 装饰器:结合 langchain_core.runnables.chain,可在工具调用链中注入参数或处理工具输出。

1.3 核心功能

  • 工具定义:提供基类(如 BaseTool)和实现(如 ToolStructuredTool)以定义工具。
  • 输入验证:通过 Pydantic 模型验证工具输入,确保类型安全。
  • 运行时注入:支持通过 InjectedToolArg 注入敏感参数,防止模型生成。
  • 工件支持:工具可返回内容和工件(如图片、数据框),工件用于下游处理。
  • 灵活集成:工具与 LangChain Expression Language (LCEL) 兼容,可组成复杂链。
  • 版本要求:需 langchain-core>=0.2.14,工件支持需 >=0.2.19。

2. 模块结构与主要组件

以下是 langchain_core.tools 模块的主要组件,按类别组织:

2.1 基类和接口

组件描述
BaseTool抽象基类,所有工具的父类,继承自 RunnableSerializable。定义工具接口,包括同步(_run)和异步(_arun)执行方法,支持 invokebatchstream 等操作。
BaseToolkit工具包基类,用于组织一组相关工具,便于功能分组和管理。

2.2 工具实现

组件描述
Tool简单工具类,继承自 BaseTool,包装函数或协程,适合单一输入场景。
StructuredTool支持多参数输入的工具,使用 Pydantic 模式定义输入结构,适合复杂场景。
RetrieverInput输入模式(推测为 Pydantic 模型),用于定义检索器工具的输入结构。

2.3 注解和异常

组件描述
InjectedToolArg注解,标记不应由模型生成的参数,由运行时注入,增强安全性。
InjectedToolCallId注解(推测),用于注入工具调用 ID,可能用于跟踪或日志。
SchemaAnnotationErrorargs_schema 缺失或类型注解错误时抛出的异常。
ToolException工具执行错误时抛出的可选异常,用于错误处理。

2.4 实用函数

函数描述
tool装饰器或函数,将 Python 函数转换为工具,自动推断名称、描述和参数。
create_schema_from_function从函数签名创建 Pydantic 模式,用于定义工具输入结构。
get_all_basemodel_annotations获取 Pydantic BaseModel 及其父类的所有注解。
convert_runnable_to_tool将任何 Runnable 对象转换为 BaseTool,增强灵活性。
render_text_description生成工具名称和描述的文本,用于提示模型。
render_text_description_and_args生成工具名称、描述和参数的文本,用于提示模型。
create_retriever_tool创建文档检索工具,集成 LangChain 的检索器组件。

3. 使用方法

以下是 langchain_core.tools 模块的主要使用方式,结合前文内容展示具体示例:

3.1 继承 BaseTool

为复杂工具创建子类,定义 namedescriptionargs_schema 并实现 _run_arun

from langchain_core.tools import BaseTool
from pydantic import BaseModel, Field
from typing import Optional, Type
from langchain_core.callbacks import CallbackManagerForToolRun

class CalculatorInput(BaseModel):
    a: int = Field(description="第一个数字")
    b: int = Field(description="第二个数字")

class CustomCalculatorTool(BaseTool):
    name = "Calculator"
    description = "用于回答数学相关问题"
    args_schema: Type[BaseModel] = CalculatorInput
    return_direct: bool = True

    def _run(
        self,
        a: int,
        b: int,
        run_manager: Optional[CallbackManagerForToolRun] = None
    ) -> int:
        """执行工具"""
        return a * b

    async def _arun(
        self,
        a: int,
        b: int,
        run_manager: Optional[AsyncCallbackManagerForToolRun] = None
    ) -> int:
        """异步执行工具"""
        return self._run(a, b, run_manager=run_manager)

调用方式

tool = CustomCalculatorTool()
result = tool.invoke({"a": 2, "b": 3})  # 输出 6

3.2 使用 @tool 装饰器

简化工具创建,自动推断模式:

from langchain_core.tools import tool

@tool
def add_numbers(a: int, b: int) -> int:
    """添加两个数字"""
    return a + b

调用方式

result = add_numbers.invoke({"a": 2, "b": 3})  # 输出 5

3.3 结合 InjectedToolArg

标记运行时注入参数,增强安全性:

from langchain_core.tools import tool, InjectedToolArg
from typing import Annotated, List

@tool
def update_favorite_pets(pets: List[str], user_id: Annotated[str, InjectedToolArg]) -> None:
    """更新用户的收藏宠物"""
    user_to_pets[user_id] = pets  # 假设的存储

注入参数(结合 chain 装饰器):

from langchain_core.runnables import chain

@chain
def inject_user_id(input):
    """注入用户 ID 到工具调用"""
    tool_call = input["tool_call"]
    user_id = input["user_id"]
    tool_call_copy = tool_call.copy()
    tool_call_copy["args"]["user_id"] = user_id
    return {"tool_call": tool_call_copy}

chain = inject_user_id | update_favorite_pets
chain.invoke({"tool_call": {"name": "update_favorite_pets", "args": {"pets": ["dog"]}}, "user_id": "123"})

3.4 创建检索工具

使用 create_retriever_tool 创建文档检索工具:

from langchain_core.tools import create_retriever_tool
from langchain_core.vectorstores import VectorStoreRetriever

retriever = VectorStoreRetriever(...)  # 假设的检索器
tool = create_retriever_tool(
    retriever,
    name="search_documents",
    description="搜索相关文档"
)

4. 参数与配置

以下是模块中主要组件的关键参数:

4.1 BaseTool 初始化参数

参数类型默认值描述
args_schemaType[BaseModel] | NoneNonePydantic 模型,定义输入参数结构和验证。
descriptionstr无默认工具描述,指导模型使用。
return_directboolFalse若为 True,输出直接返回,代理停止处理。
response_formatLiteral['content', 'content_and_artifact']'content'输出格式:仅内容或内容加工件。
handle_tool_errorbool | str | CallableFalse处理 ToolException 的方式。

4.2 @tool 装饰器参数

参数类型默认值描述
name_or_callableOptional[str | Callable]None工具名称或可调用对象。
descriptionstr | NoneNone工具描述,优先级高于文档字符串。
return_directboolFalse若为 True,输出直接返回。
args_schemaType[BaseModel] | dict | NoneNone参数模式,定义输入结构。
response_formatLiteral['content', 'content_and_artifact']'content'输出格式。
parse_docstringboolFalse若为 True,解析 Google 风格文档字符串。
error_on_invalid_docstringboolTrue若为 True,无效文档字符串抛出错误。

5. 实际应用

langchain_core.tools 模块在以下场景中广泛使用:

  • 代理系统:为代理提供工具列表,代理根据输入选择工具。例如,数学计算工具、搜索工具。
  • 自定义工作流:在 LangGraph 或链中集成工具,实现模块化功能。例如,数据处理管道。
  • 工件处理:工具返回内容和工件,工件用于下游处理,如生成图片或数据框。
  • 运行时注入:结合 InjectedToolArg,为工具注入敏感参数,如用户 ID。

示例:综合应用

创建一个工具链,结合 InjectedToolArgchain 装饰器:

from langchain_core.tools import tool, InjectedToolArg
from langchain_core.runnables import chain
from typing import Annotated, List

@tool
def update_user_profile(name: str, user_id: Annotated[str, InjectedToolArg]) -> str:
    """更新用户配置文件"""
    return f"Updated profile for user {user_id} with name {name}"

@chain
def inject_user_id(input):
    """注入用户 ID"""
    return {**input, "user_id": "123"}

chain = inject_user_id | update_user_profile
result = chain.invoke({"name": "Alice"})  # 输出 "Updated profile for user 123 with name Alice"

6. 最佳实践

  • 清晰描述:为工具提供详细的 description,包含少样本示例,帮助模型选择。
  • 输入验证:使用 args_schema 定义和验证输入,确保类型安全。
  • 注入参数:结合 InjectedToolArg 保护敏感信息,防止模型生成。
  • 文档字符串:使用 Google 风格文档字符串,确保 parse_docstring=True 时正确解析。
  • 版本检查:确保安装 langchain-core>=0.2.14,工件支持需 >=0.2.19,通过 pip install -qU langchain

7. 注意事项与限制

  • 抽象方法:继承 BaseTool 时必须实现 _run,否则抛出 NotImplementedError
  • 文档字符串格式:若使用 parse_docstring=True,需正确格式化 Google 风格文档字符串,否则可能抛出 SchemaAnnotationError
  • 版本依赖:工件支持等功能需特定版本。
  • 工件格式:工件需为可序列化对象(如字典、字节)。
  • 类方法支持:在类方法上使用 @tool 可能需变通方法,建议使用 StructuredTool.from_function

8. 结论

langchain_core.tools 模块为 LangChain 提供了定义和管理工具的强大功能,通过基类(如 BaseTool)、工具实现(如 StructuredTool)和实用函数(如 @tool),支持开发者创建自定义工具并集成到复杂应用程序中。其支持输入验证、运行时注入和工件输出,确保工具的高效性和安全性。结合 InjectedToolArgchain 装饰器,模块在代理系统和自定义工作流中表现尤为出色。

9. 参考资料

<think>好的,我现在需要帮助用户了解如何将生成的图数据存储到Neo4j数据库中,特别是使用Neo4jGraph或Neo4jVector这两个工具。首先,我得确认用户的需求是什么。用户可能已经生成了图数据,现在需要将这些数据导入到Neo4j中,但可能不清楚具体步骤工具的使用方法。 首先,我应该回想一下Neo4j的基本操作。Neo4j是一个图数据库,通常使用Cypher查询语言来操作数据。用户提到的Neo4jGraphNeo4jVector可能是指某些库或工具,用于简化与Neo4j的交互。例如,在Python中,可能有相关的库如py2neo或官方提供的neo4j驱动,但用户提到的这两个名称可能属于特定的框架,比如LangChain中的组件?因为我知道LangChain有Neo4jGraphNeo4jVector的集成,用于处理知识图谱向量嵌入。 接下来,我需要确定用户使用的是哪种编程语言环境。假设是Python,因为Neo4jGraphNeo4jVector常见于Python生态中。用户可能已经通过某种方式生成了图数据,比如节点关系,现在需要将这些数据存储到Neo4j中。 首先,用户需要安装必要的库。比如,安装langchain库,或者直接使用neo4j的Python驱动。可能需要同时安装几个包,比如langchain_community中的相关模块,或者neo4j的官方驱动。 然后,用户需要连接到Neo4j数据库。这通常需要URI、用户名密码。需要确保Neo4j实例正在运行,并且用户有正确的访问权限。 接下来,使用Neo4jGraph来存储图数据。这里可能需要将节点关系转换成Cypher语句,或者利用库提供的API来添加数据。比如,使用add_graph方法,或者通过执行Cypher命令来创建节点关系。 对于Neo4jVector,这可能涉及到将向量数据存储到Neo4j中,用于支持向量搜索。比如,存储文本的嵌入向量,并建立索引以便进行相似性搜索。这可能需要使用特定的方法,如from_existing_graph来从现有图结构中创建向量索引,或者from_texts来直接导入文本向量。 在步骤中,可能需要示例代码来说明如何连接数据库、创建图对象、添加数据以及关闭连接。同时,需要注意异常处理资源释放,比如正确关闭驱动连接。 此外,用户可能需要了解如何验证数据是否成功导入,比如在Neo4j浏览器中执行MATCH查询来检查节点关系是否存在。 还需要考虑性能优化,比如批量插入数据而不是逐条插入,以提高效率。同时,索引的创建对于查询性能也很重要,特别是当处理大规模数据时。 最后,用户可能会有疑问,比如如何处理复杂的图结构,或者如何将现有数据转换为适合Neo4j的格式。可能需要提醒用户确保数据模型的正确性,节点关系的属性是否合理,以及是否需要建立索引或约束来优化查询。 总结一下,回答应该包括以下几个部分: 1. 环境准备:安装必要的库配置Neo4j连接。 2. 使用Neo4jGraph存储图结构数据,包括节点关系。 3. 使用Neo4jVector存储向量数据,支持向量搜索。 4. 示例代码验证步骤。 5. 注意事项常见问题。</think>以下是使用$Neo4jGraph$$Neo4jVector$存储图数据到Neo4j数据库的分步指南: ### 一、环境准备 1. 安装Python依赖库: ```bash pip install neo4j langchain langchain-community ``` 2. 启动Neo4j数据库并获取连接信息: - 默认URI:$bolt://localhost:7687$ - 用户名/密码:$neo4j/your_password$ ### 二、使用Neo4jGraph存储图结构 ```python from langchain_community.graphs import Neo4jGraph # 创建连接 graph = Neo4jGraph( url="bolt://localhost:7687", username="neo4j", password="your_password" ) # 定义图数据(节点+关系) cypher_query = ''' CREATE (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'}), (a)-[:FRIEND]->(b) ''' # 执行写入操作 graph.query(cypher_query) # 验证数据 result = graph.query("MATCH (p:Person) RETURN p.name") print(result) # 输出[{'p.name': 'Alice'}, {'p.name': 'Bob'}] # 关闭连接 graph.driver.close() ``` ### 三、使用Neo4jVector存储向量数据 ```python from langchain_community.vectorstores import Neo4jVector from langchain_openai import OpenAIEmbeddings # 创建向量存储 vector_store = Neo4jVector.from_texts( texts=["机器学习导论", "图数据库原理"], embedding=OpenAIEmbeddings(), url="bolt://localhost:7687", username="neo4j", password="your_password", index_name="knowledge_base", node_label="Document" ) # 执行向量搜索 results = vector_store.similarity_search("人工智能基础") print(results[0].page_content) # 输出"机器学习导论" ``` ### 四、最佳实践 1. 批量写入优化:使用$UNWIND$语句实现批量插入 ```cypher UNWIND $batch AS row CREATE (n:Node {id: row.id}) ``` 2. 索引加速:创建索引提高查询性能 ```python graph.query("CREATE INDEX FOR (n:Person) ON (n.name)") ``` 3. 数据验证:通过Neo4j Browser执行$MATCH (n) RETURN n LIMIT 25$可视化验证
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彬彬侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值