首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >跟 Blades 学 Agent 设计 - 02 让 Agent 学会"随机应变"

跟 Blades 学 Agent 设计 - 02 让 Agent 学会"随机应变"

作者头像
用户1174346
发布2026-07-10 15:03:27
发布2026-07-10 15:03:27
310
举报

🎉Blades 已发布 v0.1.1 版本,欢迎大家使用 https://github.com/go-kratos/blades/releases/tag/v0.1.1

想象一下,你有一个只会按照固定程序工作的助手:你问他"今天天气怎么样",他会回答天气;你问他"帮我订张机票",他还是会回答天气。这样的助手显然不够智能。

真正的智能助手应该像人一样,能够理解不同的问题,并给出相应的回应。这就是路由模式要解决的核心问题——让 AI Agent 学会"随机应变"。

什么是路由?

路由本质上就是一个智能的"指挥中心",它负责分析接收到的任务,然后决定应该把这个任务交给哪个专门的"专家"去处理。

举个生活中的例子:当你走进一家大医院时,首先是挂号台的护士问你哪里不舒服。根据你的回答,她会把你引导到不同的科室——感冒去内科,骨折去骨科,心脏问题去心内科。这个护士和科室分配系统,就是一个完美路由模式。

在 AI 系统中,路由模式扮演着同样的角色:接收用户的请求,分析其意图,然后转发给最合适的处理模块。

例如,一个客户服务 Agent 通过路由模式可以分析用户查询的意图,然后将预订相关问题导向订单数据库,将产品信息查询导向搜索功能,将技术问题导向支持工具或人工客服。

为什么需要路由?

  1. 单一工具无法应对复杂世界:假设你只有一个锤子,那么所有问题在你看来都是钉子。但现实世界的问题五花八门,需要不同的专业工具来处理。
    • 用户问产品信息,需要调用产品数据库
    • 用户要技术支持,需要连接知识库或专家系统
    • 用户想下单购物,需要调用订单处理系统
    • 用户需要退款,需要走财务流程
  2. 提高效率和准确性:让专业的人做专业的事,这个道理在 AI 世界同样适用。一个专门处理订单的系统,显然比什么都能做的通用系统在订单处理上更准确、更高效。
  3. 改善用户体验:用户希望得到准确的回应,而不是一个"万能但不精"的回答。路由模式能够确保用户的每个问题都得到最专业的处理。

现实中的路由应用

  1. 新闻编辑室主任:在新闻编辑室中,主任根据新闻的类型(政治、体育、财经、科技、娱乐等)将稿件分配给不同的编辑组。每个编辑组都有自己的专业领域,能够更好地处理和编辑相关内容。
    • 体育新闻 → 体育编辑组
    • 财经新闻 → 财经编辑组
    • 科技新闻 → 科技编辑组
    • 娱乐新闻 → 娱乐编辑组
  2. 医院分诊系统:在医院中,分诊护士根据患者的症状和病情将他们引导到不同的科室(内科、外科、儿科、急诊等)。这样可以确保患者得到最合适的治疗。
    • 发烧、咳嗽 → 内科
    • 骨折、外伤 → 外科
    • 儿童疾病 → 儿科
    • 紧急情况 → 急诊科

路由的决策方式

路由中最核心的部分就是决策机制,也就是判断将任务分配给谁来做。以下是几种常见的路由决策方式:

  1. 规则匹配:最简单的路由方式是基于预定义的规则。例如,如果用户的问题中包含"订单"、"购买"等关键词,就把请求路由到订单处理模块。
代码语言:javascript
复制
if strings.Contains(userQuery, "订单") {
    routeToOrderModule()
} else if strings.Contains(userQuery, "技术支持") {
    routeToSupportModule()
}

优点:简单快速,结果确定,容易理解缺点:不够灵活,难以处理复杂语义(用户连话都说不明白,自己都不知道自己想要什么)适用场景:简单明确的任务分配

2.基于 LLM 的意图识别:更高级的路由方式是利用 AI 来理解用户的意图。通过分析用户的自然语言输入,AI 可以判断出用户真正想要什么,然后做出路由决策。

