LangChain 提供了针对常见用例的预构建 middleware。每个 middleware 都已准备好用于生产环境,并可根据您的特定需求进行配置。

提供商无关的 Middleware

以下 middleware 适用于任何 LLM 提供商:
Middleware Description
Summarization Automatically summarize conversation history when approaching token limits.
Human-in-the-loop Pause execution for human approval of tool calls.
Model call limit Limit the number of model calls to prevent excessive costs.
Tool call limit Control tool execution by limiting call counts.
Model fallback Automatically fallback to alternative models when primary fails.
PII detection Detect and handle Personally Identifiable Information (PII).
To-do list Equip agents with task planning and tracking capabilities.
LLM tool selector Use an LLM to select relevant tools before calling main model.
Tool retry Automatically retry failed tool calls with exponential backoff.
Model retry Automatically retry failed model calls with exponential backoff.
LLM tool emulator Emulate tool execution using an LLM for testing purposes.
Context editing Manage conversation context by trimming or clearing tool uses.

Summarization

当接近 token 限制时自动总结对话历史,在压缩较旧上下文的同时保留最近的消息。总结功能适用于以下场景:
  • 超过上下文窗口的长时间对话。
  • 具有大量历史记录的多轮对话。
  • 需要保留完整对话上下文的应用程序。
import { createAgent, summarizationMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-4o",
  tools: [weatherTool, calculatorTool],
  middleware: [
    summarizationMiddleware({
      model: "gpt-4o-mini",
      trigger: { tokens: 4000 },
      keep: { messages: 20 },
    }),
  ],
});
The fraction conditions for trigger and keep (shown below) rely on a chat model’s profile data if using [email protected] . If data are not available, use another condition or specify manually:
const customProfile: ModelProfile = {
    maxInputTokens: 100_000,
    // ...
}
model = await initChatModel("...", {
    profile: customProfile,
});
model
string | BaseChatModel
required
Model for generating summaries. Can be a model identifier string (e.g., 'openai:gpt-4o-mini' ) or a BaseChatModel instance.
trigger
object | object[]
Conditions for triggering summarization. Can be:
  • A single condition object (all properties must be met - AND logic)
  • An array of condition objects (any condition must be met - OR logic)
Each condition can include:
  • fraction (number): Fraction of model’s context size (0-1)
  • tokens (number): Absolute token count
  • messages (number): Message count
At least one property must be specified per condition. If not provided, summarization will not trigger automatically.
keep
object
default: "{messages: 20}"
How much context to preserve after summarization. Specify exactly one of:
  • fraction (number): Fraction of model’s context size to keep (0-1)
  • tokens (number): Absolute token count to keep
  • messages (number): Number of recent messages to keep
tokenCounter
function
Custom token counting function. Defaults to character-based counting.
summaryPrompt
string
Custom prompt template for summarization. Uses built-in template if not specified. The template should include {messages} placeholder where conversation history will be inserted.
trimTokensToSummarize
number
default: "4000"
Maximum number of tokens to include when generating the summary. Messages will be trimmed to fit this limit before summarization.
summaryPrefix
string
Prefix to add to the summary message. If not provided, a default prefix is used.
maxTokensBeforeSummary
number
deprecated
Deprecated: Use trigger: { tokens: value } instead. Token threshold for triggering summarization.
messagesToKeep
number
deprecated
Deprecated: Use keep: { messages: value } instead. Recent messages to preserve.
The summarization middleware monitors message token counts and automatically summarizes older messages when thresholds are reached. Trigger conditions control when summarization runs:
  • Single condition object (all properties must be met - AND logic)
  • Array of conditions (any condition must be met - OR logic)
  • Each condition can use fraction (of model’s context size), tokens (absolute count), or messages (message count)
Keep conditions control how much context to preserve (specify exactly one):
  • fraction - Fraction of model’s context size to keep
  • tokens - Absolute token count to keep
  • messages - Number of recent messages to keep
