意图识别与工具智能路由:17 维关键词矩阵如何让 LLM 精准选择 38 个工具

意图识别与工具智能路由:17 维关键词矩阵如何让 LLM 精准选择 38 个工具

系列文章第 26 篇 - 从"选择困难症"到"精准狙击",揭秘 Phase 6 工具扩展后的意图识别体系重构


📚 专栏信息

《从零到一构建跨平台 AI 助手:WeClaw 实战指南》专栏

专栏定位:面向开发者和技术决策者的实战专栏,用真实案例和完整代码带你理解如何构建生产级 AI 应用

本系列共 30+ 篇,分为八大模块

📖 模块一【通讯架构设计】(3 篇):混合通讯、设备绑定、请求路由

🔧 模块二【核心技术实现】(4 篇):WebSocket 路由、心跳重连、离线队列

🛡️ 模块三【安全与治理】(3 篇):密钥管理、Token 吊销、速率限制

🔍 模块四【调试与监控】(2 篇):全链路追踪、日志分析

💡 模块五【问题诊断实战】(3 篇):典型问题排查与修复

⚙️ 模块六【性能优化】(1 篇):启动速度、内存优化

🤖 模块七【主动陪伴系统】(3 篇):决策引擎、防骚扰机制、渐进式建档

🛠️ 模块八【工具系统设计】(3 篇):意图识别、工具暴露、Schema 优化

  • 模块定位:工具系统设计 · 第 1 篇(共 3 篇)

  • 前置知识:了解 Function Calling 基本概念、System Prompt 作用

  • 关联文章:第 25 篇(Phase 6 工具扩展)、第 27 篇(工具暴露策略)


👨‍💻 作者与项目

作者简介:翁勇刚 WENG YONGGANG

复制代码
      新概念龙虾-WeClaw 开发团队负责人,一群专注于跨平台 AI 应用的实践者  

理念:"让工具扩展像添加配置一样简单,让开发者专注于业务逻辑"


📝 摘要

本文结构概览

本文首先从三个真实的"工具选错"场景出发,分析 Phase 6 新增 16 个工具后原有 10 维意图识别体系失效的根本原因;然后用"机场安检分流通道"比喻讲解 17 维关键词矩阵 + 三表联动(INTENT_CATEGORIES / INTENT_TOOL_MAPPING / INTENT_PRIORITY_MAP)的协作原理;接着通过 923 行核心代码详解意图识别算法和 6029 字符工具场景决策树的设计;随后还原 "PDF" 多义性冲突的真实排查过程;最后给出动态 System Prompt 注入和渐进式工具暴露的最佳实践。

背景 :Phase 6 版本一口气新增了 16 个工具(pdf_tool、data_visualization、contract_generator 等),使总工具数达到 38 个。然而,原有的 10 个意图维度无法覆盖新工具,导致用户说"帮我生成合同"时,LLM 压根不知道系统里有 contract_generator 这个工具!

核心问题:如何让 LLM 从 38+ 工具中精准选择正确工具?全量暴露会造成"选择困难",手动指定又不够智能。

解决方案:设计 17 维关键词矩阵 × 意图-工具映射表 × 优先级权重表 + 动态 System Prompt 注入,实现"关键词 → 意图 → 工具推荐 → Prompt 指引"的智能路由链路。

关键成果

  • 意图维度从 10 → 17,关键词从 ~90 → ~170

  • 工具发现率从 ~75% → 100%(15/15 测试用例全通过)

  • CORE_SYSTEM_PROMPT 扩展至 6029 字符,包含 6 个工具场景决策树

  • 三层置信度分级:高 (≥0.8) / 中 (0.5-0.8) / 低 (<0.5)

适合读者:有 Python 基础,对 AI 助手工具选择、System Prompt 工程、Function Calling 机制感兴趣的开发者

阅读时长:约 20 分钟

关键词意图识别工具路由关键词矩阵System Prompt 工程Function Calling置信度评估


一、工具多了,LLM 反而"选择困难"了

1.1 场景重现:三个让人头疼的"选错工具"案例

想象一下这些对话场景:

案例 1:PPT 变 Word

复制代码
用户:帮我做个关于 AI 发展的 PPT

LLM:好的,我来帮您生成一份 Word 文档... [调用 doc_generator]

用户:???我要的是 PPT 啊!

案例 2:Excel 分析失踪

复制代码
用户:分析一下这个 sales_data.xlsx 文件的销售趋势

LLM:我来帮您读取文件内容... [调用 file.read]

用户:我要的是数据分析和图表,不是看原始内容!

案例 3:合同工具"隐身"

复制代码
用户:帮我生成一份房屋租赁合同

LLM:好的,我来搜索一些合同模板资料... [调用 search.web_search]