代码语言:javascript
复制
用户输入:"我想知道这个产品的规格。"
AI 分析后识别出意图为"查询产品信息",于是将请求路由到产品信息模块。

优点:理解能力强,灵活适应性强缺点:需要更多 Tokens,可能会判断错误适用场景:复杂的对话系统,需要理解语义的场景

3.基于机器学习的路由:通过训练一个分类模型,AI 可以根据历史数据学习如何路由不同类型的请求。随着时间的推移,这种方法可以不断优化路由决策,提高准确率。优点:准确率高,处理复杂情况能力强缺点:需要训练数据,前期投入大适用场景:大规模的成熟系统

我只是列举了部分常见的路由决策方式,实际应用中你可以根据具体需求选择合适的方法,或者同时使用多种方式以达到最佳效果。

基于 LLM 怎么设计路由

因为系列文章主要围绕在 Blades 平台上构建 AI Agent,所以这里重点介绍基于 LLM 的路由设计思路。

  1. 分层处理:从粗到细 就像是一个大型公司的组织架构, 一项工作任务不会直接分配到个人,而是经过多个层级的处理。首先任务会被分配到相关部门,然后由部门经理分配到具体小组,最后再由小组负责人分配到个人。路由系统也可以采用类似的分层处理方式,
代码语言:javascript
复制
  总经理
  ├─────────────────┬─────────────────┬─────────────────┬─────────────────┐
  技术部           市场部           人事部           财务部           运营部
  │                │                │                │                │
  ├─────┬─────┐    ├─────┬─────┐    │                ├─────┬─────┐    │
  前端组 后端组   推广组  销售组   招聘培训组        会计组 审计组   客服组

路由系统也可以采用类似的分层处理方式,例如:第一层 Agent 负责大致分类(比如订单、技术支持、产品信息),第二层 Agent 再根据具体需求进行更细化的路由(比如订单查询、订单修改、订单取消等)。

  1. 并行处理:大家分担,提高效率 在一个大型项目中,多个团队可以同时工作以提高效率。同样地,路由系统也可以设计成并行处理的方式。比如,当一个用户请求到达时,可以同时将请求发送给多个子 Agent,让它们各自处理不同的部分,最后再将结果汇总返回给用户。
  2. 反馈机制:持续优化路由决策 路由系统应该具备学习和优化的能力。通过收集用户反馈和处理结果,系统可以不断调整路由策略,提高准确率和用户满意度。例如,如果某个子 Agent 经常处理失败,系统可以自动减少对该 Agent 的依赖,转而使用其他更可靠的 Agent。
  3. 上下文感知:理解用户的整体需求 路由系统不仅要关注单一对话,还需要理解用户的整体需求和上下文信息。可以通过分析用户的历史交互记录和偏好,系统可以更准确地判断用户的意图,从而做出更合适的路由决策。例如,如果一个用户经常查询某类产品的信息,系统可以优先将相关请求路由到该产品信息模块。

使用 Blades 实现一个简单的路由模式案例

我们来实现一个简单的“智能助手”,它有数学 Agent地理 Agent, 可以根据用户的对话内容,路由到不同的 Agent 进行处理。 基于 LLM 的路由,主要考验的就是提示词设计能力,使用相同模型的条件下,提示词写的越好,路由就越准确。所以我们需要精心设计提示词,让路由 Agent 会根据用户的输入内容,选择最合适的子 Agent 进行处理。

代码语言:javascript
复制
   You are a routing agent.
    Choose the single best route key for handling the user's request.
    User message: <user_message>
    Available route keys (choose exactly one):
    - math_agent: You provide help with math problems. Explain your reasoning at each step and include examples.
    - history_agent: You provide assistance with historical queries. Explain important events and context clearly.

代码部分的实现很简单,核心逻辑都在 selectRoute 方法中。它通过提示词让路由 Agent 根据用户的输入内容, 选择最合适的子 Agent 进行处理。

代码语言:javascript
复制
package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "strings"

    "github.com/go-kratos/blades"
    "github.com/go-kratos/blades/contrib/openai"
)

