延迟工具加载服务

MCP生态系统中的延迟工具加载服务,通过仅发送轻量级元数据减少令牌使用,提高效率。

  • by app-appplayer
  • Dart
  • 本地部署
  • 更新于
在 GitHub 查看 app-appplayer/mcp-labs

使用说明

MCP实验室

MCP(模型上下文协议)生态系统的实验功能和增强功能。

延迟工具加载

渐进式工具披露模式的灵感来自Claude Code的“技能”系统。它不会在每次请求时向LLM发送完整的工具模式,而是只发送轻量级元数据(名称+描述),从而大大减少了令牌的使用。

主要优势

特性 描述
令牌减少 工具定义的令牌减少60-80%
零中断更改 100%向后兼容
仅选择加入 默认禁用
自动 只需设置一个标志,无需手动设置

运作原理

Normal Flow:
  User Request → [Full Tool Schemas] → LLM → Execute Tools
                      ↑
                  Many tokens

Deferred Loading Flow:
  User Request → [Metadata Only] → LLM → Validate → Execute Tools
                      ↑                      ↓
                  Few tokens          If invalid: Retry with full schema

用法

基本用法(mcp_llm)

import 'package:mcp_llm/mcp_llm.dart';

// Enable deferred loading when creating LlmClient
final client = LlmClient(
  llmProvider: provider,
  mcpClient: mcpClient,
  useDeferredLoading: true,  // Enable token optimization
);

// Use normally - deferred loading is handled automatically
final response = await client.chat('Search for Flutter tutorials');

使用MCPLlm工厂

final mcpLlm = MCPLlm();
mcpLlm.registerProvider('claude', ClaudeProviderFactory());

final client = await mcpLlm.createClient(
  providerName: 'claude',
  config: LlmConfiguration(apiKey: 'your-api-key'),
  mcpClient: mcpClient,
  useDeferredLoading: true,  // Enable here
);

独立mcp_client使用情况(无mcp_llm)

import 'package:mcp_client/mcp_client.dart';

final registry = ToolRegistry();

// Fetch and cache tools
final tools = await mcpClient.listTools();
registry.cacheFromTools(tools);

// Get lightweight metadata for your LLM integration
final metadata = registry.getAllMetadata();
final toolsForLlm = metadata.map((m) => m.toJson()).toList();

// Later, get full schema when needed for validation/execution
final fullSchema = registry.getSchema('search');

使用客户端扩展

final registry = ToolRegistry();
final metadata = await client.listToolsMetadata(registry);
// metadata: lightweight for LLM context
// registry: contains full schemas for later lookup

api参考

mcp_client类

工具元数据

轻量级工具表示(仅名称+描述)。

// Create from Tool object
final metadata = ToolMetadata.fromTool(tool);

// Create from Map
final metadata = ToolMetadata.fromMap({'name': 'search', 'description': 'Search the web'});

// Serialize (no inputSchema - token efficient)
final json = metadata.toJson();

工具注册表

工具定义的缓存层。

final registry = ToolRegistry();

// Cache tools
registry.cacheFromTools(tools);      // From Tool list
registry.cacheFromMaps(toolMaps);    // From Map list

// Get metadata (lightweight)
registry.getAllMetadata();           // All metadata
registry.getMetadata('search');      // Specific tool

// Get full schema (for validation/execution)
registry.getSchema('search');

// Status
registry.isInitialized;              // true/false
registry.count;                      // Number of cached tools
registry.toolNames;                  // ['search', 'calculator', ...]
registry.hasTool('search');          // true/false

// Invalidate on tools/list_changed notification
registry.invalidateAll();

mcp_llm类

验证结果

工具调用验证结果。

final valid = ValidationResult.valid();
final invalid = ValidationResult.invalid('Missing required parameter: query');

_logger.debug('isValid: ${result.isValid}');  // true/false
_logger.debug('error: ${result.error}');      // null or error message

LlmToolMetadata

LLM特定的轻量级元数据。

const metadata = LlmToolMetadata(name: 'search', description: 'Search for information');
final json = metadata.toJson();  // Excludes inputSchema

DeferredToolManager

编排层(当useDeferredLoading=true时,由LlmClient自动创建)。

// Usually handled internally by LlmClient
// For advanced use:
final manager = DeferredToolManager();
await manager.initialize(mcpClientManager);

manager.getMetadataForLlm();              // For LLM context
manager.getFullSchema('search');          // For validation
manager.validateToolCall('search', args); // Returns ValidationResult
manager.invalidate();                     // On tools/list_changed

项目

mcp_client_defer_loading

增强 mcp_client 支持延迟工具加载的软件包。

  • ToolMetadata -轻量级工具表示
  • ToolRegistry -具有元数据提取功能的缓存层
  • ClientToolMetadataExtension -方便的扩展

mcp_llm_defer_loading

增强 mcp_llm 带有延迟工具加载编排的包。

  • ValidationResult -工具调用验证结果
  • LlmToolMetadata -LLM特定的轻量级元数据
  • DeferredToolManager -编排层
  • useDeferredLoading 参数在 LlmClient

建筑

+------------------+     +------------------+
|    mcp_client    |     |     mcp_llm      |
+------------------+     +------------------+
| ToolMetadata     |     | LlmToolMetadata  |
| ToolRegistry     |     | ValidationResult |
|                  |     | DeferredToolMgr  |
+------------------+     +------------------+
   Data Layer            Orchestration Layer

资源工具桥

MCP资源在系统提示中可见,但LLM无法调用。合成工具(mcp_read_resource, mcp_list_resources)弥合这一差距。

final client = LlmClient(
  llmProvider: provider,
  mcpClient: mcpClient,
);

// Resources are automatically available as callable tools
final response = await client.chat('Read the config resource');

多轮刀具调用

使LLM能够进行多次连续的工具调用,直到它有足够的信息来应答。

final client = LlmClient(
  llmProvider: provider,
  mcpClient: mcpClient,
  maxToolRounds: 5,  // Allow up to 5 rounds (default: 1, max: 10)
);

final response = await client.chat('Compare weather in Seoul and Tokyo');
// Round 1: LLM calls get_weather(Seoul)
// Round 2: LLM calls get_weather(Tokyo)
// Round 3: LLM returns comparison

运行测试

# All packages
cd mcp_llm_resource_tools && dart test
cd mcp_client_defer_loading && dart test
cd mcp_llm_defer_loading && dart test

设计原则

  1. 零突破性变化:所有现有API工作不变
  2. 仅限选择加入:默认情况下禁用(useDeferredLoading: false)
  3. 自动配置:只需设置标志,无需手动设置
  4. 短暂重试:重试上下文不会污染聊天历史记录
  5. 分层:mcp_client用于数据,mcp_llm用于编排

许可证

请参阅单个软件包许可证。