用户:系统里不是有合同生成工具吗?

问题的本质:LLM 不知道系统里有什么工具,或者面对 38 个工具时"无从下手"。

1.2 四种方案对比:从"全量暴露"到"智能路由"

| 方案 | 像什么?(比喻) | 优点 | 缺点 | 适用场景 |

|------|----------------|------|------|---------|

| 全量暴露 | 把整个工具箱倒在桌上 | 实现简单,不会遗漏 | Token 浪费;LLM"选择困难" | 工具数 < 10 |

| 手动注入 | 每次告诉工人用哪把扳手 | 精准控制 | 不够智能;维护成本高 | 特定流程 |

| 关键词意图识别 | 机场安检的分流通道 | 自动分类;按需暴露 | 需要精心设计关键词 | 工具数 10-50 |

| 多维置信路由 ✅ | 智能导航 + 实时路况 | 高置信精准,低置信兜底 | 架构复杂 | 工具数 30+ |

复制代码
┌─────────────────────────────────────────────────────────────────────┐

│                      工具数量与策略选择                              │

├─────────────────────────────────────────────────────────────────────┤

│                                                                     │

│   工具数:   5     10      20       30       40       50            │

│            │      │       │        │        │        │             │

│            ▼      ▼       ▼        ▼        ▼        ▼             │

│  策略:  [全量暴露] [关键词分类] [意图路由] [多维置信+渐进暴露]       │

│                                                                     │

│  WeClaw 当前: 38 个工具 → 采用"多维置信路由"                        │

└─────────────────────────────────────────────────────────────────────┘

1.3 核心挑战:既要精准,又不能漏

我们的目标是设计一套系统,满足:

  1. 精准性 :用户说"帮我做个柱状图"→ 应该推荐 data_visualization

  2. 完整性 :新工具(如 contract_generator)不能在意图表中"隐身"

  3. 容错性:即使关键词没匹配上,也能通过低置信度兜底暴露全量工具

  4. 可维护性:新增工具时,只需添加配置,无需大改代码


二、意图识别的"三表联动"架构

2.1 整体架构:从用户输入到工具推荐

让我们用"机场安检分流通道"来理解这套架构:

复制代码
用户输入(旅客)

     │

     ▼

┌─────────────────────────────────────────────────────────────────────┐

│                     关键词匹配(安检通道分流)                         │

│                                                                     │

│  "帮我做个柱状图"                                                   │

│       │                                                             │

│       ├─ 匹配 "柱状图" → data_analysis 意图                         │

│       ├─ 匹配 "可视化" → data_analysis 意图(如果用户这么说)        │

│       └─ 匹配 "图表"   → data_analysis 意图                         │

│                                                                     │

│  置信度计算: 3/17 = 0.18 × 意图权重 → 最终置信度                     │

└─────────────────────────────────────────────────────────────────────┘

     │

     ▼

┌─────────────────────────────────────────────────────────────────────┐

│                     意图-工具映射(登机口指引)                        │

│                                                                     │

│  data_analysis 意图 → [data_processor, data_visualization,          │

│                        financial_report]                            │

└─────────────────────────────────────────────────────────────────────┘

     │

     ▼

┌─────────────────────────────────────────────────────────────────────┐

│                     优先级标注(VIP 通道标识)                        │

│                                                                     │

│  recommended: [data_processor, data_visualization]                  │

│  alternative: [financial_report, python_runner]                     │

└─────────────────────────────────────────────────────────────────────┘

     │

     ▼

┌─────────────────────────────────────────────────────────────────────┐

│                     System Prompt 注入(登机指南)                    │

│                                                                     │

│  在 Schema description 前添加 [推荐] / [备选] 标注                  │

│  + CORE_SYSTEM_PROMPT 中的工具场景决策树                            │

└─────────────────────────────────────────────────────────────────────┘

2.2 三张核心表的职责分工

| 表名 | 像什么? | 职责 | 数据结构 |

|------|---------|------|---------|

| INTENT_CATEGORIES | 机场分流通道标识 | 定义 17 个意图维度及其关键词 | dict[str, list[str]] |

| INTENT_TOOL_MAPPING | 登机口对应关系 | 意图 → 推荐工具列表 | dict[str, list[str]] |

| INTENT_PRIORITY_MAP | VIP/普通通道标识 | 工具优先级:recommended / alternative | dict[str, dict[str, list[str]]] |

三表如何联动?

python 复制代码
# 第一步:从 INTENT_CATEGORIES 识别意图

user_input = "帮我做个柱状图分析销售数据"

matched_intent = "data_analysis"  # 匹配到 "柱状图", "图表", "数据"



