Skip to content

RunnableConfig:贯穿执行链的上下文对象

在 LangChain V3 中,RunnableConfig 是一个关键概念,它作为贯穿整个执行链的上下文对象,承载着配置、元数据和控制信息。这个对象使得开发者能够在整个调用链中传递重要的运行时信息,实现诸如日志记录、追踪、限流等横切关注点。

RunnableConfig 的核心作用

RunnableConfig 的主要作用包括:

  1. 传递配置信息 - 在整个执行链中传递统一的配置参数
  2. 上下文管理 - 维护执行过程中的上下文状态
  3. 控制执行行为 - 控制执行过程中的各种行为,如超时、并发等
  4. 集成外部系统 - 与日志、监控、追踪等外部系统集成

RunnableConfig 的主要属性

callbacks

callbacksRunnableConfig 中最重要的属性之一,它允许开发者注入回调函数来监控和控制执行过程:

typescript
const config: RunnableConfig = {
  callbacks: [
    {
      // 执行开始时的回调
      handleChainStart(chain, inputs) {
        console.log('Chain started with inputs:', inputs);
      },
      
      // 执行结束时的回调
      handleChainEnd(outputs) {
        console.log('Chain ended with outputs:', outputs);
      },
      
      // 执行出错时的回调
      handleChainError(error) {
        console.error('Chain error:', error);
      }
    }
  ]
};

const result = await chain.invoke(input, config);

metadata

metadata 用于传递与执行相关的元数据信息:

typescript
const config: RunnableConfig = {
  metadata: {
    userId: '12345',
    sessionId: 'session-abc',
    requestId: 'req-xyz',
    tags: ['production', 'critical']
  }
};

const result = await chain.invoke(input, config);

这些元数据可以在日志记录、监控和追踪中发挥重要作用。

maxConcurrency

maxConcurrency 用于控制并发执行的数量,特别在批量处理时非常有用:

typescript
const config: RunnableConfig = {
  maxConcurrency: 5 // 最多同时执行5个任务
};

const results = await chain.batch(inputs, config);

timeout

timeout 用于设置执行超时时间:

typescript
const config: RunnableConfig = {
  timeout: 30000 // 30秒超时
};

const result = await chain.invoke(input, config);

实际应用场景

日志记录和追踪

通过 callbacks,我们可以轻松实现执行过程的日志记录和追踪:

typescript
class LoggingCallback {
  handleChainStart(chain, inputs, runId) {
    console.log(`[${runId}] Chain started:`, chain.getName());
  }
  
  handleChainEnd(outputs, runId) {
    console.log(`[${runId}] Chain completed successfully`);
  }
  
  handleChainError(error, runId) {
    console.log(`[${runId}] Chain failed:`, error.message);
  }
}

const config = {
  callbacks: [new LoggingCallback()],
  metadata: {
    traceId: generateTraceId()
  }
};

限流控制

通过 maxConcurrency,我们可以实现对资源使用的控制:

typescript
// 对于资源密集型操作,限制并发数量
const resourceIntensiveConfig: RunnableConfig = {
  maxConcurrency: 2
};

// 对于轻量级操作,可以允许更高的并发
const lightweightConfig: RunnableConfig = {
  maxConcurrency: 10
};

超时管理

通过 timeout,我们可以确保操作不会无限期执行:

typescript
const config: RunnableConfig = {
  timeout: 10000 // 10秒超时
};

try {
  const result = await slowLLM.invoke(input, config);
} catch (error) {
  if (error.name === 'TimeoutError') {
    console.log('Operation timed out');
  }
}

配置的传递和继承

RunnableConfig 在执行链中是传递和继承的:

typescript
const globalConfig: RunnableConfig = {
  callbacks: [new GlobalLogger()],
  timeout: 30000
};

const localConfig: RunnableConfig = {
  metadata: { step: 'specific-step' },
  timeout: 15000 // 覆盖全局超时设置
};

// localConfig 会与 globalConfig 合并
const result = await chain.invoke(input, {
  ...globalConfig,
  ...localConfig
});

与 AbortSignal 集成

RunnableConfig 还可以与 AbortSignal 集成,实现更精细的控制:

typescript
const controller = new AbortController();
const config: RunnableConfig = {
  signal: controller.signal
};

// 在另一个地方可以取消执行
setTimeout(() => {
  controller.abort();
}, 5000);

try {
  const result = await chain.invoke(input, config);
} catch (error) {
  if (error.name === 'AbortError') {
    console.log('Execution was aborted');
  }
}

类型安全和验证

LangChain V3 通过 TypeScript 提供了完整的类型安全支持:

typescript
interface RunnableConfig {
  callbacks?: Callback[];
  metadata?: Record<string, any>;
  maxConcurrency?: number;
  timeout?: number;
  signal?: AbortSignal;
  // 其他配置项...
}

这种类型定义确保了在编译时就能发现配置错误。

总结

RunnableConfig 是 LangChain V3 中一个非常重要的概念,它为执行链提供了统一的配置和上下文管理机制。通过 timeout 等属性,开发者可以灵活地控制执行行为,实现日志记录、追踪、限流等横切关注点。

在下一章中,我们将探讨 Runnable 如何处理错误,以及如何抛出结构化错误信息。