学习笔记 · Obsidian

LangChain TypeScript:Middleware、Context、Runtime 与 HITL

LangChainTypeScript

Context engineering 的核心

Agent 质量往往受“模型在某一步看到了什么”支配,而不只是 model 大小。应分别设计三类数据:

数据生命周期典型载体
Runtime context单次调用稳定、通常只读contextSchema + invoke 的 { context }
Short-term state同一 thread 持久、每一步演化agent state + checkpointer
Long-term memory跨 thread/会话共享store 的 namespace + key

另有 model context:真正送入当前模型调用的 prompt、messages、tools 与 schemas。Middleware 的价值就是在适当生命周期读取数据,并只把本步需要的信息投影到 model context。

Runtime:依赖注入,不是全局变量袋

工具和 middleware 可通过 runtime 读取:

  • context:用户/租户、数据库句柄、feature flags 等调用级依赖;
  • state:当前 thread 的 checkpointed 数据;
  • store:长期记忆;
  • streamWriter:自定义进度;
  • executionInfo:thread ID、run ID 等执行身份;
  • serverInfo:LangGraph Server 上的 assistant、authenticated user 等服务端信息。

serverInfo 在本地非 Agent Server 环境为 null。executionInfo/serverInfo 要求 `deepagents >= 1.9.0` 或 `@langchain/langgraph >= 1.2.8`。认证逻辑必须处理“字段不存在”和“本地运行”两条分支,不能从 prompt 中的 user ID 推断身份。

TypeScript 的 contextSchema 若包含必填字段,agent.invoke 会在编译期要求传入;这能减少漏参,但外部请求仍需运行时校验。

Middleware 生命周期与顺序

Node-style hooks:

  • beforeAgent / afterAgent:整个 run 前后;
  • beforeModel / afterModel:每次 model call 前后。

Wrap hooks:

  • wrapModelCall(request, handler):模型选择、prompt、tools、retry/fallback、响应处理;
  • wrapToolCall(request, handler):鉴权、参数处理、timeout、重试、错误转换、审计。

多 middleware 的顺序是:before hooks 按数组正序,after hooks 逆序;wrap 形成洋葱模型,第一个 middleware 位于最外层。顺序会改变语义,例如 PII redaction 应先于日志;timeout 与 retry 的内外关系决定“每次重试超时”还是“整个操作总超时”。应把顺序作为测试契约。

Node hook 返回 state update;wrap hook 要更新 state 时返回 Command。StateSchema 可以用 ReducedValue 描述合并;以下划线开头的私有字段不会出现在最终 agent 结果中,但仍可能存在运行内存/trace,不能当加密机制。

canJumpTo 允许 middleware 跳到 model、tools 或 end。Jump 是控制流能力,应避免在多个 middleware 中隐式竞争。

自定义 middleware 的选择

简单、无配置逻辑可直接使用 hook factory;需要共享状态、复杂配置、多个 hooks 或可复用包时用 createMiddleware。典型生产场景:

  • 动态 system prompt / model routing;
  • 按租户过滤 tools;
  • model/tool retry、fallback、circuit breaker;
  • 预算、调用次数和 token 限制;
  • 输入/输出审核与 PII 处理;
  • trace tags、业务指标和自定义 stream projection。

Middleware 注册 stream transformer 要求 `[email protected]+`。Transformer 应是可组合、顺序明确、支持取消的异步管道。

预置 middleware 地图

类别能力边界
Contextsummarization、context editing压缩有损;阈值依赖 model profile 或显式 token 配置
Human controlHITL必须 checkpointer + thread;恢复需原 checkpoint
Budgetsmodel/tool call limit、to-do list需要定义 run/thread 计数语义
Reliabilitymodel fallback、model/tool retry、tool error有限重试;副作用工具必须幂等
SafetyPII detection/redaction/block、guardrails规则与模型审核互补;日志链路也要脱敏
Tool selectionLLM tool selector、provider tool search/emulator额外模型调用或 provider 依赖可能增加成本
Deep-agent harnessfilesystem、subagent来自 deepagents;backend、sandbox、持久性和权限另行设计

“production-ready”表示实现可配置,不表示默认配置自动满足业务合规、SLA 和安全要求。

Guardrails:确定性规则优先

Guardrail 可作用于输入、模型前后、工具前后:

  • 规则型检查适合权限、允许列表、金额/路径限制、schema、正则 PII;
  • 模型型审核适合语义风险,但有延迟、费用和误判;
  • 高风险副作用最终由工具服务端再鉴权,middleware 不是唯一防线。

处理策略可以 block、redact/mask、替换安全回复、抛出错误或 interrupt。必须明确用户可见错误、内部审计、重试和恢复路径,避免 redaction 后数据仍从 trace/异常/自定义事件泄漏。

HITL 的状态机

humanInTheLoopMiddleware 按 interruptOn 对工具配置审批。每个工具可允许:

  • allowAccept:批准原动作;
  • allowEdit:修改参数后执行;
  • allowRespond:不执行工具,直接提供反馈。

必要条件:checkpointer、稳定 thread_id、持久保存 interrupt/checkpoint、恢复时使用 Command({ resume: ... })。同一 turn 有多个被暂停工具时,每个 action 都要对应一项 decision,顺序和数量必须一致。

安全边界:

  • edit 后必须重新 schema 校验和鉴权;
  • 审批 UI 只能把服务端返回的允许动作展示给有权 reviewer;
  • 执行恢复可能重复到达,副作用需要幂等 key;
  • checkpoint/store 要有租户隔离、保留期和审计;
  • timeout/拒绝/无人审批必须有终态。

重要 JS 差异:条件式 `when`/conditional interrupt 当前仅 Python 支持。 TypeScript 页面虽混入 interrupt_on、v2 Python 风格说明,JS 实现应使用实际 interruptOn 与上述 allow 选项,不要宣称具备 Python-only 条件策略。

路由与文档边界

/oss/javascript/langchain/middleware 是可点击别名,当前 308 到 /middleware/overview,所以 sources 同时记录别名和正文;它不代表额外的 middleware 语义。文档数处混入 Python 参数名/代码块,属于模板复用缺陷,不能作为 TypeScript API 契约。

逐页覆盖

页面学习结论
Context engineeringruntime context、state、store 与 model context 的生命周期和读写方式。
Middleware overviewagent/model/tool hooks、控制流、顺序与常见用途。
Built-in middlewaresummary、HITL、limits、fallback/retry、PII、todo、tool selection、filesystem、subagent。
Custom middlewarehook/createMiddleware、StateSchema、Command、stream transformer 与 context typing。
Runtimecontext/state/store/stream writer、executionInfo/serverInfo 及版本要求。
GuardrailsPII、规则/模型检查、block/redact/HITL 和分层安全。
Human-in-the-loopinterrupt policy、accept/edit/respond、checkpoint 和恢复协议;conditional JS 缺口。

延伸