import { createAgent, summarizationMiddleware } from "langchain";

// Single condition
const agent = createAgent({
  model: "gpt-4o",
  tools: [weatherTool, calculatorTool],
  middleware: [
    summarizationMiddleware({
      model: "gpt-4o-mini",
      trigger: { tokens: 4000, messages: 10 },
      keep: { messages: 20 },
    }),
  ],
});

// Multiple conditions
const agent2 = createAgent({
  model: "gpt-4o",
  tools: [weatherTool, calculatorTool],
  middleware: [
    summarizationMiddleware({
      model: "gpt-4o-mini",
      trigger: [
        { tokens: 3000, messages: 6 },
      ],
      keep: { messages: 20 },
    }),
  ],
});

// Using fractional limits
const agent3 = createAgent({
  model: "gpt-4o",
  tools: [weatherTool, calculatorTool],
  middleware: [
    summarizationMiddleware({
      model: "gpt-4o-mini",
      trigger: { fraction: 0.8 },
      keep: { fraction: 0.3 },
    }),
  ],
});

Human-in-the-loop

Pause agent execution for human approval, editing, or rejection of tool calls before they execute. Human-in-the-loop is useful for the following:
  • High-stakes operations requiring human approval (e.g. database writes, financial transactions).
  • Compliance workflows where human oversight is mandatory.
  • Long-running conversations where human feedback guides the agent.
Human-in-the-loop middleware requires a checkpointer to maintain state across interruptions.
import { createAgent, humanInTheLoopMiddleware } from "langchain";

function readEmailTool(emailId: string): string {
  /** Mock function to read an email by its ID. */
  return `Email content for ID: ${emailId}`;
}

function sendEmailTool(recipient: string, subject: string, body: string): string {
  /** Mock function to send an email. */
  return `Email sent to ${recipient} with subject '${subject}'`;
}

const agent = createAgent({
  model: "gpt-4o",
  tools: [readEmailTool, sendEmailTool],
  middleware: [
    humanInTheLoopMiddleware({
      interruptOn: {
        sendEmailTool: {
          allowedDecisions: ["approve", "edit", "reject"],
        },
        readEmailTool: false,
      }
    })
  ]
});
For complete examples, configuration options, and integration patterns, see the Human-in-the-loop documentation .
Watch this video guide demonstrating Human-in-the-loop middleware behavior.

Model call limit

限制模型调用次数以防止无限循环或过高成本。模型调用限制适用于以下场景:
  • 防止失控的智能体发起过多 API 调用。
  • 在生产部署中实施成本控制。
  • 在特定调用预算内测试智能体行为。
import { createAgent, modelCallLimitMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-4o",
  tools: [],
  middleware: [
    modelCallLimitMiddleware({
      threadLimit: 10,
      runLimit: 5,
      exitBehavior: "end",
    }),
  ],
});
Watch this video guide demonstrating Model Call Limit middleware behavior.
threadLimit
number
Maximum model calls across all runs in a thread. Defaults to no limit.
runLimit
number
Maximum model calls per single invocation. Defaults to no limit.
exitBehavior
string
default: "end"
Behavior when limit is reached. Options: 'end' (graceful termination) or 'error' (throw exception)

Tool call limit

通过限制工具调用次数来控制智能体执行,可以是全局限制所有工具或针对特定工具。工具调用限制适用于以下场景:
  • 防止对昂贵外部 API 的过度调用。
  • 限制网络搜索或数据库查询。
  • 对特定工具的使用实施速率限制。
  • 防止智能体陷入无限循环。