# 第二步:从 INTENT_TOOL_MAPPING 获取工具列表

tools = INTENT_TOOL_MAPPING["data_analysis"]

# → ["data_processor", "data_visualization", "financial_report"]



# 第三步:从 INTENT_PRIORITY_MAP 获取优先级

priority = INTENT_PRIORITY_MAP["data_analysis"]

# → {"recommended": ["data_processor", "data_visualization"],

#    "alternative": ["financial_report", "python_runner"]}

2.3 完整流程图:Mermaid 版

复制代码
graph TB

    A[用户输入] --> B[关键词匹配]

    B --> C{匹配到意图?}

    C -->|是| D[计算置信度]

    C -->|否| E[置信度=0]

    D --> F{置信度判断}

    E --> F

    F -->|≥0.8 高| G[推荐工具集 ~10个]

    F -->|0.5-0.8 中| H[扩展工具集 ~20个]

    F -->|<0.5 低| I[全量工具集 38个]

    G --> J[Schema 优先级标注]

    H --> J

    I --> J

    J --> K[注入 System Prompt]

    K --> L[LLM 工具选择]

    L --> M{调用成功?}

    M -->|是| N[重置失败计数]

    M -->|否| O[失败计数+1]

    O --> P{连续失败≥2?}

    P -->|是| Q[自动升级工具集]

    P -->|否| R[等待重试]

三、代码详解------从关键词到工具推荐的全链路

3.1 INTENT_CATEGORIES:17 个意图维度的完整定义

Phase 6 将意图维度从 10 个扩展到 17 个。以下是完整定义(摘自 prompts.py):

python 复制代码
# src/core/prompts.py



INTENT_CATEGORIES: dict[str, list[str]] = {

    # ==================== 原有 10 个意图维度 ====================

    "browser_automation": [

        "打开网页", "浏览器", "网站操作", "网页", "URL", "url",

        "点击", "登录网站", "打开链接", "访问网站", "网站",

    ],

    "file_operation": [

        "读文件", "写文件", "整理", "复制", "移动", "文件夹",

        "目录", "文件", "重命名", "解压", "压缩", "文件内容",

    ],

    "document_assembly": [

        "文档", "word", "docx", "组合", "生成文档", "整合",

        "组装", "报告", "保存到文档", "写到文档", "制作文档",

        "创建文档", "生成一份文档", "合并内容", "组装成文档",

    ],

    # ... 省略 mcp_task, system_admin, daily_assistant, knowledge,

    #     life_management, email_task, multimedia ...

    

    # ==================== 新增 7 个意图维度 ====================

    "document_processing": [

        "PDF", "pdf", "合并pdf", "拆分pdf", "加密pdf", "解密pdf",

        "格式转换", "转换格式", "docx转pdf", "md转docx", "转成pdf",

        "PPT", "ppt", "幻灯片", "演示文稿", "做PPT", "生成PPT",

        "转换", "导出",

    ],

    "data_analysis": [

        "数据分析", "数据处理", "Excel分析", "excel", "xlsx",

        "图表", "柱状图", "折线图", "饼图", "散点图", "热力图",

        "数据可视化", "可视化", "仪表盘", "dashboard",

        "财务报表", "资产负债表", "利润表", "现金流量表", "财务分析",

        "财务报告", "报表",

    ],

    "creative_content": [

        "写论文", "写文章", "写小说", "续写", "写作",

        "证件照", "一寸照", "二寸照", "换背景",

        "GIF", "gif", "动图", "制作gif", "图片合成",

        "思维导图", "脑图", "mindmap", "mind map",

        "篇论文", "篇文章", "篇小说",  # ✅ 支持 "写一篇论文" 表达

    ],

    "professional_docs": [

        "合同", "租赁合同", "劳动合同", "买卖合同", "服务合同",

        "合同模板", "生成合同",

        "简历", "个人简历", "求职简历", "简历模板", "生成简历",

    ],

    "development": [

        "代码模板", "代码分析", "代码格式化", "生成测试",

        "代码生成", "代码骨架", "API模板", "代码复杂度",

        "format code", "analyze code",

        "格式化代码", "格式化这段", "格式化python",  # ✅ 支持变体

    ],

    "education": [

        "出题", "测验", "考试题", "练习题", "做题",

        "闪卡", "flashcard", "记忆卡",

        "学习计划", "复习计划", "学习安排",

        "概念解释", "解释概念", "什么是",

        "选择题", "填空题", "问答题", "数学题", "道题",  # ✅ 支持变体

    ],

    "research": [

        "文献检索", "搜论文", "查论文", "学术搜索",

        "引用", "参考文献", "文献综述", "OpenAlex",

        "相关论文", "搜索论文", "检索论文",

    ],

}

