使用说明
@portkey ai/mcp工具过滤器
使用嵌入相似性对MCP(模型上下文协议)服务器进行超快速语义工具过滤。将您的工具上下文从1000多个工具减少到最相关的10-20个工具 10ms以下.
特性
- ⚡ 迅速的:1000多种内置优化工具的过滤延迟<10ms
- 🚀 性能优化:6-8倍更快的点积,智能top-K选择,真正的LRU缓存
- 🎯 语义理解:使用嵌入进行智能工具匹配
- 📦 对运行时零依赖:仅需要嵌入提供程序API
- 🔄 灵活输入:接受聊天完成消息或原始字符串
- 💾 智能缓存:缓存嵌入和上下文以获得最佳性能
- 🎛️ 可配置的:调整得分阈值、top-k,并始终包含工具
- 📊 性能指标:内置时间优化
安装
npm install @portkey-ai/mcp-tool-filter
快速开始
import { MCPToolFilter } from '@portkey-ai/mcp-tool-filter';
// 1. Initialize the filter (choose embedding provider)
// Option A: Local Embeddings (RECOMMENDED for low latency < 5ms)
const filter = new MCPToolFilter({
embedding: {
provider: 'local',
}
});
// Option B: API Embeddings (for highest accuracy)
const filter = new MCPToolFilter({
embedding: {
provider: 'openai',
apiKey: process.env.OPENAI_API_KEY,
}
});
// 2. Load your MCP servers (one-time setup)
await filter.initialize(mcpServers);
// 3. Filter tools based on context
const result = await filter.filter(
"Search my emails for the Q4 budget discussion"
);
// 4. Use the filtered tools in your LLM request
console.log(result.tools); // Top 20 most relevant tools
console.log(result.metrics.totalTime); // e.g., "2ms" for local, "500ms" for API
嵌入提供程序选项
局部嵌入(推荐)
赞成的意见:
- ⚡ 超快:1-5ms延迟
- 🔒 Private:没有数据发送到外部API
- 💰 免费:无API费用
- 🌐 离线:无需互联网即可工作
欺骗:
- 精度略低于API模型
- 首次初始化下载模型(~25MB)
const filter = new MCPToolFilter({
embedding: {
provider: 'local',
model: 'Xenova/all-MiniLM-L6-v2', // Optional: default model
quantized: true, // Optional: use quantized model for speed (default: 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维,更高质量
演出
- 初始化:100ms-4s(一次性,下载模式)
- 过滤请求:1-5ms
- 缓存请求:<1ms
API嵌入
为了获得最高精度,请使用OpenAI或其他API提供商:
const filter = new MCPToolFilter({
embedding: {
provider: 'openai',
apiKey: process.env.OPENAI_API_KEY,
model: 'text-embedding-3-small', // Optional
dimensions: 384, // Optional: match local model for fair comparison
}
});
赞成的意见:
- 🎯 最高精度:比当地好5-15%
- 🔄 易于切换型号
- 🌐 不需要当地资源
欺骗:
- 🐌 慢速:每次请求400-800ms
- 💰 成本:每100万代币约0.02美元
- 🔒 发送到外部API的数据
- 📶 需要互联网连接
演出
- 初始化:200ms-60s(取决于刀具数量)
- 滤波请求:400-800ms
- 缓存请求:1-3ms
快速比较
| 方面 | 本地 | API | 获胜者 |
|---|---|---|---|
| 速度 | 1-5ms | 400-800ms | 🏆 本地(速度快200倍) |
| 准确度 | 良好(85-90%) | 最佳(100%) | 🏆 API |
| 成本 | 免费 | 约0.02美元/百万代币 | 🏆 本地 |
| 隐私 | 完全本地 | 发送到API的数据 | 🏆 本地 |
| 离线 | ✅ 脱机工作 | ❌ 需要互联网 | 🏆 本地 |
| 设置 | 零配置 | 需要API密钥 | 🏆 本地 |
📊 看 TRADEOFFS.md 进行详细分析
MCP服务器JSON格式
库需要一组具有以下结构的MCP服务器:
[
{
"id": "gmail",
"name": "Gmail MCP Server",
"description": "Email management tools",
"categories": ["email", "communication"],
"tools": [
{
"name": "search_gmail_messages",
"description": "Search and find email messages in Gmail inbox. Use when user wants to find, search, look up emails...",
"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模式(参数名称用于匹配)
最佳结果提示
-
丰富的描述:用用例写详细的描述
"description": "Search emails in Gmail. Use when user wants to find, lookup, or retrieve messages, correspondence, or mail." -
添加关键字:包括同义词和变体
"keywords": ["email", "mail", "inbox", "messages", "correspondence"] -
提及用例:明确说明何时使用该工具
"description": "... Use when user wants to draft, compose, write, or prepare an email to send later."
API 参考
MCPToolFilter
工具过滤的主类。
构造函数
new MCPToolFilter(config: MCPToolFilterConfig)
配置选项:
{
embedding: {
// Local embeddings (recommended)
provider: 'local',
model?: string, // Default: 'Xenova/all-MiniLM-L6-v2'
quantized?: boolean, // Default: true
// OR API embeddings
provider: 'openai' | 'voyage' | 'cohere',
apiKey: string,
model?: string, // Default: 'text-embedding-3-small'
dimensions?: number, // Default: 1536 (or 384 for local)
baseURL?: string, // For custom endpoints
},
defaultOptions?: {
topK?: number, // Default: 20
minScore?: number, // Default: 0.3
contextMessages?: number, // Default: 3
alwaysInclude?: string[], // Always include these tools
exclude?: string[], // Never include these tools
maxContextTokens?: number, // Default: 500
},
includeServerDescription?: boolean, // Default: false (see below)
debug?: boolean // Enable debug logging
}
关于 includeServerDescription:
启用后,此选项在工具嵌入中包含MCP服务器描述,提供有关工具域/类别的其他上下文。
// Enable server descriptions in embeddings
const filter = new MCPToolFilter({
embedding: { provider: 'local' },
includeServerDescription: true // Default: 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>
基于输入上下文的过滤工具。
输入类型:
// String input
await filter.filter("Search my emails about the project");
// Chat messages
await filter.filter([
{ role: 'user', content: 'What meetings do I have today?' },
{ role: 'assistant', content: 'Let me check your calendar.' }
]);
选项 (全部可选,覆盖默认值):
{
topK?: number, // Max tools to return
minScore?: number, // Minimum similarity score (0-1)
contextMessages?: number, // How many recent messages to use
alwaysInclude?: string[], // Tool names to always include
exclude?: string[], // Tool names to exclude
maxContextTokens?: number, // Max context size
}
退货:
{
tools: ScoredTool[], // Filtered and ranked tools
metrics: {
totalTime: number, // Total time in ms
embeddingTime: number, // Time to embed context
similarityTime: number, // Time to compute similarities
toolsEvaluated: number, // Total tools evaluated
}
}
getStats()
获取有关筛选器状态的统计信息。
const stats = filter.getStats();
// {
// initialized: true,
// toolCount: 25,
// cacheSize: 5,
// embeddingDimensions: 1536
// }
clearCache()
清除上下文嵌入缓存。
filter.clearCache();
性能优化
内置优化
该库包括几个开箱即用的性能优化:
- 🚀 环形无卷点产品 -通过CPU流水线优化,向量相似度计算速度提高了6-8倍
- 📊 智能Top-K选择 -混合算法对典型工作负载使用快速内置排序,对500多种工具切换到基于堆的选择
- 💾 真正的LRU缓存 -基于访问模式的智能缓存驱逐,而不仅仅是插入顺序
- 🎯 就地操作 -通过就地向量归一化减少内存分配
- ⚡ 基于集合的查找 -O(1)排除检查,而不是O(n)阵列扫描
这些优化是自动和透明的,不需要配置!
延迟故障
1000个工具的典型性能:
Building context: <1ms
Embedding API call: 3-5ms (cached: 0ms)
Similarity computation: 1-2ms (6-8x faster with optimizations)
Sorting/filtering: <1ms (hybrid algorithm)
─────────────────────────────
Total: 5-9ms
用户配置提示
-
使用较小的嵌入:512或1024维,计算速度更快
embedding: { provider: 'openai', model: 'text-embedding-3-small', dimensions: 512 // Faster than 1536 } -
减小上下文大小:消息更少=嵌入速度更快
defaultOptions: { contextMessages: 2, // Instead of 3-5 maxContextTokens: 300 } -
利用缓存:相同的上下文重用缓存的嵌入(0ms)
-
调整topK:如果不需要20个工具,请减少工具数量
await filter.filter(input, { topK: 10 });
性能基准
显示优化改进的微观基准:
Dot Product (1536 dims): 0.001ms vs 0.006ms (6x faster)
Vector Normalization: 0.003ms vs 0.006ms (2x faster)
Top-K Selection (<500 tools): Uses optimized built-in sort
Top-K Selection (500+ tools): O(n log k) heap-based selection
LRU Cache Access: True access-order tracking
请参阅现有的端到端性能测试基准示例:
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);
// Filter tools based on conversation
const { tools } = await filter.filter(messages);
// Convert to OpenAI tool format
const openaiTools = tools.map(t => ({
type: 'function',
function: {
name: t.toolName,
description: t.tool.description,
parameters: t.tool.inputSchema,
}
}));
// Make LLM request with filtered tools
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);
// Create a custom tool selector
async function selectTools(messages) {
const { tools } = await filter.filter(messages);
return tools.map(t => convertToLangChainTool(t));
}
// Use in your agent
const model = new ChatOpenAI();
const tools = await selectTools(messages);
const response = await model.invoke(messages, { tools });
缓存策略
// Recommended: Initialize once at startup
let filterInstance: MCPToolFilter;
async function getFilter() {
if (!filterInstance) {
filterInstance = new MCPToolFilter({ /* ... */ });
await filterInstance.initialize(mcpServers);
}
return filterInstance;
}
// Use in request handlers
app.post('/chat', async (req, res) => {
const filter = await getFilter();
const result = await filter.filter(req.body.messages);
// ... use filtered tools
});
基准测试
各种刀具数量的性能(M1 Max):
局部嵌入(Xenova/全MiniLM-L6-v2):
| 工具 | 初始化 | 筛选器(冷) | 筛选器(缓存) |
|---|---|---|---|
| 10 | ~100ms | 2ms | <1ms |
| 100 | ~500ms | 3ms | <1ms |
| 500 | ~2s | 4ms | 1ms |
| 1000 | ~4s | 5ms | 1ms |
| 5000 | ~20s | 8ms | 2ms |
API嵌入(OpenAI text-embedding-3-商城):
| 工具 | 初始化 | 筛选器(冷) | 筛选器(缓存) |
|---|---|---|---|
| 10 | ~200ms | 500ms | 1ms |
| 100 | ~1.5秒 | 550毫秒 | 2毫秒 |
| 500秒 | ~6秒 | 600毫秒 | 2毫秒 |
| 1000 | ~12秒 | 650毫秒 | 3毫秒 |
| 5000 | ~60s | 800ms | 4ms |
关键要点:
- 🚀 本地嵌入是 速度提高200至300倍 用于筛选请求
- ✅ 本地嵌入符合 <50ms目标 轻易地
- 💰 本地嵌入没有API成本
- 📊 API嵌入可能具有略高的精度
- ⚡ 两者都从缓存中受益匪浅
备注:初始化是一次性成本。选择本地嵌入以获得低延迟,选择API嵌入以获得最大精度。
何时使用本地与API嵌入
在以下情况下使用本地嵌入:
- ⚡ 您需要超低延迟(<10ms)
- 🔒 隐私很重要(没有外部API调用)
- 💰 您希望API成本为零
- 🌐 您需要离线操作
- 📊 “足够好”的精度是可以接受的
在以下情况下使用API嵌入:
- 🎯 你需要最大的准确性
- 🌍 您的互联网连接良好
- 💵 API成本不值得关注
- 📈 您正在处理复杂/微妙的查询
建议: 从本地嵌入开始。只有在精度不足时才切换到API。
测试本地与API
比较用例的性能:
npx ts-node examples/test-local-embeddings.ts
这将对这两个提供商进行基准测试,并向您展示:
- 初始化时间
- 平均过滤时间
- 缓存筛选时间
- 速度比较
调试和性能监控
启用调试日志记录
要查看每个请求的详细计时日志,请启用调试模式:
const filter = new MCPToolFilter({
embedding: { /* ... */ },
debug: true // Enable detailed timing logs
});
这将输出每个筛选器请求的详细日志:
=== Starting filter request ===
[1/5] Options merged: 0.12ms
[2/5] Context built (156 chars): 0.34ms
[3/5] Cache MISS (lookup: 0.08ms)
→ Embedding generated: 1247.56ms
[4/5] Similarities computed: 1.23ms (25 tools, 0.049ms/tool)
[5/5] Tools selected & ranked: 0.15ms (5 tools returned)
=== Total filter time: 1249.48ms ===
Breakdown: merge=0.12ms, context=0.34ms, cache=0.08ms, embedding=1247.56ms, similarity=1.23ms, selection=0.15ms
时间分解
每个筛选器请求记录5个步骤:
- 选项合并 (
merge):将提供的选项与默认值合并 - 上下文构建 (
context):根据输入消息构建上下文字符串 - 缓存查找和嵌入 (
cache+embedding):- 缓存HIT:0ms嵌入时间(重用缓存嵌入)
- 缓存MISS:调用嵌入API(通常200-2000ms,取决于提供商)
- 相似度计算 (
similarity):计算所有工具的余弦相似度- 还显示了每个工具的平均时间
- 工具选择 (
selection):按分数筛选并选择前K名工具
示例:测试时间
看 examples/test-timings.ts 完整示例:
export OPENAI_API_KEY=your-key-here
npx ts-node examples/test-timings.ts
这将运行多个筛选器请求,显示:
- 缓存未命中与缓存命中性能
- 不同的查询类型
- 聊天消息上下文处理
性能指标
每个过滤器请求都会返回详细的指标:
const result = await filter.filter(input);
console.log(result.metrics);
// {
// totalTime: 1249.48, // Total request time in ms
// embeddingTime: 1247.56, // Time spent on embedding API
// similarityTime: 1.23, // Time computing similarities
// toolsEvaluated: 25 // Number of tools evaluated
// }
生产监控
const result = await filter.filter(messages);
// Log metrics for monitoring
logger.info('Tool filter performance', {
totalTime: result.metrics.totalTime,
embeddingTime: result.metrics.embeddingTime,
cached: result.metrics.embeddingTime === 0,
toolsReturned: result.tools.length,
});
// Alert if too slow
if (result.metrics.totalTime > 5000) {
logger.warn('Slow filter request', result.metrics);
}
高级用法
两级过滤
对于非常大的工具集,使用分层过滤:
// Stage 1: Filter by server categories
const relevantServers = mcpServers.filter(server =>
server.categories?.some(cat => userIntent.includes(cat))
);
// Stage 2: Filter tools within relevant servers
const result = await filter.filter(messages);
自定义评分
将嵌入相似性与关键字匹配相结合:
const { tools } = await filter.filter(input);
// Boost tools with exact keyword matches
const boostedTools = tools.map(tool => {
const hasKeywordMatch = tool.tool.keywords?.some(kw =>
input.toLowerCase().includes(kw.toLowerCase())
);
return {
...tool,
score: hasKeywordMatch ? tool.score * 1.2 : tool.score
};
}).sort((a, b) => b.score - a.score);
始终包括电动工具
始终包括某些基本工具:
const filter = new MCPToolFilter({
// ...
defaultOptions: {
alwaysInclude: [
'web_search', // Always useful
'conversation_search', // Access to context
],
}
});
故障排除
首次请求缓慢
问题:第一次筛选器调用缓慢。
解决方案:嵌入API调用需要3-5ms。具有类似上下文的后续调用会被缓存,而且速度更快。
// Warm up the cache
await filter.filter("hello"); // ~5ms
await filter.filter("hello"); // ~1ms (cached)
工具选择不当
问题:选择了错误的工具。
解决方案:
- 使用更多关键字和用例改进工具描述
- 降低
minScore阈值 - 增加
topK包含更多工具 - 添加重要工具
alwaysInclude
内存使用
问题:许多工具的内存使用率很高。
解决方案:使用较小的嵌入尺寸:
embedding: {
dimensions: 512 // Instead of 1536
}
这将内存减少约66%,同时精度损失最小。
许可证
麻省理工学院
贡献
欢迎投稿!请打开问题或PR。
支持
- GitHub问题: github/portkey-ai/mcp-tool-filter
- 电子邮件:support@portkey.ai