import { createAgent, toolCallLimitMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-4o",
  tools: [searchTool, databaseTool],
  middleware: [
    toolCallLimitMiddleware({ threadLimit: 20, runLimit: 10 }),
    toolCallLimitMiddleware({
      toolName: "search",
      threadLimit: 5,
      runLimit: 3,
    }),
  ],
});
Watch this video guide demonstrating Tool Call Limit middleware behavior.
toolName
string
要限制的特定工具名称。如果未提供,限制将应用于 所有工具(全局)
threadLimit
number
线程(对话)中所有运行的最大工具调用次数。在具有相同线程 ID 的多次调用之间保持持久。需要检查点管理器来维护状态。 undefined 表示无线程限制。
runLimit
number
每次单独调用(一条用户消息 → 响应周期)的最大工具调用次数。每收到新的用户消息时重置。 undefined 表示无运行限制。 注意: 必须至少指定 threadLimit runLimit 其中之一。
exitBehavior
string
default: "continue"
达到限制时的行为:
  • 'continue' (默认)- 用错误消息阻止超出限制的工具调用,允许其他工具和模型继续执行。模型根据错误消息决定何时结束。
  • 'error' - 抛出 ToolCallLimitExceededError 异常,立即停止执行
  • 'end' - 立即停止执行,并为超出限制的工具调用返回 ToolMessage 和 AI 消息。仅在限制单个工具时有效;如果其他工具有待处理的调用则抛出错误。
通过以下方式指定限制:
  • 线程限制 - 对话中所有运行的最大调用次数(需要检查点管理器)
  • 运行限制 - 每次单独调用的最大调用次数(每轮重置)
退出行为:
  • 'continue' (默认)- 用错误消息阻止超出限制的调用,智能体继续执行
  • 'error' - 立即抛出异常
  • 'end' - 使用 ToolMessage + AI 消息停止(仅限单工具场景)
import { createAgent, toolCallLimitMiddleware } from "langchain";

const globalLimiter = toolCallLimitMiddleware({ threadLimit: 20, runLimit: 10 });
const searchLimiter = toolCallLimitMiddleware({ toolName: "search", threadLimit: 5, runLimit: 3 });
const databaseLimiter = toolCallLimitMiddleware({ toolName: "query_database", threadLimit: 10 });
const strictLimiter = toolCallLimitMiddleware({ toolName: "scrape_webpage", runLimit: 2, exitBehavior: "error" });

const agent = createAgent({
  model: "gpt-4o",
  tools: [searchTool, databaseTool, scraperTool],
  middleware: [globalLimiter, searchLimiter, databaseLimiter, strictLimiter],
});

Model fallback

当主模型失败时自动回退到替代模型。模型回退适用于以下场景:
  • 构建能够处理模型故障的弹性智能体。
  • 通过回退到更便宜的模型来优化成本。
  • 跨 OpenAI、Anthropic 等提供商的冗余。
import { createAgent, modelFallbackMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-4o",
  tools: [],
  middleware: [
    modelFallbackMiddleware(
      "gpt-4o-mini",
      "claude-3-5-sonnet-20241022"
    ),
  ],
});
该中间件接受可变数量的字符串参数,按顺序表示回退模型:
...models
string[]
required
One or more fallback model strings to try in order when the primary model fails
modelFallbackMiddleware(
  "first-fallback-model",
  "second-fallback-model",
  // ... more models
)

PII detection

使用可配置策略检测和处理对话中的个人身份信息 (PII)。PII 检测适用于以下场景:
  • 具有合规要求的医疗和金融应用程序。
  • 需要清理日志的客服智能体。
  • Any application handling sensitive user data.
import { createAgent, piiMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-4o",
  tools: [],
  middleware: [
    piiMiddleware("email", { strategy: "redact", applyToInput: true }),
    piiMiddleware("credit_card", { strategy: "mask", applyToInput: true }),
  ],
});

Custom PII types

您可以通过提供 detector 参数来创建自定义 PII 类型。这使您能够检测超出内置类型的特定用例模式。 创建自定义检测器的三种方式:
  1. Regex pattern string - Simple pattern matching
  2. RegExp object - More control over regex flags
  3. Custom function - Complex detection logic with validation
import { createAgent, piiMiddleware, type PIIMatch } from "langchain";

