实用功能

错误处理

在图中优雅地捕获和处理异常,构建健壮的 Agent

📚 学习目标

学完这篇文章后,你将能够:

  • 在节点内部捕获并处理异常
  • 使用 retry 策略自动重试失败的节点
  • 设计“Fallback 节点”来处理不可恢复的错误

前置知识

在开始学习之前,建议先阅读:

你需要了解:

  • JavaScript try/catch 机制

1️⃣ 节点级 Try/Catch

最基础的方法是在节点函数内部包裹 try/catch。

import { ToolMessage } from '@langchain/core/messages';

const safeToolNode = async (state) => {
  try {
    const result = await riskyTool.invoke(...);
    return { result };
  } catch (error) {
    console.error("Tool failed:", error);
    // 返回一个错误标识,而不是抛出异常让整个图崩溃
    return { 
      error: error.message,
      //以此通知 LLM 工具调用失败
      messages: [new ToolMessage({ 
        content: `Error: ${error.message}`, 
        tool_call_id: ... 
      })] 
    };
  }
};

[!NOTE] 上面的 tool_call_id 需要来自“LLM 的工具调用请求”。如果你使用 ToolNode,它会帮你把 tool result/错误包装成 ToolMessage 并返回给模型。


2️⃣ 自动重试 (Retry Policy)

LangGraph 允许你为节点配置重试策略。这对于不稳定的网络请求(如 LLM API 调用)非常有用。

注意:目前 LangGraph JS 版本主要通过在 compile 时传入 retry 策略,或在某些预置节点(如 ToolNode)中支持。

// 示例:在 ToolNode 中处理错误
// 如果工具抛出错误,ToolNode 默认会捕获并返回包含错误信息的 ToolMessage
// 这样 LLM 可以看到错误并尝试修复参数重新调用

对于通用节点,你可以自己实现重试逻辑。建议用“指数退避 + 抖动”,避免服务雪崩:

function sleep(ms: number) {
  return new Promise((r) => setTimeout(r, ms));
}

const retryNode = async (state) => {
  let retries = 3;
  let backoffMs = 200;
  while (retries > 0) {
    try {
      return await doSomething();
    } catch (e) {
      retries--;
      if (retries === 0) throw e;
      const jitter = Math.floor(Math.random() * 100);
      await sleep(backoffMs + jitter);
      backoffMs *= 2;
    }
  }
};

3️⃣ 递归限制:防止循环失控

当你的图里存在循环边(例如 ReAct Loop)时,务必设置 recursionLimit

try {
  await app.invoke(inputs, { recursionLimit: 20 });
} catch (e) {
  console.log('可能触发了 recursionLimit 或其他运行时错误');
}

4️⃣ Fallback 分支

你可以设计专门的错误处理分支。

// 1. 定义状态包含 error 字段
const State = Annotation.Root({
  // ...
  error: Annotation<string>(),
});

// 2. 路由逻辑
const routeError = (state) => {
  if (state.error) {
    return "human_help"; // 错误 -> 转人工
  }
  return "next_step";
};

// 3. 构建图
graph.addConditionalEdges("node_a", routeError);

这样,当节点 A 发生逻辑错误(它捕获异常并设置 state.error)时,系统会自动路由到人工干预节点。


📚 参考资源

官方文档


💡 练习题

  1. 设计题:设计一个 robust 的网络搜索节点。如果搜索 API超时,它应该重试 3 次;如果依然失败,它应该返回一个“搜索不可用”的占位符,而不是让程序崩溃。

✅ 总结

本章要点

  • 永远不要让未捕获的异常中断 Graph 的运行(除非是致命错误)。
  • 将错误信息反馈给 LLM(通过 ToolMessage),让 LLM 尝试自我修复。
  • 使用条件边构建错误恢复流程。

下一步:学习高级流控制工具:Command 对象

登录以继续阅读

解锁完整文档、代码示例及更多高级功能。

立即登录

On this page