关键设计点

  1. 关键词变体覆盖:不只是"写论文",还包括"篇论文"(匹配"写一篇论文")

  2. 多语言支持:同时包含中文"格式化代码"和英文"format code"

  3. 精确分类:PPT 从 document_assembly 移到 document_processing,避免混淆

3.2 关键词冲突的解决------三个真实案例

案例 1:"PDF" 的多义性

python 复制代码
# ❌ 修改前:"PDF" 在 knowledge 意图中

# 导致用户说"合并 PDF"时,系统推荐 knowledge_rag 工具(错误!)



# ✅ 修改后:"PDF" 移到 document_processing 意图

"document_processing": [

    "PDF", "pdf", "合并pdf", "拆分pdf", ...

],

案例 2:"图片" 的歧义

python 复制代码
# ❌ 修改前:"图片" 在 ASSEMBLY_KEYWORDS 中

# 导致用户说"生成一张证件照"时,触发文档组装流程



# ✅ 修改后:从 ASSEMBLY_KEYWORDS 移除"图片"

ASSEMBLY_KEYWORDS = [

    "文档", "word", "docx", "组合", "生成文档",

    # "图片",  ← 删除!图片相关由 creative_content 处理

    ...

]

案例 3:"论文" 的精确化

python 复制代码
# 问题:用户说"写一篇论文" vs "搜索论文"

# - "写论文" → creative_content → ai_writer

# - "搜论文" → research → literature_search



# ✅ 解决方案:在 knowledge 中只保留"论文分析"相关

"knowledge": [

    "知识库", "文档搜索", "语义搜索", "RAG", "rag",

    "论文分析", "批量论文",  # 精确区分,避免与 research 冲突

],

3.3 INTENT_TOOL_MAPPING:意图到工具的映射表

python 复制代码
# src/core/prompts.py



INTENT_TOOL_MAPPING: dict[str, list[str]] = {

    "browser_automation": [

        "browser", "browser_use", "mcp_browserbase", "mcp_browserbase-csdn",

    ],

    "file_operation": ["file", "shell"],

    "document_assembly": [

        "doc_generator", "image_generator", "weather", "file",

    ],

    # ... 原有意图映射 ...

    

    # ==================== 新增 7 个意图的工具映射 ====================

    "document_processing": [

        "pdf_tool", "format_converter", "ppt_generator",

    ],

    "data_analysis": [

        "data_processor", "data_visualization", "financial_report",

    ],

    "creative_content": [

        "ai_writer", "id_photo", "gif_maker", "mind_map",

    ],

    "professional_docs": [

        "contract_generator", "resume_builder",

    ],

    "development": [

        "coding_assistant", "python_runner",

    ],

    "education": [

        "education_tool",

    ],

    "research": [

        "literature_search",

    ],

}

设计原则

  • ✅ 每个意图映射 1-4 个工具(不宜过多)

  • ✅ 相关性最强的工具排在前面

  • ✅ 可以跨意图共享工具(如 python_runner 在 knowledge 和 development 中)

3.4 INTENT_PRIORITY_MAP:推荐与备选的优先级

python 复制代码
# src/core/prompts.py



INTENT_PRIORITY_MAP: dict[str, dict[str, list[str]]] = {

    # ... 原有配置 ...

    

    # ==================== 新增 7 个意图的优先级配置 ====================

    "document_processing": {

        "recommended": ["pdf_tool", "format_converter", "ppt_generator"],

        "alternative": ["doc_generator", "shell"],  # shell 用于特殊转换

    },

    "data_analysis": {

        "recommended": ["data_processor", "data_visualization"],

        "alternative": ["financial_report", "python_runner"],

    },

    "creative_content": {

        "recommended": ["ai_writer", "id_photo", "gif_maker", "mind_map"],

        "alternative": ["doc_generator", "image_generator"],

    },

    "professional_docs": {

        "recommended": ["contract_generator", "resume_builder"],

        "alternative": ["doc_generator"],  # 兜底用通用文档生成

    },

    "development": {

        "recommended": ["coding_assistant"],

        "alternative": ["python_runner", "shell"],

    },

    "education": {

        "recommended": ["education_tool"],

        "alternative": [],  # 无备选,education_tool 功能完备

    },

    "research": {

        "recommended": ["literature_search"],

        "alternative": ["knowledge_rag", "search"],  # 兜底用通用搜索

    },

}

recommended vs alternative 的区别

| 优先级 | 在 Schema 中的标注 | 使用场景 |

|--------|-------------------|---------|

| recommended | [推荐] 工具描述... | 意图匹配度高时优先使用 |

| alternative | [备选] 工具描述... | 推荐工具不适用时的备选 |