// Method 1: Regex pattern string
const agent1 = createAgent({
  model: "gpt-4o",
  tools: [],
  middleware: [
    piiMiddleware("api_key", {
      detector: "sk-[a-zA-Z0-9]{32}",
      strategy: "block",
    }),
  ],
});

// Method 2: RegExp object
const agent2 = createAgent({
  model: "gpt-4o",
  tools: [],
  middleware: [
    piiMiddleware("phone_number", {
      detector: /\+?\d{1,3}[\s.-]?\d{3,4}[\s.-]?\d{4}/,
      strategy: "mask",
    }),
  ],
});

// Method 3: Custom detector function
function detectSSN(content: string): PIIMatch[] {
  const matches: PIIMatch[] = [];
  const pattern = /\d{3}-\d{2}-\d{4}/g;
  let match: RegExpExecArray | null;

  while ((match = pattern.exec(content)) !== null) {
    const ssn = match[0];
    // Validate: first 3 digits shouldn't be 000, 666, or 900-999
    const firstThree = parseInt(ssn.substring(0, 3), 10);
    if (firstThree !== 0 && firstThree !== 666 && !(firstThree >= 900 && firstThree <= 999)) {
      matches.push({
        text: ssn,
        start: match.index ?? 0,
        end: (match.index ?? 0) + ssn.length,
      });
    }
  }
  return matches;
}

const agent3 = createAgent({
  model: "gpt-4o",
  tools: [],
  middleware: [
    piiMiddleware("ssn", {
      detector: detectSSN,
      strategy: "hash",
    }),
  ],
});
自定义检测器函数签名: 检测器函数必须接受一个字符串(内容)并返回匹配结果: 返回 PIIMatch 对象数组:
interface PIIMatch {
  text: string;    // The matched text
  start: number;   // Start index in content
  end: number;      // End index in content
}

function detector(content: string): PIIMatch[] {
  return [
    { text: "matched_text", start: 0, end: 12 },
    // ... more matches
  ];
}
对于自定义检测器:
  • 对于简单模式使用正则表达式字符串
  • 当需要标志位时使用 RegExp 对象(例如,不区分大小写匹配)
  • 当需要超出模式匹配的验证逻辑时使用自定义函数
  • 自定义函数让您完全控制检测逻辑,并可实现复杂的验证规则
