第6节:路由链(Router Chain)详解:小白也能看懂的教程

什么是路由链? 

路由链(Router Chain)是 LangChain 框架中的一个重要概念,它的作用就像一个"智能调度员"。想象一下你去银行办事,门口有一个引导员,他会根据你要办的业务把你引导到对应的窗口。路由链就是这样的"引导员",它会根据用户的问题,自动选择最合适的专家来回答。

比如:
你问游泳相关问题 → 路由链引导到"游泳教练"
你问跑步相关问题 → 路由链引导到"跑步教练"
你问篮球相关问题 → 路由链引导到"篮球教练"

核心代码解析

1. 定义路由信息结构体

type MultiPromptInfo struct {
    Key         string                 // 问题类型的标识符(比如"swimming")
    Description string                 // 描述这个专家是做什么的
    Prompt      prompts.FormatPrompter // 这个专家具体的提示词模板
}

这个结构体就像一个"专家档案",记录了每个专家的:
唯一标识(Key)
专业介绍(Description)
回答问题的模板(Prompt)

2. 路由链的核心结构

type MultiChains struct {
    LLMChains    *chains.LLMChain       // 主路由链,负责判断问题类型
    Routers      map[string]chains.Chain // 存储所有专家的实际处理链
    Destinations map[string]string       // 存储所有可用的专家标识和描述
    OutputParser outputparser.Structured // 结构化输出解析器
}

这就像一个调度中心的完整配置:
LLMChains: 调度员(主路由)
Routers: 所有专家的实际工作台
Destinations: 所有可选专家的名单
OutputParser: 格式化解析工具

3. 创建路由链

func NewMultiChains(llm llms.Model, multiPrompts []*MultiPromptInfo) *MultiChains {
    var (
        routerLLChain = make(map[string]chains.Chain, len(multiPrompts))
        destination   = make(map[string]string, len(multiPrompts))
    )
    for i, _ := range multiPrompts {
        // 为每个专家创建专门的处理链
        routerLLChain[multiPrompts[i].Key] = chains.NewLLMChain(llm, multiPrompts[i].Prompt)
        // 记录专家标识和描述的对应关系
        destination[multiPrompts[i].Key] = multiPrompts[i].Description
    }
    return &MultiChains{
        Destinations: destination,
        LLMChains:    chains.NewLLMChain(llm, _prompt), // 创建主路由链
        Routers:      routerLLChain,
        OutputParser: _outputparser,
    }
}

这段代码就像在建立一个专家团队:
1.为每个专家创建专门的工作台(处理链)
2.建立专家名单(标识和描述的对应关系)
3.设置总调度台(主路由链)


4. 路由决策过程

func (m MultiChains) Call(ctx context.Context, inputs map[string]any, options ...chains.ChainCallOption) (map[string]any, error) {
    input := inputs[_input]
    // 让主路由链判断应该交给哪个专家处理
    res, err := chains.Predict(ctx, m.LLMChains, map[string]any{
        _input:        input,
        _destinations: m.Destinations,
        _formatting:   m.OutputParser.GetFormatInstructions(),
    }, options...)
    if err != nil {
        return nil, err
    }
    // 根据判断结果交给对应专家处理
    return m.processLLMResult(ctx, res)
}

这就像调度员的工作流程:
1.接收用户问题
2.查看所有专家的资料
3.判断应该交给哪个专家
4.把问题转交给对应专家

5. 专家处理过程

func (m *MultiChains) processLLMResult(ctx context.Context, text string) (map[string]any, error) {
    // 解析调度员的判断结果
    data, err := m.OutputParser.Parse(text)
    if err != nil {
        return nil, err
    }
    next := data.(map[string]string)
    
    // 获取调度员指定的专家标识
    destination := next[_destinations]
    // 获取给专家的具体问题
    nextInput := next[_nextInput]
    
    // 找到对应的专家并让专家回答问题
    router := m.Routers[destination]
    return chains.Call(ctx, router, map[string]any{
        _input: nextInput,
    })
}
这就像专家处理问题的过程:
1.理解调度员的安排(解析判断结果)
2.找到对应的专家
3.把具体问题交给专家回答

实际使用示例

func TestRouterChains(t *testing.T) {
    // 定义专家团队
    multiPromptInfos := []*MultiPromptInfo{
        {
            Key:         "swimming",                            // 游泳专家标识
            Description: "你是一个资深的游泳教练,精通游泳相关知识",     // 专家介绍
            Prompt:      prompts.NewPromptTemplate(              // 专家回答模板
                "你是一个资深的游泳教练,精通游泳相关知识 请根据用户输入问题进行回答 \n {{.input}}", 
                []string{"input"}),
        },
        {
            Key:         "racing",                              // 跑步专家标识
            Description: "你是一个资深的赛跑冠军,精通赛跑相关知识",      // 专家介绍
            Prompt:      prompts.NewPromptTemplate(              // 专家回答模板
                "你是一个资深的赛跑冠军,精通赛跑相关知识 请根据用户输入问题进行回答 \n {{.input}}", 
                []string{"input"}),
        },
    }

    // 创建LLM模型
    llm := getLLmOpenaiClientNew(t)
    // 创建路由链系统
    routerChains := NewMultiChains(llm, multiPromptInfos)
    // 用户提问并获取答案
    predict, err := chains.Call(context.Background(), routerChains, map[string]any{"input": "请问如何游泳?"})
    if err != nil {
        panic(err)
        return
    }
    fmt.Println(predict)
}

工作流程总结

1.初始化阶段:

  • 创建各个领域的专家(游泳教练、跑步教练等)
  • 为每个专家设置专门的处理模板
  • 建立调度系统

2.处理用户问题阶段:

  • 用户提出问题:"请问如何游泳?"
  • 调度员分析问题内容
  • 调度员判断应该交给游泳教练处理
  • 将问题转给游泳教练
  • 游泳教练根据专业模板回答问题
  • 返回最终答案给用户

为什么这样设计?

这种设计有几个重要优势:

  1. 专业性强:每个专家只处理自己擅长的领域,回答更专业
  2. 扩展性好:可以轻松添加新的专家领域
  3. 智能化:自动判断问题类型,无需用户手动选择
  4. 解耦合:各个专家相互独立,互不影响

常见问题和解决方案

为什么Key建议用英文?
虽然Key可以用中文,但建议用英文,因为:

  1. 大多数LLM模型对英文更敏感,处理更准确
  2. 英文标识更简洁,减少解析错误
  3. 避免中文编码问题

如果LLM判断错误怎么办?
可以通过优化提示词模板来提高判断准确性:

  • 给出更明确的判断标准
  • 提供更多示例
  • 明确输出格式要求

总结

路由链就像一个智能的"问题分发系统",它通过以下步骤工作:

  1. 建立专家团队
  2. 设置调度中心
  3. 接收用户问题
  4. 智能分发给合适专家
  5. 返回专家答案

这种设计模式在实际应用中非常有用,比如客服系统、智能助手、专业咨询系统等场景都可以采用类似的架构

 

 

源代码

https://download.csdn.net/download/qq_36466946/91999333

 

posted @ 2025-09-23 18:03  phpwyl  阅读(29)  评论(0)    收藏  举报