3.5 detect_intent_with_confidence():多维度意图识别算法

这是意图识别的核心方法,实现了"关键词匹配 → 置信度评估 → 主意图判定"的完整流程:

python 复制代码
# src/core/prompts.py



def detect_intent_with_confidence(user_input: str) -> IntentResult:

    """多维度意图识别 + 置信度评估。



    1. 对每个意图维度做关键词匹配并计分

    2. 单一意图匹配 → 高置信度 (0.8-1.0)

    3. 多意图且分数差距大 → 中置信度 (0.5-0.8)

    4. 多意图且分数接近 → 低置信度 (0.3-0.5)

    5. 无匹配 → 极低置信度 (0.0)

    """

    input_lower = user_input.lower()



    # ========== 第一步:各维度关键词匹配 ==========

    intent_scores: dict[str, float] = {}

    intent_matched: dict[str, list[str]] = {}



    for intent_name, keywords in INTENT_CATEGORIES.items():

        matched = [kw for kw in keywords if kw in input_lower]

        if matched:

            # 得分 = 匹配关键词数 / 该意图总关键词数 (归一化)

            score = len(matched) / len(keywords)

            intent_scores[intent_name] = score

            intent_matched[intent_name] = matched



    # ========== 第二步:特殊排除规则 ==========

    # assembly 意图排除博客写作等场景

    if "document_assembly" in intent_scores:

        if any(kw in input_lower for kw in EXCLUDE_ASSEMBLY_KEYWORDS):

            del intent_scores["document_assembly"]

            intent_matched.pop("document_assembly", None)



    # ========== 第三步:置信度计算 ==========

    if not intent_scores:

        # 无匹配:极低置信度

        return IntentResult(confidence=0.0, primary_intent="")



    sorted_intents = sorted(intent_scores.items(), key=lambda x: x[1], reverse=True)

    primary_intent = sorted_intents[0][0]

    top_score = sorted_intents[0][1]



    if len(sorted_intents) == 1:

        # 单一意图:高置信度 (0.8-1.0)

        confidence = 0.8 + top_score * 0.2

        intents = {primary_intent}

    else:

        second_score = sorted_intents[1][1]

        gap = top_score - second_score



        if gap >= 0.3:

            # 多意图但主意图明显领先:中置信度 (0.5-0.8)

            confidence = min(0.5 + gap, 0.8)

            intents = {primary_intent}

            if second_score >= 0.15:

                intents.add(sorted_intents[1][0])  # 包含第二意图

        else:

            # 多意图且分数接近:低置信度 (0.3-0.5)

            confidence = 0.3 + gap * 0.5

            intents = {name for name, score in sorted_intents if score >= 0.1}



    # ========== 第四步:确定 Prompt 模块注入 ==========

    prompt_modules: set[str] = set()

    if "document_assembly" in intents:

        prompt_modules.add("assembly")

    if "mcp_task" in intents:

        prompt_modules.add("mcp")



    return IntentResult(

        intents=intents,

        confidence=confidence,

        primary_intent=primary_intent,

        matched_keywords=intent_matched,

        scores=intent_scores,

        prompt_modules=prompt_modules,

    )

置信度分级表

| 置信度范围 | 场景 | 暴露策略 |

|-----------|------|---------|

| 0.8-1.0 | 单一意图,关键词明确 | 推荐工具集(~10 个) |

| 0.5-0.8 | 多意图但主意图明显 | 扩展工具集(~20 个) |

| 0.3-0.5 | 多意图且分数接近 | 全量工具集(38 个) |

| 0.0 | 无匹配 | 全量工具集(38 个) |


四、关键词冲突诊断------多义词是最大陷阱

4.1 真实案例:"PDF" 导致的工具选择错误

问题现象

复制代码
用户:帮我合并这三个 PDF 文件

LLM:好的,我来在知识库中搜索相关内容... [调用 knowledge_rag.search]

用户:不是搜索!是合并 PDF!

日志分析

复制代码
2026-03-22 10:15:32 | prompts | DEBUG | 意图识别结果:

  intents={'knowledge'}

  primary_intent='knowledge'

  matched_keywords={'knowledge': ['PDF']}  ← 问题!PDF 在 knowledge 里

  confidence=0.82

根本原因

原设计中,"PDF" 关键词在 knowledge 意图下(因为知识库支持 PDF 文档检索),但用户说"合并 PDF"时的意图是文档处理,不是知识检索。

修复方案

python 复制代码
# ❌ 修改前

"knowledge": [

    "知识库", "文档搜索", "语义搜索", "RAG", "PDF",  # PDF 在这里

    ...

],



# ✅ 修改后

"knowledge": [

    "知识库", "文档搜索", "语义搜索", "RAG", "rag", "向量", "索引",

    "论文分析", "批量论文",  # PDF 移走了!

],

