返回市场
MCP工具过滤器

MCP工具过滤器

作者:Portkey-AI24 星标更新:2025-11-08

项目介绍

技术文档摘要

@portkey-ai/mcp-tool-filter

使用嵌入相似性进行超快速语义工具筛选,适用于MCP(模型上下文协议)服务器。将您的工具上下文从1000多个工具减少到最相关的10-20个工具,时间在10毫秒以内

特点

  • 闪电般快速:对1000多个工具进行筛选延迟小于10毫秒,并内置优化
  • 🚀 性能优化:6-8倍更快的点积计算,智能的Top-K选择,真正的LRU缓存
  • 🎯 语义理解:使用嵌入进行智能工具匹配
  • 📦 运行时零依赖:仅需一个嵌入提供者API
  • 🔄 灵活的输入:接受聊天完成消息或原始字符串
  • 💾 智能缓存:缓存嵌入和上下文以实现最佳性能
  • 🎛️ 可配置:调整评分阈值、Top-K和始终包含的工具
  • 📊 性能指标:内置计时优化

安装

npm install @portkey-ai/mcp-tool-filter

快速开始

import { MCPToolFilter } from '@portkey-ai/mcp-tool-filter';

// 1. 初始化筛选器(选择嵌入提供者)

// 选项A:本地嵌入(推荐用于低延迟<5毫秒)
const filter = new MCPToolFilter({
  embedding: {
    provider: 'local',
  }
});

// 选项B:API嵌入(用于最高精度)
const filter = new MCPToolFilter({
  embedding: {
    provider: 'openai',
    apiKey: process.env.OPENAI_API_KEY,
  }
});

// 2. 加载您的MCP服务器(一次性设置)
await filter.initialize(mcpServers);

// 3. 根据上下文筛选工具
const result = await filter.filter(
  "搜索我的邮件中关于Q4预算讨论的内容"
);

// 4. 在LLM请求中使用筛选后的工具
console.log(result.tools); // 最相关的前20个工具
console.log(result.metrics.totalTime); // 例如,本地为“2ms”,API为“500ms”

嵌入提供者选项

本地嵌入(推荐)

优点:

  • ⚡ 超快:延迟1-5毫秒
  • 🔒 私有:不向外部API发送数据
  • 💰 免费:无API费用
  • 🌐 离线:无需互联网连接

缺点:

  • 准确度略低于API模型
  • 第一次初始化下载模型(约25MB)
const filter = new MCPToolFilter({
  embedding: {
    provider: 'local',
    model: 'Xenova/all-MiniLM-L6-v2', // 可选:默认模型
    quantized: true, // 可选:使用量化模型以提高速度(默认:true)
  }
});

可用模型:

  • Xenova/all-MiniLM-L6-v2(默认)- 384维,非常快
  • Xenova/all-MiniLM-L12-v2 - 384维,更准确
  • Xenova/bge-small-en-v1.5 - 384维,平衡良好
  • Xenova/bge-base-en-v1.5 - 768维,质量更高

性能:

  • 初始化:100毫秒-4秒(一次性,下载模型)
  • 筛选请求:1-5毫秒
  • 缓存请求:<1毫秒

API嵌入

为了获得最高精度,请使用OpenAI或其他API提供者:

const filter = new MCPToolFilter({
  embedding: {
    provider: 'openai',
    apiKey: process.env.OPENAI_API_KEY,
    model: 'text-embedding-3-small', // 可选
    dimensions: 384, // 可选:与本地模型匹配以进行公平比较
  }
});

优点:

  • 🎯 最高精度:比本地高5-15%
  • 🔄 易于切换模型
  • 🌐 不需要本地资源

缺点:

  • 🐌 慢:每次请求400-800毫秒
  • 💰 花钱:~$0.02/1M令牌
  • 🔒 数据发送到外部API
  • 📶 需要互联网连接

性能:

  • 初始化:200毫秒-60秒(取决于工具数量)
  • 筛选请求:400-800毫秒
  • 缓存请求:1-3毫秒

快速对比

方面本地API胜者
速度1-5毫秒400-800毫秒🏆 本地(快200倍)
精度良好(85-90%)最佳(100%)🏆 API
成本免费~$0.02/1M令牌🏆 本地
隐私完全本地数据发送到API🏆 本地
离线✅ 支持离线❌ 需要互联网🏆 本地
设置零配置需要API密钥🏆 本地

📊 查看详细分析 TRADEOFFS.md

MCP服务器JSON格式

库期望一个MCP服务器数组,具有以下结构:

[
  {
    "id": "gmail",
    "name": "Gmail MCP服务器",
    "description": "电子邮件管理工具",
    "categories": ["email", "communication"],
    "tools": [
      {
        "name": "search_gmail_messages",
        "description": "在Gmail收件箱中搜索和查找电子邮件消息。当用户想要查找、搜索、查找电子邮件时使用。",
        "keywords": ["email", "search", "inbox", "messages"],
        "category": "email-search",
        "inputSchema": {
          "type": "object",
          "properties": {
            "q": { "type": "string" }
          }
        }
      }
    ]
  }
]

字段描述

必填字段:

  • id:服务器的唯一标识符
  • name:人类可读的服务器名称
  • tools:工具定义数组
    • name:唯一的工具名称
    • description:工具做什么以及何时使用的丰富描述

可选但推荐:

  • description:服务器级别的描述
  • categories:用于分层过滤的类别标签数组
  • keywords:用于更好匹配的同义词/相关术语数组
  • category:工具级别的类别
  • inputSchema:参数的JSON模式(参数名称用于匹配)

最佳结果提示

  1. 丰富的描述:编写带有用例的详细描述

    "description": "在Gmail中搜索电子邮件。当用户想要查找、查找或检索消息、通信或邮件时使用。"
    
  2. 添加关键词:包括同义词和变体

    "keywords": ["email", "mail", "inbox", "messages", "correspondence"]
    
  3. 提及用例:明确说明何时使用该工具

    "description": "... 当用户想要起草、撰写、编写或将来的邮件时使用。"
    

API参考

MCPToolFilter

工具筛选的主要类。

构造函数

new MCPToolFilter(config: MCPToolFilterConfig)

配置选项:

{
  embedding: {
    // 本地嵌入(推荐)
    provider: 'local',
    model?: string,               // 默认:'Xenova/all-MiniLM-L6-v2'
    quantized?: boolean,          // 默认:true
    
    // 或API嵌入
    provider: 'openai' | 'voyage' | 'cohere',
    apiKey: string,
    model?: string,               // 默认:'text-embedding-3-small'
    dimensions?: number,          // 默认:1536(或本地的384)
    baseURL?: string,            // 用于自定义端点
  },
  defaultOptions?: {
    topK?: number,              // 默认:20
    minScore?: number,          // 默认:0.3
    contextMessages?: number,   // 默认:3
    alwaysInclude?: string[],   // 始终包含这些工具
    exclude?: string[],         // 从不包含这些工具
    maxContextTokens?: number,  // 默认:500
  },
  includeServerDescription?: boolean,  // 默认:false(见下文)
  debug?: boolean               // 启用调试日志
}

关于includeServerDescription

启用此选项将在工具嵌入中包含MCP服务器描述,提供有关工具领域/类别的附加上下文。

// 在嵌入中启用服务器描述
const filter = new MCPToolFilter({
  embedding: { provider: 'local' },
  includeServerDescription: true  // 默认:false
});

权衡:

  • 有助于:一般意图查询如“管理我的本地文件”(+25%改进)
  • 有害于:特定工具查询如“执行这个SQL查询”(-50%退化)
  • 中立:总体影响是中性的(0%变化)

建议:除非您的用例主要涉及高级意图查询,否则保持禁用(默认:false)。查看examples/benchmark-server-description.ts以获取详细的基准测试。

方法

initialize(servers: MCPServer[]): Promise<void>

使用MCP服务器初始化筛选器。这会预先计算并缓存所有工具嵌入。

注意:启动时调用一次。这是一个异步操作,具体耗时取决于工具的数量。

await filter.initialize(servers);
filter(input: FilterInput, options?: FilterOptions): Promise<FilterResult>

根据输入上下文筛选工具。

输入类型:

// 字符串输入
await filter.filter("搜索我关于项目的电子邮件");

// 聊天消息
await filter.filter([
  { role: 'user', content: '今天我有哪些会议?' },
  { role: 'assistant', content: '让我检查一下你的日程。' }
]);

选项(全部可选,覆盖默认值):

{
  topK?: number,              // 返回的最大工具数
  minScore?: number,          // 最小相似度分数(0-1)
  contextMessages?: number,   // 使用多少最近的消息
  alwaysInclude?: string[],   // 始终包含的工具名称
  exclude?: string[],         // 排除的工具名称
  maxContextTokens?: number,  // 上下文大小的最大值
}

返回:

{
  tools: ScoredTool[],        // 筛选并排名的工具
  metrics: {
    totalTime: number,        // 总耗时(毫秒)
    embeddingTime: number,    // 嵌入上下文的时间
    similarityTime: number,   // 计算相似度的时间
    toolsEvaluated: number,   // 总共评估的工具数
  }
}
getStats()

获取筛选器状态的统计信息。

