在LangChain中传递运行时值给工具

在使用LangChain开发智能应用时,我们经常需要将一些运行时的参数传递给工具。这些参数可能在请求时才被确定,比如请求用户的ID。在大多数情况下,这些参数不应该由LLM(大语言模型)控制,因为这样可能存在安全风险。因此,我们需要一种机制,让LLM只控制那些它需要控制的参数,而其他参数则由应用逻辑来固定。

本指南将详细介绍如何在LangChain中实现这一点,即防止模型生成某些工具参数,并在运行时进行直接注入。

1. 技术背景介绍

LangChain是一个用于构建基于大语言模型应用的开源框架。它允许开发者创建工具并与模型进行交互。在实际应用中,我们需要确保某些参数仅由应用逻辑来控制,而不是由模型生成,比如用户的ID。

2. 核心原理解析

通过使用InjectedToolArg注解,我们可以标记某些工具参数(如user_id)为运行时注入,这意味着这些参数不应由模型生成。

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

user_to_pets = {}

@tool(parse_docstring=True)
def update_favorite_pets(
    pets: List[str], user_id: Annotated[str, InjectedToolArg]
) -> None:
    """Add the list of favorite pets."""
    user_to_pets[user_id] = pets

在上面的代码中,我们使用AnnotatedInjectedToolArg标记了user_id参数,这样模型调用工具时,这个参数就不会被生成。

3. 代码实现演示

以下代码展示了如何设置和调用工具,同时注入运行时参数user_id

# 设置用户ID
user_id = "123"

# 调用工具并传递运行时参数
update_favorite_pets.invoke({"pets": ["lizard", "dog"], "user_id": user_id})
print(user_to_pets)  # 输出: {'123': ['lizard', 'dog']}

# 当模型调用工具时,不会生成user_id参数
tools = [
    update_favorite_pets,
    # ... 其他工具
]

# 注入user_id参数的工具链
from langchain_core.runnables import chain
from copy import deepcopy

@chain
def inject_user_id(ai_msg):
    tool_calls = []
    for tool_call in ai_msg.tool_calls:
        tool_call_copy = deepcopy(tool_call)
        tool_call_copy["args"]["user_id"] = user_id
        tool_calls.append(tool_call_copy)
    return tool_calls

4. 应用场景分析

这种机制非常适用于需要在多用户环境中管理个性化数据的场景。例如,聊天机器人需要根据用户ID来获取或更新用户的个性化设置,而不需要模型关心用户ID。

5. 实践建议

  • 确保所有需要注入的参数都使用InjectedToolArg进行标记,以避免安全问题。
  • 在生产环境中,考虑使用安全的参数传递机制,以保护用户隐私。

结束语:如果遇到问题欢迎在评论区交流。
—END—

你可能感兴趣的:(langchain,windows,python)