"document_processing": [

    "PDF", "pdf", "合并pdf", "拆分pdf", "加密pdf", "解密pdf",  # PDF 在这里

    ...

],

4.2 排查思路:三步定位冲突

复制代码
┌─────────────────────────────────────────────────────────────────────┐

│                        关键词冲突排查三步法                          │

├─────────────────────────────────────────────────────────────────────┤

│                                                                     │

│  第一步:复现 → 记录用户输入,观察 matched_keywords 日志             │

│           ↓                                                         │

│  第二步:归属检查 → 该关键词应该属于哪个意图?                        │

│           ↓                                                         │

│  第三步:冲突验证 → 检查是否有其他意图也包含该关键词                  │

│           ↓                                                         │

│  修复:移动关键词到正确意图 / 添加到排除词列表                        │

│                                                                     │

└─────────────────────────────────────────────────────────────────────┘

4.3 EXCLUDE_ASSEMBLY_KEYWORDS:排除词的作用

有些场景虽然包含"文档"等关键词,但不应该触发文档组装流程:

python 复制代码
# src/core/prompts.py



EXCLUDE_ASSEMBLY_KEYWORDS = [

    "写博客", "发博客", "写一篇博客", "发布博客",  # 博客是 MCP 任务

    "登录", "注册", "搜索", "查询",                 # 通用动作

    # 新增:防止与 document_processing 冲突

    "合并pdf", "拆分pdf", "格式转换", "转换格式",  # PDF 操作不是组装

    "PPT", "ppt", "幻灯片",                        # PPT 不是 Word 组装

]

工作原理

python 复制代码
# 在 detect_intent_with_confidence() 中

if "document_assembly" in intent_scores:

    if any(kw in input_lower for kw in EXCLUDE_ASSEMBLY_KEYWORDS):

        del intent_scores["document_assembly"]  # 排除!

4.4 测试验证:15/15 用例全通过

修复后的测试结果:

| 序号 | 用户输入 | 期望意图 | 期望工具 | 结果 |

|------|---------|---------|---------|------|

| 1 | 帮我做个PPT | document_processing | ppt_generator | ✅ |

| 2 | 合并这三个PDF | document_processing | pdf_tool | ✅ |

| 3 | 生成租赁合同 | professional_docs | contract_generator | ✅ |

| 4 | 分析sales.xlsx | data_analysis | data_processor | ✅ |

| 5 | 做个柱状图 | data_analysis | data_visualization | ✅ |

| 6 | 写一篇论文 | creative_content | ai_writer | ✅ |

| 7 | 搜索相关论文 | research | literature_search | ✅ |

| 8 | 出10道数学选择题 | education | education_tool | ✅ |

| 9 | 格式化这段Python代码 | development | coding_assistant | ✅ |

| 10 | 制作个人简历 | professional_docs | resume_builder | ✅ |

| 11 | 生成财务报表 | data_analysis | financial_report | ✅ |

| 12 | 做个思维导图 | creative_content | mind_map | ✅ |

| 13 | 音频转文字 | multimedia | speech_to_text | ✅ |

| 14 | 制作证件照 | creative_content | id_photo | ✅ |

| 15 | 做个GIF动图 | creative_content | gif_maker | ✅ |


五、System Prompt 工程------让 LLM 主动选对工具

5.1 CORE_SYSTEM_PROMPT:6029 字符的工具指南

CORE_SYSTEM_PROMPT 是每次对话都会注入的核心提示词,包含了 6 个工具场景决策树

python 复制代码
# src/core/prompts.py



CORE_SYSTEM_PROMPT = """你是 WeClaw,一个运行在 Windows 上的 AI 桌面智能体。

...



【浏览器工具选择指南】

...

【选择决策树】

- 任务是否需要已登录的网站账号?→ 是 → mcp_browserbase-csdn

- 任务是否需要多步骤自主决策?→ 是 → browser_use.run_task

- 是否需要自动识别页面元素?→ 是 → browser_use.*

- 是否知道确切的 CSS 选择器?→ 是 → browser.click / browser.type_text

- 是否只是简单打开 URL 截图?→ 是 → browser.open_url + browser.screenshot



【文档处理工具选择指南】

...

【选择决策树】

- 需要操作已有 PDF 文件(合并/拆分/加密)?→ pdf_tool

- 需要格式之间互转?→ format_converter

- 需要从零生成 PPT?→ ppt_generator

- 需要从内容生成 Word 文档?→ doc_generator



【数据分析工具选择指南】

...

【选择决策树】

- 需要读取/处理/导出数据?→ data_processor

- 需要生成图表或可视化?→ data_visualization

- 需要专业财务报表?→ financial_report

- 需要数据+图表组合?→ data_processor 读取 + data_visualization 生成图表



【创作与多媒体工具选择指南】

...



【专业文档工具选择指南】

...



【开发与学习工具选择指南】

...

"""