// RoutingWorkflow is a workflow that routes requests to different agents based on the content of the prompt.
type RoutingWorkflow struct {
    blades.Agent
    routes map[string]string
    agents map[string]blades.Agent
}

// NewRoutingWorkflow creates a new RoutingWorkflow with the given model provider and routes.
func NewRoutingWorkflow(routes map[string]string) (*RoutingWorkflow, error) {
    provider := openai.NewChatProvider()
    router, err := blades.NewAgent(
        "triage_agent",
        blades.WithModel("gpt-5"),
        blades.WithProvider(provider),
        blades.WithInstructions("You determine which agent to use based on the user's homework question"),
    )
    if err != nil {
        returnnil, err
    }
    agents := make(map[string]blades.Agent, len(routes))
    for name, instructions := range routes {
        agent, err := blades.NewAgent(
            name,
            blades.WithModel("gpt-5"),
            blades.WithProvider(provider),
            blades.WithInstructions(instructions),
        )
        if err != nil {
            returnnil, err
        }
        agents[name] = agent
    }
    return &RoutingWorkflow{
        Agent:  router,
        routes: routes,
        agents: agents,
    }, nil
}

// Run selects a route using the prompt content and streams from the chosen runner.
func (r *RoutingWorkflow) Run(ctx context.Context, invocation *blades.Invocation) blades.Generator[*blades.Message, error] {
    returnfunc(yield func(*blades.Message, error) bool) {
        agent, err := r.selectRoute(ctx, invocation)
        if err != nil {
            yield(nil, err)
            return
        }
        stream := agent.Run(ctx, invocation)
        for msg, err := range stream {
            if !yield(msg, err) {
                break
            }
        }
    }
}

// selectRoute determines the best route key and runner for the given prompt.
func (r *RoutingWorkflow) selectRoute(ctx context.Context, invocation *blades.Invocation) (blades.Agent, error) {
    var buf strings.Builder
    buf.WriteString("You are a routing agent.\n")
    buf.WriteString("Choose the single best route key for handling the user's request.\n")
    buf.WriteString("User message: " + invocation.Message.Text() + "\n")
    buf.WriteString("Available route keys (choose exactly one):\n")
    routes, err := json.Marshal(r.routes)
    if err != nil {
        returnnil, err
    }
    buf.WriteString(string(routes))
    for res, err := range r.Agent.Run(ctx, blades.NewInvocation(blades.UserMessage(buf.String()))) {
        if err != nil {
            returnnil, err
        }
        choice := strings.TrimSpace(res.Text())
        return r.agents[choice], nil
    }
    returnnil, fmt.Errorf("no route selected")
}

func main() {
    var (
        routes = map[string]string{
            "math_agent":    "You provide help with math problems. Explain your reasoning at each step and include examples.",
            "history_agent": "You provide assistance with historical queries. Explain important events and context clearly.",
        }
    )
    routing, err := NewRoutingWorkflow(routes)
    if err != nil {
        log.Fatal(err)
    }
    // Example prompt that will be routed to the history_agent
    input := blades.UserMessage("What is the capital of France?")
    runner := blades.NewRunner(routing)
    res, err := runner.Run(context.Background(), input)
    if err != nil {
        log.Fatal(err)
    }
    log.Println(res.Text())
}

https://github.com/go-kratos/blades/blob/main/examples/workflow-routing

总结

路由模式是构建智能 AI Agent 的关键技术之一。通过合理设计路由机制,AI 系统能够更高效、更准确地处理用户请求,提升整体性能和用户体验。在实际应用中,可以根据具体需求选择合适的路由决策方式,并结合上下文信息和反馈机制不断优化路由策略。

后续的文章中,我会继续分享使用 Blades,通过 flow、graph 等组件方式实现更复杂路由模式的设计思路。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-11-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 kratos 开源社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是路由?
  • 为什么需要路由?
  • 现实中的路由应用
  • 路由的决策方式
  • 基于 LLM 怎么设计路由
  • 使用 Blades 实现一个简单的路由模式案例
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档