piiType
string
required
要检测的 PII 类型。可以是内置类型( email credit_card ip mac_address url )或自定义类型名称。
strategy
string
default: "redact"
如何处理检测到的 PII。选项:
  • 'block' - 检测到时抛出错误
  • 'redact' - 替换为 [REDACTED_TYPE]
  • 'mask' - 部分掩码(例如, ****-****-****-1234
  • 'hash' - 替换为确定性哈希值(例如, <email_hash:a1b2c3d4>
detector
RegExp | string | function
自定义检测器。可以是:
  • RegExp - 用于匹配的正则表达式模式
  • string - 正则表达式模式字符串(例如, "sk-[a-zA-Z0-9]{32}"
  • function - 自定义检测器函数 (content: string) => PIIMatch[]
如果未提供,则使用该 PII 类型的内置检测器。
applyToInput
boolean
default: "true"
在模型调用前检查用户消息
applyToOutput
boolean
default: "false"
在模型调用后检查 AI 消息
applyToToolResults
boolean
default: "false"
执行后检查工具结果消息

To-do list

为智能体配备任务规划和跟踪能力,用于复杂的多步骤任务。待办事项列表适用于以下场景:
  • 需要跨多个工具协调的复杂多步骤任务。
  • 需要进度可见性的长时间运行操作。
此中间件自动为智能体提供 write_todos 工具和系统提示,以指导有效的任务规划。
import { createAgent, todoListMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-4o",
  tools: [readFile, writeFile, runTests],
  middleware: [todoListMiddleware()],
});
观看此 视频指南 演示待办事项列表中间件的行为。
没有可用的配置选项(使用默认值)。

LLM tool selector

使用 LLM 在调用主模型之前智能选择相关工具。LLM 工具选择器适用于以下场景:
  • 拥有多个工具(10+)的智能体,其中大多数工具与每个查询无关。
  • 通过过滤无关工具来减少 token 使用量。
  • 提高模型的专注度和准确性。
此中间件使用结构化输出来询问 LLM 哪些工具与当前查询最相关。结构化输出模式定义了可用的工具名称和描述。模型提供商通常会在后台将此结构化输出信息添加到系统提示中。
import { createAgent, llmToolSelectorMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-4o",
  tools: [tool1, tool2, tool3, tool4, tool5, ...],
  middleware: [
    llmToolSelectorMiddleware({
      model: "gpt-4o-mini",
      maxTools: 3,
      alwaysInclude: ["search"],
    }),
  ],
});
model
string | BaseChatModel
Model for tool selection. Can be a model identifier string (e.g., 'openai:gpt-4o-mini' ) or a BaseChatModel instance. Defaults to the agent’s main model.
systemPrompt
string
选择模型的指令。如果未指定,则使用内置提示。
maxTools
number
要选择的最大工具数量。如果模型选择了更多,则只使用前 maxTools 个。如果未指定则无限制。
alwaysInclude
string[]
无论选择结果如何都始终包含的工具名称。这些不计入 maxTools 限制。

Tool retry

使用可配置的指数退避自动重试失败的工具调用。工具重试适用于以下场景:
  • 处理外部 API 调用中的瞬时故障。
  • 提高依赖网络的工具的可靠性。
  • 构建能够优雅处理临时错误的弹性智能体。
API 参考: toolRetryMiddleware
import { createAgent, toolRetryMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-4o",
  tools: [searchTool, databaseTool],
  middleware: [
    toolRetryMiddleware({
      maxRetries: 3,
      backoffFactor: 2.0,
      initialDelayMs: 1000,
    }),
  ],
});
maxRetries
number
default: "2"
Maximum number of retry attempts after the initial call (3 total attempts with default). Must be >= 0.
tools
(ClientTool | ServerTool | string)[]
Optional array of tools or tool names to apply retry logic to. Can be a list of BaseTool instances or tool name strings. If undefined , applies to all tools.
retryOn
((error: Error) => boolean) | (new (...args: any[]) => Error)[]
default: "() => true"
Either an array of error constructors to retry on, or a function that takes an error and returns true if it should be retried. Default is to retry on all errors.
onFailure
'error' | 'continue' | ((error: Error) => string)
default: "continue"
Behavior when all retries are exhausted. Options:
  • 'continue' (default) - Return a ToolMessage with error details, allowing the LLM to handle the failure and potentially recover
  • 'error' - Re-raise the exception, stopping agent execution
  • Custom function - Function that takes the exception and returns a string for the ToolMessage content, allowing custom error formatting
Deprecated values: 'raise' (use 'error' instead) and 'return_message' (use 'continue' 代替)。这些已弃用的值仍然有效,但会显示警告。
backoffFactor
number
default: "2.0"
指数退避的乘数。每次重试等待 initialDelayMs * (backoffFactor ** retryNumber) 毫秒。设置为 0.0 表示固定延迟。必须 >= 0。
initialDelayMs
number
default: "1000"
首次重试前的初始延迟(毫秒)。必须 >= 0。
maxDelayMs
number
default: "60000"
重试之间的最大延迟(毫秒),限制指数退避增长。必须 >= 0。
jitter
boolean
default: "true"
是否为延迟添加随机抖动( ±25% )以避免惊群效应
该中间件使用指数退避自动重试失败的工具调用。 关键配置:
  • maxRetries - 重试尝试次数(默认:2)
  • backoffFactor - 指数退避乘数(默认:2.0)
  • initialDelayMs - 起始延迟(毫秒)(默认:1000ms)
  • maxDelayMs - 延迟增长上限(默认:60000ms)
  • jitter - 添加随机变化(默认:true)