决策树的设计理念

  1. 问题驱动:用"是否需要 XXX?"的问题引导 LLM 做选择

  2. 层层递进:从最具体的场景开始判断,避免歧义

  3. 兜底覆盖:每个决策树都有默认路径

5.2 为什么 6029 字符刚刚好?

| Prompt 长度 | 优点 | 缺点 |

|------------|------|------|

| < 2000 字符 | Token 消耗少 | 指引不够详细,LLM 容易选错 |

| 2000-6000 字符 ✅ | 平衡精准度和成本 | 需要精心组织结构 |

| > 10000 字符 | 覆盖全面 | Token 成本高;LLM 可能"忘记"前面内容 |

我们的选择:6029 字符,包含 6 个决策树,覆盖 90% 的常见场景。

5.3 动态 Prompt 模块注入

根据意图识别结果,按需注入额外的 Prompt 模块:

python 复制代码
# src/core/prompts.py



def build_system_prompt_from_intent(intent_result: IntentResult) -> str:

    """根据意图识别结果构建 System Prompt。"""

    parts = [CORE_SYSTEM_PROMPT]



    # 始终注入陪伴模块 - 陪伴角色是 WeClaw 的核心身份

    parts.append(COMPANION_PROMPT_MODULE)



    # 按需注入组装任务指南

    if "assembly" in intent_result.prompt_modules:

        parts.append(ASSEMBLY_TASK_PROMPT)



    # 按需注入 MCP 工具指南

    if "mcp" in intent_result.prompt_modules:

        parts.append(MCP_TOOL_GUIDE_PROMPT)



    return "\n\n".join(parts)

模块化 Prompt 的优势

复制代码
┌─────────────────────────────────────────────────────────────────────┐

│                       Prompt 组装示意图                              │

├─────────────────────────────────────────────────────────────────────┤

│                                                                     │

│  CORE_SYSTEM_PROMPT (6029 字符)                                     │

│        +                                                            │

│  COMPANION_PROMPT_MODULE (300 字符) [始终注入]                       │

│        +                                                            │

│  ASSEMBLY_TASK_PROMPT (2000 字符) [仅组装任务注入]                   │

│        +                                                            │

│  MCP_TOOL_GUIDE_PROMPT (800 字符) [仅 MCP 任务注入]                  │

│        =                                                            │

│  最终 System Prompt (6329 ~ 9129 字符)                              │

│                                                                     │

└─────────────────────────────────────────────────────────────────────┘

5.4 Do's & Don'ts

✅ 推荐做法

python 复制代码
# ✅ 决策树式指引,问题驱动

【选择决策树】

- 需要合并/拆分 PDF?→ pdf_tool

- 需要格式转换?→ format_converter



# ✅ 在 Schema description 中添加优先级标注

schema["function"]["description"] = f"[推荐] {original_desc}"



# ✅ 使用排除词避免错误触发

EXCLUDE_ASSEMBLY_KEYWORDS = ["合并pdf", "PPT", ...]

❌ 避免做法

python 复制代码
# ❌ 简单罗列工具名,没有选择指引

"""可用工具:pdf_tool, format_converter, ppt_generator, doc_generator"""

# LLM:这四个有什么区别?我该用哪个?



# ❌ Prompt 过长,超过 10000 字符

# LLM 可能"忘记"前面的指引



# ❌ 关键词重复出现在多个意图中,没有排除机制

"knowledge": ["PDF", ...],

"document_processing": ["PDF", ...],  # 冲突!

六、总结与展望

6.1 核心要点回顾

本文讲解了 WeClaw 工具智能路由系统的设计与实现:

3 张核心表的协作

| 表 | 作用 | 规模 |

|----|------|------|

| INTENT_CATEGORIES | 17 个意图维度,~170 个关键词 | 关键词矩阵 |

| INTENT_TOOL_MAPPING | 意图 → 工具列表 | 路由表 |

| INTENT_PRIORITY_MAP | recommended / alternative | 优先级表 |

1 个核心公式

复制代码
精准工具路由 = 关键词矩阵 × 意图映射 × 优先级权重 + 动态 Prompt 注入

             × 置信度分层 × 自动回退机制

关键数字

  • 意图维度:10 → 17(+7 个新维度)

  • 关键词数:~90 → ~170(+80%)

  • 工具发现率:~75% → 100%(15/15 全通过)

  • CORE_SYSTEM_PROMPT:~2000 → 6029 字符

