LangChain ToolRuntime 怎么选三类数据

掘金热榜文章《LangChain ToolRuntime 入门:context、state 与 store 的实际用法》涉及了一个常见误区:把登录用户、会话消息和长期偏好全部塞进 State。这样短期或许能跑通,但数据生命周期一旦拉长,边界就会变得混乱。另一个误区是把 runtime.context 当成大模型上下文窗口,实际上前者是应用注入的运行依赖,后者才是模型实际接收到的消息与提示词。

Context 用于放置单次运行中相对稳定的身份、权限和外部依赖;State 用于放置当前会话执行中持续变化的消息、步骤结果和流程进度;Store 用于放置需要跨会话复用的偏好、记忆与资料。在 LangChain 1.x 中,这三类数据都可以通过 ToolRuntime 统一访问,分别对应 runtime.context、runtime.state 和 runtime.store。

ToolRuntime 是 LangChain 1.x 推荐的工具运行时接口。工具执行时,框架会自动注入 runtime 对象,不需要使用 Annotated,也不需要让模型填写这个参数。它不会出现在模型可调用的工具参数列表中,模型只需要理解工具能够完成什么操作。

Context、State 与 Store 的区别集中在生命周期、访问入口和模型可见边界。

数据入口 读写属性 生命周期 典型内容 访问方式 模型可见边界
Context 只读 单次 Agent 调用内保持稳定 用户 ID、租户、权限、外部服务连接 runtime.context 默认不会自动发送给模型,代码主动读取并加入提示词或工具结果后才会暴露
State 可读写 默认在当前 Agent 执行内维护;配置 Checkpointer 后可按会话线程恢复 消息、步骤结果、计数器、业务流程进度 runtime.state 由 Agent 的消息组装逻辑决定,并非整个状态都会自动暴露
Store 可读写 面向跨会话复用,实际保存时长取决于后端 用户偏好、长期记忆、跨会话资料 runtime.store 不会自动进入模型输入,需要先读取再使用

用户身份、租户信息和权限适合放进 Context。调用者在 Agent 启动时传入这些数据,节点、中间件和工具再通过 Runtime 获取,从而避免把用户 ID 或数据库连接硬编码进工具。Context 不会因为放进 Runtime 就自动进入模型输入;只有代码显式读取这些数据,并将其加入提示词或工具返回结果,模型才能看到其中的内容。

消息、步骤结果、计数器和流程进度适合放进 State,因为它们会在一次执行过程中不断变化。State 默认在当前 Agent 执行内维护;同一 thread_id 下的后续调用能否恢复这些数据,取决于是否配置 Checkpointer。

用户偏好、长期记忆和跨会话资料适合放进 Store。Store 与 State 的关键区别不是“能否持久化”,而是数据是否以跨会话复用为目标;Store 的实际保存周期仍取决于具体实现,参考实现包括 InMemoryStore、PostgresStore 等。

示例中的最小工具无需用 Annotated 声明 runtime 参数,工具只向模型暴露自己的用途;Context 用于身份校验,State 用于读取消息,Store 作为跨会话数据入口,具体读写接口则取决于所选后端。

from dataclasses import dataclass

from langchain.agents import create_agent
from langchain.tools import ToolRuntime, tool


@dataclass
class RequestContext:
    user_id: str
    tenant_id: str


@tool
def runtime_snapshot(runtime: ToolRuntime) -> str:
    context = runtime.context
    state = runtime.state
    store = runtime.store

    if not context.user_id or not context.tenant_id:
        return "missing runtime context"

    message_count = len(state.get("messages", []))
    return f"messages={message_count}; store_ready={store is not None}"


agent = create_agent(
    model=model,
    tools=[runtime_snapshot],
    context_schema=RequestContext,
)

实际选择时,可以按两个问题判断:这份数据在当前运行中会不会被修改?下一次会话是否还需要使用它?运行中保持稳定、只服务于本次调用的请求级依赖优先放入 Context;只服务于当前会话、需要持续变化的线程内进度放入 State;需要跨会话读写和复用、独立于单次会话保存的长期数据放入 Store。

Runtime Context、模型上下文窗口和 RunnableConfig 承担不同职责。Context 是应用提供的业务依赖,不是模型 token 窗口;runtime.config 对应 RunnableConfig,用于承载 thread_id 和模型运行参数,thread_id 也不能代替 Context 中的用户身份或租户信息。 旧教程中常见的 InjectedState、InjectedStore 仍可用于理解注入机制,但在 LangChain 1.x 中,ToolRuntime 是更统一的工具访问方式。

ToolRuntime 中的 tool_call_id、stream_writer 属于执行辅助字段,分别用于标识工具调用和辅助流式输出,不应被当作业务数据存储区。

ToolRuntime 统一了访问方式,却没有自动解决所有数据治理问题。Context 默认不进入模型输入,State 跨调用恢复依赖 Checkpointer,Store 的持久化能力取决于后端选型;生产环境中的会话恢复、长期存储、数据清理和租户隔离,仍然需要项目自行设计并验证。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容