失败处理:
  • onFailure: "continue" (默认)- 返回错误消息
  • onFailure: "error" - 重新抛出异常
  • 自定义函数 - 返回错误消息的函数
import { createAgent, toolRetryMiddleware } from "langchain";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

// Basic usage with default settings (2 retries, exponential backoff)
const agent = createAgent({
  model: "gpt-4o",
  tools: [searchTool, databaseTool],
  middleware: [toolRetryMiddleware()],
});

// Retry specific exceptions only
const retry = toolRetryMiddleware({
  maxRetries: 4,
  retryOn: [TimeoutError, NetworkError],
  backoffFactor: 1.5,
});

// Custom exception filtering
function shouldRetry(error: Error): boolean {
  // Only retry on 5xx errors
  if (error.name === "HTTPError" && "statusCode" in error) {
    const statusCode = (error as any).statusCode;
    return 500 <= statusCode && statusCode < 600;
  }
  return false;
}

const retryWithFilter = toolRetryMiddleware({
  maxRetries: 3,
  retryOn: shouldRetry,
});

// Apply to specific tools with custom error handling
const formatError = (error: Error) =>
  "Database temporarily unavailable. Please try again later.";

const retrySpecificTools = toolRetryMiddleware({
  maxRetries: 4,
  tools: ["search_database"],
  onFailure: formatError,
});

// Apply to specific tools using BaseTool instances
const searchDatabase = tool(
  async ({ query }) => {
    // Search implementation
    return results;
  },
  {
    name: "search_database",
    description: "Search the database",
    schema: z.object({ query: z.string() }),
  }
);

const retryWithToolInstance = toolRetryMiddleware({
  maxRetries: 4,
  tools: [searchDatabase], // Pass BaseTool instance
});

// Constant backoff (no exponential growth)
const constantBackoff = toolRetryMiddleware({
  maxRetries: 5,
  backoffFactor: 0.0, // No exponential growth
  initialDelayMs: 2000, // Always wait 2 seconds
});

// Raise exception on failure
const strictRetry = toolRetryMiddleware({
  maxRetries: 2,
  onFailure: "error", // Re-raise exception instead of returning message
});

Model retry

使用可配置的指数退避自动重试失败的模型调用。模型重试适用于以下场景:
  • 处理模型 API 调用中的瞬时故障。
  • 提高依赖网络的模型请求的可靠性。
  • 构建能够优雅处理临时模型错误的弹性智能体。
API reference: modelRetryMiddleware
import { createAgent, modelRetryMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-4o",
  tools: [searchTool, databaseTool],
  middleware: [
    modelRetryMiddleware({
      maxRetries: 3,
      backoffFactor: 2.0,
      initialDelayMs: 1000,
    }),
  ],
});
maxRetries
number
default: "2"
Maximum number of retry attempts after the initial call (3 total attempts with default). Must be >= 0.
retryOn
((error: Error) => boolean) | (new (...args: any[]) => Error)[]
default: "() => true"
Either an array of error constructors to retry on, or a function that takes an error and returns true if it should be retried. Default is to retry on all errors.
onFailure
'error' | 'continue' | ((error: Error) => string)
default: "continue"
Behavior when all retries are exhausted. Options:
  • 'continue' (default) - Return an AIMessage with error details, allowing the agent to potentially handle the failure gracefully
  • 'error' - Re-raise the exception, stopping agent execution
  • Custom function - Function that takes the exception and returns a string for the AIMessage content, allowing custom error formatting