6.2 扩展阅读

前置知识

  • ✅ Function Calling 机制(OpenAI / Claude)

  • ✅ System Prompt 工程基础

  • ✅ Python 数据结构(dict、set)

后续主题

  • 📖 下一篇:《第 27 篇:渐进式工具暴露引擎 --- 三层置信度策略与自动回退机制》

  • 🔜 下下篇:《第 28 篇:Schema 动态优先级标注 --- 让 [推荐]/[备选] 引导 LLM 决策》

6.3 互动环节

思考题

  1. 如果用户说"帮我把这个 Excel 转成 PDF 并加个柱状图",应该触发哪些意图?如何编排多工具协作?

  2. data_analysisdocument_processing 意图同时被匹配时(如"分析数据并导出 PDF 报告"),如何决定主意图?

  3. 为什么选择 0.8 / 0.5 作为置信度分界线?是否有更好的划分方式?

讨论话题

在你的 AI 项目中,是如何处理"工具太多导致选择困难"问题的?是使用意图识别还是其他方案?欢迎在评论区分享你的经验!


下期预告:《第 27 篇:渐进式工具暴露引擎》

  • 🎯 三层工具集:推荐集(~10)→ 扩展集(~20)→ 全量集(38)

  • 📈 置信度驱动:高置信精准暴露,低置信兜底全量

  • 🔄 自动回退:连续失败 ≥2 次自动升级工具集

  • 🏷️ Schema 标注:[推荐] / [备选] 前缀引导决策

敬请期待!


附录 A:17 个意图维度完整关键词参考表

| 意图维度 | 关键词数 | 代表关键词 | 映射工具 |

|---------|---------|-----------|---------|

| browser_automation | 11 | 打开网页, 浏览器, URL | browser, browser_use |

| file_operation | 12 | 读文件, 写文件, 目录 | file, shell |

| document_assembly | 15 | 文档, word, 组装 | doc_generator |

| mcp_task | 6 | browserbase, csdn | mcp_browserbase |

| system_admin | 12 | 进程, 截图, 系统 | shell, screen |

| daily_assistant | 7 | 天气, 日程, 提醒 | weather, cron |

| knowledge | 7 | 知识库, RAG, 论文分析 | knowledge_rag |

| life_management | 11 | 日记, 记账, 健康 | diary, finance |

| email_task | 5 | 邮件, 发邮件, 邮箱 | email |

| multimedia | 17 | 语音, OCR, 图片 | voice_input, ocr |

| document_processing | 18 | PDF, PPT, 格式转换 | pdf_tool, ppt_generator |

| data_analysis | 22 | 数据分析, 图表, 财务 | data_processor, data_visualization |

| creative_content | 16 | 写论文, 证件照, GIF | ai_writer, id_photo |

| professional_docs | 11 | 合同, 简历 | contract_generator, resume_builder |

| development | 11 | 代码模板, 格式化 | coding_assistant |

| education | 14 | 出题, 闪卡, 学习计划 | education_tool |

| research | 11 | 文献检索, 搜论文 | literature_search |

(粗体为 Phase 6 新增维度)


附录 B:参考资料

  1. OpenAI Function Calling 官方文档

  2. Anthropic Tool Use 指南

  3. 上一篇:《第 25 篇:Phase 6 工具扩展方案 --- 16 个新工具 77 个 Actions》

  4. 下一篇:《第 27 篇:渐进式工具暴露引擎》


版权声明:本文为 WeClaw 团队原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接https://blog.csdn.net/yweng18/article/details/xxxxxx(待发布后更新)

相关推荐
Zero2 小时前
机器学习线性代数--(7)逆矩阵、列空间、秩、零空间与非方阵
线性代数·机器学习·矩阵
Zero2 小时前
机器学习线性代数--(12)抽象向量空间:超越箭头的世界
线性代数·机器学习
Zero2 小时前
机器学习线性代数--(9)叉积
人工智能·线性代数·机器学习
Zero2 小时前
机器学习线性代数--(8)点积与对偶性
人工智能·线性代数·机器学习
Zero2 小时前
机器学习线性代数--(11)特征向量与特征值:变换的“主轴”
线性代数·机器学习
lihihi2 小时前
P10474 [ICPC 2011 Beijing R] Matrix 矩阵哈希
矩阵·哈希算法
爱喝纯牛奶的柠檬19 小时前
基于STM32的4*4矩阵软键盘驱动
stm32·嵌入式硬件·矩阵
Frostnova丶19 小时前
LeetCode 48 & 1886.矩阵旋转与判断
算法·leetcode·矩阵
阿Y加油吧1 天前
力扣打卡——搜索二维矩阵、相交链表
线性代数·leetcode·矩阵