const stats = filter.getStats();
// {
//   initialized: true,
//   toolCount: 25,
//   cacheSize: 5,
//   embeddingDimensions: 1536
// }
clearCache()

清除上下文嵌入缓存。

filter.clearCache();

性能优化

内置优化

库包括几个开箱即用的性能优化:

  1. 🚀 循环展开的点积 - 通过CPU流水线优化,矢量相似性计算速度快6-8倍
  2. 📊 智能Top-K选择 - 混合算法使用快速内置排序处理典型工作负载,对于500+工具切换到基于堆的选择
  3. 💾 真正的LRU缓存 - 基于访问模式而非插入顺序的智能缓存驱逐
  4. 🎯 就地操作 - 通过就地向量归一化减少内存分配
  5. ⚡ 集合查找 - O(1)排除检查而不是O(n)数组扫描

这些优化是自动且透明的 - 无需配置!

延迟分解

1000个工具的典型性能:

构建上下文:        <1毫秒
嵌入API调用:      3-5毫秒  (缓存:0毫秒)
相似度计算:      1-2毫秒  (优化后6-8倍更快)
排序/筛选:       <1毫秒   (混合算法)
─────────────────────────────
总计:                   5-9毫秒

用户配置提示

  1. 使用较小的嵌入:512或1024维度以加快计算

    embedding: {
      provider: 'openai',
      model: 'text-embedding-3-small',
      dimensions: 512  // 比1536更快
    }
    
  2. 减少上下文大小:较少的消息=更快的嵌入

    defaultOptions: {
      contextMessages: 2,  // 而不是3-5
      maxContextTokens: 300
    }
    
  3. 利用缓存:相同的上下文重用缓存的嵌入(0毫秒)

  4. 调整topK:如果您不需要20个工具,请求更少的工具

    await filter.filter(input, { topK: 10 });
    

性能基准测试

显示优化改进的微基准测试:

点积(1536维):        0.001毫秒 vs 0.006毫秒(6倍更快)
向量归一化:           0.003毫秒 vs  0.006毫秒(2倍更快)
Top-K选择(<500工具):   使用优化的内置排序
Top-K选择(500+工具):   O(n log k)基于堆的选择
LRU缓存访问:           真实的访问顺序跟踪

查看现有的基准测试示例以进行端到端性能测试:

npx ts-node examples/benchmark.ts

集成示例

与Portkey AI网关集成

import Portkey from 'portkey-ai';
import { MCPToolFilter } from '@portkey-ai/mcp-tool-filter';

const portkey = new Portkey({ apiKey: '...' });
const filter = new MCPToolFilter({ /* ... */ });

await filter.initialize(mcpServers);

// 根据对话筛选工具
const { tools } = await filter.filter(messages);

// 转换为OpenAI工具格式
const openaiTools = tools.map(t => ({
  type: 'function',
  function: {
    name: t.toolName,
    description: t.tool.description,
    parameters: t.tool.inputSchema,
  }
}));

// 使用筛选后的工具进行LLM请求
const completion = await portkey.chat.completions.create({
  model: 'gpt-4',
  messages: messages,
  tools: openaiTools,
});

与LangChain集成

import { ChatOpenAI } from 'langchain/chat_models/openai';
import { MCPToolFilter } from '@portkey-ai/mcp-tool-filter';

const filter = new MCPToolFilter({ /* ... */ });
await filter.initialize(mcpServers);

// 创建自定义工具选择器
async function selectTools(messages) {
  const { tools } = await filter.filter(messages);
  return tools.map(t => convertToLangChainTool(t));
}

// 在您的代理中使用
const model = new ChatOpenAI();
const tools = await selectTools(messages);
const response = await model.invoke(messages, { tools });

缓存策略

// 推荐:启动时初始化一次
let filterInstance: MCPToolFilter;

async function getFilter() {
  if (!filterInstance) {
    filterInstance = new MCPToolFilter({ /* ... */ });
    await filterInstance.initialize(mcpServers);
  }
  return filterInstance;
}

// 在请求处理器中使用
app.post('/chat', async (req, res) => {
  const filter = await getFilter();
  const result = await filter.filter(req.body.messages);
  // ... 使用筛选后的工具
});

基准测试

不同工具数量下的性能(M1 Max):

本地嵌入(Xenova/all-MiniLM-L6-v2):

工具初始化筛选(冷)筛选(缓存)
10~100毫秒2毫秒<1毫秒
100~500毫秒3毫秒<1毫秒
500~2秒4毫秒1毫秒
1000~4秒5毫秒1毫秒
5000~20秒8毫秒2毫秒

API嵌入(OpenAI text-embedding-3-small):

工具初始化筛选(冷)筛选(缓存)
10~200毫秒500毫秒1毫秒
100~1.5秒5