backoffFactor
number
default: "2.0"
指数退避的乘数。每次重试等待 initialDelayMs * (backoffFactor ** retryNumber) 毫秒。设置为 0.0 表示固定延迟。必须 >= 0。
initialDelayMs
number
default: "1000"
首次重试前的初始延迟(毫秒)。必须 >= 0。
maxDelayMs
number
default: "60000"
重试之间的最大延迟(毫秒),限制指数退避增长。必须 >= 0。
jitter
boolean
default: "true"
是否为延迟添加随机抖动( ±25% )以避免惊群效应
该中间件使用指数退避自动重试失败的模型调用。
import { createAgent, modelRetryMiddleware } from "langchain";

// Basic usage with default settings (2 retries, exponential backoff)
const agent = createAgent({
  model: "gpt-4o",
  tools: [searchTool],
  middleware: [modelRetryMiddleware()],
});

class TimeoutError extends Error {
    // ...
}
class NetworkError extends Error {
    // ...
}

// Retry specific exceptions only
const retry = modelRetryMiddleware({
  maxRetries: 4,
  retryOn: [TimeoutError, NetworkError],
  backoffFactor: 1.5,
});

// Custom exception filtering
function shouldRetry(error: Error): boolean {
  // Only retry on rate limit errors
  if (error.name === "RateLimitError") {
    return true;
  }
  // Or check for specific HTTP status codes
  if (error.name === "HTTPError" && "statusCode" in error) {
    const statusCode = (error as any).statusCode;
    return statusCode === 429 || statusCode === 503;
  }
  return false;
}

const retryWithFilter = modelRetryMiddleware({
  maxRetries: 3,
  retryOn: shouldRetry,
});

// Return error message instead of raising
const retryContinue = modelRetryMiddleware({
  maxRetries: 4,
  onFailure: "continue", // Return AIMessage with error instead of throwing
});

// Custom error message formatting
const formatError = (error: Error) =>
  `Model call failed: ${error.message}. Please try again later.`;

const retryWithFormatter = modelRetryMiddleware({
  maxRetries: 4,
  onFailure: formatError,
});

// Constant backoff (no exponential growth)
const constantBackoff = modelRetryMiddleware({
  maxRetries: 5,
  backoffFactor: 0.0, // No exponential growth
  initialDelayMs: 2000, // Always wait 2 seconds
});

// Raise exception on failure
const strictRetry = modelRetryMiddleware({
  maxRetries: 2,
  onFailure: "error", // Re-raise exception instead of returning message
});

LLM tool emulator

使用 LLM 模拟工具执行以进行测试,用 AI 生成的响应替代实际工具调用。LLM 工具模拟器适用于以下场景:
  • 在不执行真实工具的情况下测试智能体行为。
  • 当外部工具不可用或成本较高时开发智能体。
  • 在实现实际工具之前原型化智能体工作流。
import { createAgent, toolEmulatorMiddleware } from "langchain";

const agent = createAgent({
  model: "gpt-4o",
  tools: [getWeather, searchDatabase, sendEmail],
  middleware: [
    toolEmulatorMiddleware(), // Emulate all tools
  ],
});
tools
(string | ClientTool | ServerTool)[]
要模拟的工具名称(字符串)或工具实例列表。如果为 undefined (默认),将模拟所有工具。如果为空数组 [] ,则不模拟任何工具。如果是包含工具名称/实例的数组,则只模拟这些工具。
model
string | BaseChatModel
用于生成模拟工具响应的模型。可以是模型标识符字符串(例如, 'anthropic:claude-sonnet-4-5-20250929' )或 BaseChatModel 实例。如果未指定,默认使用智能体的模型。
该中间件使用 LLM 为工具调用生成合理的响应,而不是执行实际工具。
import { createAgent, toolEmulatorMiddleware, tool } from "langchain";
import * as z from "zod";

const getWeather = tool(
  async ({ location }) => `Weather in ${location}`,
  {
    name: "get_weather",
    description: "Get the current weather for a location",
    schema: z.object({ location: z.string() }),
  }
);

const sendEmail = tool(
  async ({ to, subject, body }) => "Email sent",
  {
    name: "send_email",
    description: "Send an email",
    schema: z.object({
      to: z.string(),
      subject: z.string(),
      body: z.string(),
    }),
  }
);

