什么是回退机制?
可以理解为一种**“保险机制”**,就像:
- A 计划不行 → 执行 B 计划
- A 服务器挂了 → 走 B 节点
- A 模型限流 → 让本地模型顶上
主模型出错时,自动调用备用模型继续执行,用户无感知,体验不中断
如何实现回退
早期的时候,LangChain.js 没有提供相应的 API,所以需要通过 try/catch 来进行模拟:
async function safeInvoke(prompt) { try { const res = await openaiLLM.invoke(prompt) console.log('OpenAI模型回复:', res.content) } catch (err) { console.warn('OpenAI模型出错,切换到备用模型:', err.message) const fallbackRes = await llama3LLM.invoke(prompt) console.log('Llama3模型回复:', fallbackRes.content) }}不过这种模型不够优雅,而且有一定的局限性。
现在 LangChain.js 已经提供了对应的方法 withFallbacks,这是 Runnable 类型上的一个方法:给“主”Runnable 挂上备选 Runnable 列表。当主 Runnable 执行失败(抛错)时,会按顺序尝试后备,直到某个成功或全部失败为止。
-
在现有 Runnable 上调用
const chainWithFallback = primaryRunnable.withFallbacks([fallback1,fallback2,]) -
直接实例化 RunnableWithFallbacks(工具类)
import { RunnableWithFallbacks } from '@langchain/core/runnables'const r = new RunnableWithFallbacks({runnable: primaryRunnable, // 主链fallbacks: [fallback1, fallback2], // 备用链})
课堂练习
使用 withFallbacks 实现回退
质量驱动的“软回退”
默认回退只在抛异常时触发。如果你想“结果不达标时也回退”,可以在主链末尾加一个“校验器”,不达标就主动抛错,让回退机制接管。
import { RunnableLambda } from "@langchain/core/runnables";
// 一个简单的输出质量校验器:含“抱歉/无法”就认为不达标const rejectIfLowQuality = new RunnableLambda({ func: async (text: string) => { const bad = /抱歉|无法|我不能/.test(text); if (bad) { throw new Error("LowQualityOutput"); // 主动抛错,触发回退 } return text; },});
// 把校验器挂在主链末尾const primaryChecked = primaryChain.pipe(rejectIfLowQuality);
// 回退链保持不变const resilientQuality = primaryChecked.withFallbacks([secondaryChain, localChain]);
const answer = await resilientQuality.invoke({ question: "给我 3 条提升 RAG 召回质量的做法。",});