Q高级15: 解释 LangChain 中的 Confidence-Based Agent Routing 的概念和实现方法,并提供一个示例,展示如何构建一个基于置信度的多代理决策系统。
LangChain 中的 Confidence-Based Agent Routing
概念
Confidence-Based Agent Routing(基于置信度的代理路由)是一种多代理协作模式,其中系统根据每个代理对其输出结果的置信度分数来决定将请求路由到哪个代理。核心思想是:当某个代理对其回答不确定(置信度低)时,系统自动将任务转交给更专业或更可靠的代理,从而提高整体回答的质量和可靠性。
在 LangChain 生态中,该模式通常结合以下技术实现:
- 输出置信度评估:通过 LLM 自我评分、logit 概率或外部验证模型获得置信度。
- 条件路由:根据置信度阈值选择不同的处理路径(如继续使用当前代理、切换到备用代理、或调用工具/检索增强)。
- 多代理编排:利用 LangGraph 或自定义 Router 来管理多个代理及路由逻辑。
实现方法
- 代理定义:每个代理封装一个 LLM 链,并在输出中包含一个置信度分数(例如让 LLM 输出
{"answer": "...", "confidence": 0.8})。 - 置信度评估:
- 显式评估:提示 LLM “请评估你对以上答案的信心,给出 0-1 的分数”。
- 隐式评估:使用模型输出的 logits(如
max_prob)或 p(true) 等概率信号。
- 路由逻辑:
- 设定阈值(如 0.7)。若置信度 ≥ 阈值,直接返回答案。
- 否则,将原始问题转发给另一个代理(例如:通用代理 → 专家代理 → 搜索代理)。
- 编排:使用 LangChain 的
RunnableBranch、RouterChain或 LangGraph 的StateGraph实现动态路由。
示例:构建基于置信度的多代理决策系统
以下示例构建一个医疗咨询辅助系统,包含三个代理:
- 通用代理:回答常见健康问题,并自带置信度。
- 专家代理:模拟专科医生,对复杂问题更可靠但成本更高。
- 搜索代理:在置信度低时触发网络检索(这里用模拟数据演示)。
系统流程:先尝试通用代理,若置信度 < 0.7 则转专家代理;若专家置信度仍低,则启动搜索代理。
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import PydanticOutputParser
from langchain_openai import ChatOpenAI
from langchain_core.runnables import RunnableBranch, RunnableLambda
from pydantic import BaseModel, Field
from typing import Literal
import os
# 假设设置了 OPENAI_API_KEY
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
# 定义所有代理共享的输出结构(答案 + 置信度)
class AgentResponse(BaseModel):
answer: str = Field(description="对用户问题的回答")
confidence: float = Field(description="0-1 之间的置信度分数", ge=0, le=1)
source: Literal["general", "expert", "search"] = Field(description="回答来源")
parser = PydanticOutputParser(pydantic_object=AgentResponse)
# 1. 通用代理
general_prompt = ChatPromptTemplate.from_messages([
("system", "你是一个通用健康助手。请回答用户问题,并评估你的置信度(0-1)。"
"如果你不确定,请给出较低置信度。\n{format_instructions}"),
("human", "{question}")
]).partial(format_instructions=parser.get_format_instructions())
general_agent = general_prompt | llm | parser
# 2. 专家代理(更专业,置信度更高)
expert_prompt = ChatPromptTemplate.from_messages([
("system", "你是一位资深医学专家。请给出准确专业的回答,并评估置信度。\n{format_instructions}"),
("human", "{question}")
]).partial(format_instructions=parser.get_format_instructions())
expert_agent = expert_prompt | llm | parser
# 3. 搜索代理(模拟联网检索,返回固定答案+高置信度)
def search_agent(question: str) -> AgentResponse:
# 实际可调用 Tavily、Google 等 API
return AgentResponse(
answer=f"根据最新检索结果:关于“{question}”,建议咨询正规医疗机构。",
confidence=0.95,
source="search"
)
search_runnable = RunnableLambda(lambda x: search_agent(x["question"]))
# 定义路由决策函数
def route_by_confidence(response: AgentResponse):
"""根据置信度决定下一步:继续输出 or 路由到其他代理"""
if response.confidence >= 0.7:
return response # 直接返回
else:
# 返回特殊标记,触发 fallback
return {"continue": False, "fallback_reason": "low_confidence", "original_response": response}
def is_low_confidence(x):
"""判断是否需要路由的守卫函数"""
# 如果 x 是 AgentResponse 且置信度低,或者字典标记为 fallback
if isinstance(x, AgentResponse):
return x.confidence < 0.7
elif isinstance(x, dict) and x.get("continue") is False:
return True
return False
# 构建路由分支:先尝试通用代理,若不满足则尝试专家代理,再不满足则搜索
routing_chain = (
{"question": lambda x: x}
| general_agent
| RunnableBranch(
(lambda r: r.confidence >= 0.7, RunnableLambda(lambda r: r)), # 直接输出
# 低置信度:转专家代理
(lambda r: True, {"question": lambda x: x["question"]} | expert_agent) # 注意:这里需要保留原始问题
)
)
# 更清晰的实现:使用 LangGraph 或自定义循环。为了可读性,下面使用简单的函数式路由封装。
def run_multi_agent_system(question: str) -> AgentResponse:
# 第一级:通用代理
resp1 = general_agent.invoke({"question": question})
if resp1.confidence >= 0.7:
return resp1
# 第二级:专家代理
resp2 = expert_agent.invoke({"question": question})
if resp2.confidence >= 0.7:
return resp2
# 第三级:搜索代理
return search_agent(question)
# 测试示例
if __name__ == "__main__":
test_questions = [
"如何缓解普通感冒症状?", # 通用代理可能自信回答
"罕见病‘庞贝氏症’的酶替代疗法最新进展?" # 通用代理可能低自信,转到专家或搜索
]
for q in test_questions:
result = run_multi_agent_system(q)
print(f"问题: {q}")
print(f"回答: {result.answer}")
print(f"置信度: {result.confidence}, 来源: {result.source}\n")
关键点说明
- 置信度来源:示例中通过 Prompt 要求 LLM 自评分数。实际生产可结合模型 logits、Token 概率或独立评判模型。
- 路由逻辑:顺序回退(通用 → 专家 → 搜索)。也可并行请求多个代理,再选择置信度最高的输出。
- LangChain 组件:
RunnableBranch实现条件分支。PydanticOutputParser确保结构化输出。- 使用普通函数封装复杂路由更直观。
- 扩展性:可升级为 LangGraph 状态机,支持循环、并行、历史记忆等高级模式。
进阶:使用 LangGraph 实现更健壮的路由
from langgraph.graph import StateGraph, END
from typing import TypedDict
class State(TypedDict):
question: str
answer: str
confidence: float
source: str
current_agent: str
def general_node(state: State):
resp = general_agent.invoke({"question": state["question"]})
return {"answer": resp.answer, "confidence": resp.confidence, "source": resp.source, "current_agent": "general"}
def expert_node(state: State):
resp = expert_agent.invoke({"question": state["question"]})
return {"answer": resp.answer, "confidence": resp.confidence, "source": resp.source, "current_agent": "expert"}
def search_node(state: State):
resp = search_agent(state["question"])
return {"answer": resp.answer, "confidence": resp.confidence, "source": resp.source, "current_agent": "search"}
def route_after_general(state: State):
if state["confidence"] >= 0.7:
return END
else:
return "expert"
def route_after_expert(state: State):
if state["confidence"] >= 0.7:
return END
else:
return "search"
builder = StateGraph(State)
builder.add_node("general", general_node)
builder.add_node("expert", expert_node)
builder.add_node("search", search_node)
builder.set_entry_point("general")
builder.add_conditional_edges("general", route_after_general, {"expert": "expert", END: END})
builder.add_conditional_edges("expert", route_after_expert, {"search": "search", END: END})
builder.add_edge("search", END)
graph = builder.compile()
# 运行
result = graph.invoke({"question": "什么是mRNA疫苗?", "current_agent": ""})
print(result["answer"])
这种基于置信度的路由模式显著提升了系统的鲁棒性,在 RAG、客户支持、医疗咨询等需要高可靠性的场景中尤为实用。
⚡️面试时候调理清晰回答这个问题
在面试中,如果被问到 “LangChain 中的 Confidence-Based Agent Routing(基于置信度的代理路由)”,我会按照以下逻辑清晰回答:
一、概念解释(是什么,为什么)
首先,Confidence-Based Agent Routing 是一种多代理协作的设计模式。它的核心思想是:
每个代理在执行任务后,都会给出一个 置信度分数(比如 0~1,表示对自己输出的把握程度)。系统根据这个分数动态决定——
- 如果当前代理置信度 高于阈值,直接采用它的结果;
- 如果 低于阈值,就把任务 路由 给另一个更专业、更可靠或能获取外部知识的代理。
为什么需要它?
因为单一代理不可能对所有问题都有高把握。比如通用 LLM 可能对常识问题很有信心,但对专业医疗问题则信心不足。通过置信度路由,可以让低成本代理先处理简单问题,低成本无法解决时再调用高成本专家代理,从而在 准确性 和 成本/延迟 之间取得平衡。
二、实现方法(怎么做)
在 LangChain 中,典型实现步骤包括:
-
设计统一的代理输出格式
要求每个代理返回结构化结果,例如:
{ "answer": "...", "confidence": 0.85, "source": "general" }
可以使用PydanticOutputParser强制 LLM 输出置信度。 -
构建多个专用代理
例如:通用代理、领域专家代理、检索增强代理(RAG)、搜索代理等。每个代理自己评估置信度。 -
置信度评估方式
- 显式评估:在 prompt 中要求 LLM “请给你对刚才答案的信心打分(0-1)”。
- 隐式评估:利用模型输出 token 的概率(logits)、或者训练一个小的置信度预测模型。
-
路由决策逻辑
可以使用 LangChain 的RunnableBranch或 LangGraph 的条件边。
伪逻辑:result = general_agent.invoke(question)if result.confidence >= 0.7:return resultelse:result = expert_agent.invoke(question)if result.confidence >= 0.7:return resultelse:return search_agent.invoke(question) -
编排框架
- 简单场景:
RunnableBranch+ 顺序 fallback。 - 复杂场景:使用 LangGraph 构建状态机,支持循环、并行请求多个代理并选择置信度最高的。
- 简单场景:
三、示例:医疗咨询的多代理决策系统
场景:用户问“我头痛发热,该吃什么药?”
-
通用代理(低成本 GPT-3.5)
回答:“可以吃布洛芬”。置信度 0.6(因为不确定是否有禁忌症)。 -
路由判断:0.6 < 0.7,所以转给 专家代理(基于 GPT-4 + 医学知识库)
回答:“若体温>38.5℃且无药物过敏,可服用对乙酰氨基酚。建议多喝水并休息。” 置信度 0.9 → 采用此答案。 -
如果专家置信度也低(例如罕见病),则再转给 搜索代理(调用 Web 检索工具)给出带引用的答案。
核心代码示意(LangGraph 风格):
def general_agent(state):
resp = llm.invoke(...)
return {"answer": resp.answer, "confidence": resp.confidence}
def route_after_general(state):
if state["confidence"] >= 0.7:
return "end"
else:
return "expert"
graph.add_node("general", general_agent)
graph.add_conditional_edges("general", route_after_general, ...)
四、面试加分点(注意事项)
- 阈值设定:需要根据业务调优,过低会导致不必要的 fallback,过高可能放过错误答案。
- 置信度校准:LLM 自评置信度可能过于乐观,可以结合历史数据做 recalibration。
- 可观测性:记录每次路由路径和置信度,便于调试。
- 并行 vs 串行:如果延迟不敏感,可以并行调用多个代理,选择置信度最高的结果,但成本更高。
总结一句话:
Confidence-Based Agent Routing 通过让每个代理输出置信度,结合条件路由机制,实现“简单问题快速响应,复杂问题自动升级”,是构建可靠、高效多代理系统的重要手段。