// Emulate all tools (default behavior)
const agent = createAgent({
  model: "gpt-4o",
  tools: [getWeather, sendEmail],
  middleware: [toolEmulatorMiddleware()],
});

// Emulate specific tools by name
const agent2 = createAgent({
  model: "gpt-4o",
  tools: [getWeather, sendEmail],
  middleware: [
    toolEmulatorMiddleware({
      tools: ["get_weather"],
    }),
  ],
});

// Emulate specific tools by passing tool instances
const agent3 = createAgent({
  model: "gpt-4o",
  tools: [getWeather, sendEmail],
  middleware: [
    toolEmulatorMiddleware({
      tools: [getWeather],
    }),
  ],
});

// Use custom model for emulation
const agent5 = createAgent({
  model: "gpt-4o",
  tools: [getWeather, sendEmail],
  middleware: [
    toolEmulatorMiddleware({
      model: "claude-sonnet-4-5-20250929",
    }),
  ],
});

Context editing

当达到 token 限制时,通过清除较旧的工具调用输出来管理对话上下文,同时保留最近的结果。这有助于在包含许多工具调用的长对话中保持上下文窗口可管理。上下文编辑适用于以下场景:
  • 超过 token 限制的包含许多工具调用的长对话
  • 通过删除不再相关的旧工具输出来降低 token 成本
  • 仅在上下文中保留最近的 N 个工具结果
import { createAgent, contextEditingMiddleware, ClearToolUsesEdit } from "langchain";

const agent = createAgent({
  model: "gpt-4o",
  tools: [],
  middleware: [
    contextEditingMiddleware({
      edits: [
        new ClearToolUsesEdit({
          triggerTokens: 100000,
          keep: 3,
        }),
      ],
    }),
  ],
});
edits
ContextEdit[]
default: "[new ClearToolUsesEdit()]"
要应用的 ContextEdit 策略数组
ClearToolUsesEdit 选项:
triggerTokens
number
default: "100000"
触发编辑的 token 计数。当对话超过此 token 数量时,将清除较旧的工具输出。
clearAtLeast
number
default: "0"
编辑运行时要回收的最小 token 数量。如果设置为 0,则按需清除。
keep
number
default: "3"
必须保留的最近工具结果数量。这些永远不会被清除。
clearToolInputs
boolean
default: "false"
是否清除 AI 消息上的原始工具调用参数。当设置为 true 时,工具调用参数将被替换为空对象。
excludeTools
string[]
default: "[]"
要从清除中排除的工具名称列表。这些工具的输出永远不会被清除。
placeholder
string
default: "[cleared]"
为已清除的工具输出插入的占位符文本。这将替换原始工具消息内容。
当达到 token 限制时,该中间件应用上下文编辑策略。最常用的策略是 ClearToolUsesEdit ,它会清除较旧的工具结果,同时保留最近的结果。 工作原理:
  1. 监控对话中的 token 计数
  2. 当达到阈值时,清除较旧的工具输出
  3. 保留最近的 N 个工具结果
  4. 可选择性地保留工具调用参数以供上下文使用
import { createAgent, contextEditingMiddleware, ClearToolUsesEdit } from "langchain";

const agent = createAgent({
  model: "gpt-4o",
  tools: [searchTool, calculatorTool, databaseTool],
  middleware: [
    contextEditingMiddleware({
      edits: [
        new ClearToolUsesEdit({
          triggerTokens: 2000,
          keep: 3,
          clearToolInputs: false,
          excludeTools: [],
          placeholder: "[cleared]",
        }),
      ],
    }),
  ],
});

Provider-specific middleware

这些中间件针对特定的 LLM 提供商进行了优化。请参阅每个提供商的文档以获取完整详情和示例。
连接这些文档 到 Claude、VSCode 等,通过 MCP 获取实时答案。