内容
# MCP 动态路由
<div align="center">
<img src="assets/banner.jpg" alt="MCP 动态路由 Banner" width="800px" style="border-radius: 8px; margin-bottom: 20px;" />
</div>
<p align="center">
<a href="https://github.com/kavinbm16/Mcp-Dynamic-Router/actions"><img src="https://github.com/kavinbm16/Mcp-Dynamic-Router/actions/workflows/ci.yml/badge.svg" alt="持续集成状态"></a>
<a href="https://goreportcard.com/report/github.com/kavinbm16/Mcp-Dynamic-Router"><img src="https://goreportcard.com/badge/github.com/kavinbm16/Mcp-Dynamic-Router" alt="Go 报告卡"></a>
<a href="https://pkg.go.dev/github.com/kavinbm16/mcp-dynamic-router"><img src="https://pkg.go.dev/badge/github.com/kavinbm16/mcp-dynamic-router.svg" alt="Go 参考"></a>
<a href="LICENSE"><img src="https://img.shields.io/github/license/kavinbm16/Mcp-Dynamic-Router.svg" alt="许可证"></a>
</p>
<h3 align="center">为您的语音管道提供数千种工具。让模型只能看到正确的少数工具。</h3>
---
## ❓ 为什么使用 MCP 动态路由?
如果您在 `claude_config.json` 中硬编码了 10+ 个下游 MCP 服务器:
* **巨大的上下文窗口开销:** 您强制 LLM 处理所有 100+ 种工具的模式和参数定义,从而增加了延迟和 token 成本。
* **准确性下降:** 注册过多的工具会引入语义混淆,导致 LLM 产生幻觉参数或选择错误的工具。
* **静态生命周期:** 添加或删除工具需要重启 LLM 会话。
**MCP 动态路由** 作为一个智能中间件层:
1. **集中式生命周期:** 并发连接和编排多个 MCP 服务器(SSE/HTTP),动态热加载工具模式。
2. **亚毫秒级延迟(快速通道):** 精确的词汇匹配绕过语义向量嵌入和 LLM 重新排序调用,返回时间小于 `<1ms`。
3. **流式 RAG 预取:** 在用户仍在讲话时评估部分语音转录,以预热连接并安全地预取只读工具。
4. **安全性和自定义范围:** 在每个请求的基础上限制工具暴露,并在查询置信度较低时安全地拒绝执行。
```mermaid
graph TD
User([用户提示/语音]) -->|1. 音频/文本| Client[客户端代理/应用程序]
subgraph 网关 ["MCP 动态路由网关 (routerd)"]
Client -->|2. 路由/流式传输| API[HTTP 端点:/v1/route, /v1/stream]
API -->|3. 选择候选工具| Routing[两阶段路由引擎]
Client -->|4. 执行工具| API
API -->|5. 验证模式| Validator{JSON 模式验证器}
API -->|6. 调度调用| Downstream[SSE/HTTP MCP 客户端]
end
subgraph 服务器 ["下游服务器"]
Downstream -->|7. JSON-RPC| S1[天气服务器]
Downstream -->|7. JSON-RPC| S2[健康服务器]
end
```
---
## ⚡ 主要功能
* **🔌 动态服务器编排** — 并发连接多个 MCP 服务器(HTTP/SSE),处理工具模式更新时的动态热加载。
* **📈 流式 RAG 引擎** — 在用户仍在讲话时启动路由部分转录,以预热下游连接并安全地预取只读工具。
* **🎯 混合评分和重新排序** — 结合 BM25 词汇评分、语义向量嵌入和基于 LLM 的重新排序,以实现精确、低延迟的选择。
* **🛡️ 安全拒绝策略** — 当输入不明确或置信度低于阈值时拒绝路由,以防止错误突变。
* **🚀 多语言兼容性** — 直接嵌入到您的 Go 代码库中,或作为轻量级本地 HTTP 边车伴侣部署到 Python、TypeScript、LiveKit 或 Pipecat 代理。
```text
"您能查看 Bengaluru 的天气吗——"
│
├── 部分转录 → 领域检索 → 工具候选列表
│ └── 预热安全上下文
│
"...明天早上?" ─┴── 最终转录 → 确认路由 → 绑定 → 执行
```
路由是完全 **提供者中立** 的;它与任何 STT、LLM、TTS、实时语音 API 或代理框架无缝集成。
> **状态:** 积极开发中。动态注册发现、自动工具审计、混合检索、流式 RAG、模式验证和 HTTP 边车已完全实现并测试。
## 🚀 30 秒快速入门
在本地使用零配置尝试动态路由。我们提供一个模拟服务器命令,托管两个虚拟 MCP 服务(天气和计算器),并为您自动生成 `mcp-mock.toml`。
### 1. 启动模拟 MCP 服务器
打开一个终端并运行:
```bash
go run ./cmd/mock-servers
```
*(这启动了一个模拟天气服务,监听 `:8091`,和一个模拟计算器服务,监听 `:8092`,并写入一个本地的 `mcp-mock.toml` 文件。)*
### 2. 启动动态路由守护进程
打开第二个终端并运行:
```bash
go run ./cmd/routerd -mcp mcp-mock.toml
```
*(这启动了动态网关边车,监听 `:8090`,并连接到两个下游模拟服务器。)*
### 3. 验证路由
打开第三个终端并使用简单的 HTTP 请求测试路由:
```bash
curl -s -X POST http://localhost:8090/v1/route \
-H "Content-Type: application/json" \
-d '{"utterance": "What is the weather in New York?"}'
```
您将收到一个 JSON 响应,显示所选的天气服务,完全绕过计算器服务!
---
### 2A. 集成到 Go 中
```go
package main
import (
"context"
"fmt"
dynamicrouter "github.com/kavinbm16/mcp-dynamic-router"
"github.com/kavinbm16/mcp-dynamic-router/router"
)
func main() {
ctx := context.Background()
app := dynamicrouter.NewBuilder().WithMCPConfigPath("mcp.toml").Build()
defer app.Close()
report, err := app.Start(ctx)
if err != nil { panic(err) }
fmt.Println("connected:", report.Connected)
result, err := app.Route(ctx, router.RouteRequest{
Utterance: "Will I need an umbrella in Bengaluru tomorrow?",
Context: "User timezone: Asia/Kolkata",
Final: true,
})
if err != nil { panic(err) }
fmt.Println(result.Decision, result.Candidates[0].Tool.ID)
}
```
### 2B. 或在任意管道旁运行边车
```bash
go run ./cmd/routerd -mcp mcp.toml
```
路由最终的语音转录:
```bash
curl -s http://127.0.0.1:8090/v1/route \
-H 'content-type: application/json' \
-d '{
"utterance": "Will I need an umbrella in Bengaluru tomorrow?",
"context": "User timezone: Asia/Kolkata",
"final": true
}'
```
然后执行所选工具(边车代理调用下游 MCP 服务器并自动验证参数):
```bash
curl -s http://127.0.0.1:8090/v1/execute \
-H 'content-type: application/json' \
-d '{
"tool_id": "weather-service.get_forecast",
"arguments": {
"location": "Bengaluru",
"units": "metric"
}
}'
```
这是完整的集成边界:JSON 输入,路由决策和工具执行输出。客户端不需要任何 MCP 特定的连接代码。
## 流式 RAG:在用户停止讲话之前路由
普通的工具路由等待回合结束。流式 RAG 在用户仍在讲话时利用这段空闲时间检索可能的领域和工具。
包含的流式 RAG 会话执行四个精确的操作:
1. 忽略太短或 ASR 置信度较弱的部分转录。
2. 当更新到达时取消路由旧的部分转录。
3. 仅在同一工具连续更新后标记路由稳定。
4. 仅允许预取标记为 `readOnly` 的工具;最终转录触发提交。
它从不将部分转录视为执行副作用的许可。
### 从任意语言通过 HTTP
发送部分 ASR 更新:
```bash
curl -s http://127.0.0.1:8090/v1/stream \
-H 'content-type: application/json' \
-d '{
"session_id": "call-42",
"transcript": "check the weather in Bengaluru",
"confidence": 0.91,
"final": false
}'
```
然后使用相同的会话 ID 提交最终转录:
```bash
curl -s http://127.0.0.1:8090/v1/stream \
-H 'content-type: application/json' \
-d '{
"session_id": "call-42",
"transcript": "check the weather in Bengaluru tomorrow morning",
"confidence": 0.97,
"final": true
}'
```
每个响应包含 `triggered`、`stable`、`stability_count`、路由决策、候选工具、置信度、边距和阶段延迟。最终请求自动关闭其服务器端流式 RAG 会话;废弃的会话在两分钟后过期。
### 直接在 Go 中
```go
session := app.NewStreamBuilder().
OnPrediction(func(p streamrag.Prediction) {
log.Printf("partial route stable=%v decision=%s", p.Stable, p.Result.Decision)
}).
OnPrefetch(func(ctx context.Context, tool router.Tool) error {
// 预热缓存或下游连接。永远不要在这里执行突变。
return warm(tool)
}).
OnCommit(func(p streamrag.Prediction) {
// 转录是最终的。继续参数绑定和策略。
commit(p.Result)
}).
Build()
defer session.Close()
session.Submit(ctx, streamrag.Event{
Transcript: partialTranscript,
Confidence: asrConfidence,
Final: false,
})
```
`Submit` 是异步的,立即返回。`Update` 为请求/响应传输提供相同的状态机。
## 它在哪里适用
| 管道 | 集成点 |
|---|---|
| 串联 STT → LLM → TTS | 将每个有用的 STT 部分发送到 `/v1/stream`;使用 `final:true` 发送结束回合的转录。 |
| 原生语音到语音 API | 将转录事件镜像到流式 RAG;将最终选定的模式返回给实时模型。 |
| 文本代理 | 对每个最终用户消息调用 `/v1/route`。 |
| Go 代理 | 嵌入根 `dynamicrouter.App`。 |
| Python 或 TypeScript 代理 | 将 `routerd` 作为本地边车运行,并使用普通的 HTTP JSON。 |
| 多代理系统 | 运行一个共享的路由器服务或一个注册表隔离的实例,每个信任边界一个。 |
管道拥有音频和对话 UX。路由器拥有发现、缩小范围、排名、不确定性和 MCP 连接。
## 准确性始于工具描述
路由器无法推断工具未声明的限制。对 856 个 MCP 工具的 2026 年分析报告称,**97.1% 包含至少一个描述缺陷**。参见 [MCP 工具描述质量研究](https://arxiv.org/abs/2602.14878)。
在普通的 MCP `description` 字段中使用此格式:
```text
领域:日历
用途: 在用户的日历中创建一个新事件。
在以下情况下调用此工具:当用户明确要求安排、
预订或添加日历事件。
参数:
- title(字符串,必填):简短的事件标题。口语示例:“dentist appointment”。
- start_time(字符串,必填):用户的时区中解析的 ISO-8601 时间。
口语示例:“tomorrow at three”。
- timezone(字符串,选填):IANA 时区,如“Asia/Kolkata”。
限制:
- 不搜索、更新或删除现有事件。
- 仅当用户明确要求邀请外部与会者时,才不允许调用。
- 需要在邀请外部与会者之前确认。
示例:
用户:“明天中午与 Mira 安排午餐。”
参数:{"title":"Lunch with Mira","start_time":"2026-06-30T12:00:00+05:30","timezone":"Asia/Kolkata"}
```
这些字段的重要性:
| 字段 | 为路由器提供的信息 |
|---|---|
| `Domain` | 一个小的第一阶段搜索空间。 |
| `Purpose` | 积极的语义身份。 |
| `Invoke when` | 自然的语音模式和意图边界。 |
| `Parameters` | 语音到模式的接地。 |
| `Limitations` | 关于混淆邻居的负面证据。 |
| `Example` | 从语音到有效参数的现实桥梁。 |
`Domain` 是路由器约定而非 MCP 要求。直接设置 `Tool.Domain`,在描述中包含 `Domain:`,或让路由器回落到 MCP 服务器名称。
JSON 模式应重复每个机器强制执行事实:
```json
{
"type": "object",
"properties": {
"title": {
"type": "string",
"description": "从用户的言语中推断出的短事件标题"
},
"timezone": {
"type": "string",
"description": "IANA 时区",
"examples": ["Asia/Kolkata"]
}
},
"required": ["title"],
"additionalProperties": false
}
```
在本地或 CI 中审核描述:
```bash
go run ./cmd/router-audit -tools testdata/tools.json -minimum 90
```
当描述未能通过策略时,命令退出状态为非零。
## 路由工作原理
```mermaid
flowchart LR
A["语音转录 + 会话上下文"] --> B["阶段 1:领域路由器"]
R["动态 MCP 注册表"] --> C["工具卡编译器"]
C --> B
B -->|"20 个工具最多"| D["阶段 2:工具选择器"]
D --> E["置信度 + 边距策略"]
E --> F["已选择"]
E --> G["澄清"]
E --> H["无工具"]
F --> I["模式验证"]
I --> J["MCP 执行"]
```
### 阶段 1:领域路由器
注册表被分组为显式领域文档。BM25 和可选的嵌入检索选择相关的领域桶,然后将活动池限制在 20 个工具内。大型领域在截断前会进行内部排名;工具顺序永远不会决定候选列表。
### 阶段 2:工具选择器
为您的管道选择成本/准确性点:
- **词汇:** 无依赖的 BM25。
- **混合:** BM25 和嵌入相似性融合在一起。
- **重新排序:** 混合检索加上对候选列表的小型约束输出 LLM。
#### 评分融合公式
使用混合路由时,词汇和语义分数被归一化并使用配置的权重融合:
1. **归一化分数:** 对于词汇和语义运行,各个分数均通过该集合中的最大分数归一化:
$$S_{norm} = \frac{S}{S_{max}}$$
2. **权重融合:** 归一化权重计算如下:
$$W_{lex\_norm} = \frac{W_{lex}}{W_{lex} + W_{sem}}, \quad W_{sem\_norm} = \frac{W_{sem}}{W_{lex} + W_{sem}}$$
$$S_{fused} = W_{lex\_norm} \cdot S_{lex\_norm} + W_{sem\_norm} \cdot S_{sem\_norm}$$
3. **重新排序插值:** 如果启用了第二阶段重新排序,则最终分数会插值融合分数和重新排序分数($S_{rerank} \in [0, 1]$):
$$S_{final} = (1 - W_{reranker}) \cdot S_{fused} + W_{reranker} \cdot S_{rerank}$$
### 放弃
路由器返回:
- `selected` 当置信度和 top-1 边距都通过时;
- `clarify` 当可能的工具太接近时;
- `no_tool` 当没有足够强的候选工具时。
错误的动作不是延迟优化。置信度阈值必须在您的保留数据上进行校准。
#### 校准决策策略
该策略使用您的配置中的两个超参数来控制路由行为:
| 参数 | 类型 | 默认值 | 调整策略 |
|---|---|---|---|
| `MinConfidence` | float | `0.42` | **提高** 以减少假阳性路由(例如,将随机聊天路由到工具)。 **降低** 如果有效意图被分类为 `no_tool`。 |
| `MinMargin` | float | `0.06` | **提高** 以强制严格消歧义(如果工具接近,则产生 `clarify`)。 **降低** 如果相似工具可互换执行。 |
## 可选的本地智能
在边车中启用 Ollama 嵌入和第二阶段选择器:
```bash
go run ./cmd/routerd \
-mcp mcp.toml \
-ollama http://localhost:11434 \
-embedding-model nomic-embed-text \
-selector-model qwen3:4b
```
或在 Go 中配置它们:
```go
app := dynamicrouter.NewBuilder().
WithMCPConfigPath("mcp.toml").
WithEmbedder(&embedding.Ollama{
BaseURL: "http://localhost:11434",
Model: "nomic-embed-text",
}).
WithReranker(&selector.Ollama{
BaseURL: "http://localhost:11434",
Model: "qwen3:4b",
}).
Build()
```
这两个接口都是可替换的。实现 `router.Embedder` 或 `router.Reranker` 以使用另一个本地模型、托管 API 或专用分类器。
## 动态 MCP 行为
- 服务器从 `mcp.toml` 并发连接。
- 一个失败的服务器不会禁用健康的服务器。
- 连接使用可重用的 Streamable HTTP 会话。
- `notifications/tools/list_changed` 原子替换该服务器的工具并重建索引。
- 进行中的请求继续针对其不变的快照。
- 工具参数可以使用 `router.ValidateArguments` 在执行前进行检查。
### 诱导
- `enabled=false`:不宣传诱导处理程序。
- `enabled=true, auto_accept=false`:除非应用程序提供 `mcpclient.WithElicitationHandler`,否则请求被拒绝。
- `auto_accept=true`:自动接受请求。避免对重要工具使用此功能。
- `timeout`:应用程序处理程序的截止日期(秒)。
语音应用程序应将诱导映射到其自己的用户确认状态机。沉默不是同意。
## 衡量
包含的评估器读取工具注册表和标记的 JSONL:
```json
{"utterance":"我需要带伞去 Bengaluru 吗?","expected_tool":"weather.get_forecast"}
{"utterance":"给我讲个睡前故事","expected_tool":""}
```
运行词汇基线:
```bash
go run ./cmd/router-eval -tools testdata/tools.json -cases testdata/cases.jsonl
```
运行混合检索:
```bash
go run ./cmd/router-eval \
-tools testdata/tools.json \
-cases testdata/cases.jsonl \
-ollama http://localhost:11434 \
-model nomic-embed-text
```
报告包括 top-1 准确率、top-5 召回率、no-tool 请求的错误路由以及 P50/P95 路由延迟。
可信的数据集包括混淆的工具对、真实的 ASR 错误、no-tool 请求、口语名称和数字、跨回合上下文以及多个规模的注册表。在开发数据上进行调优;在保留的测试集上发布结果。
## 动态 MCP 路由
请参阅 [README](README.md) 以获取更多信息。
## HTTP API
`routerd` 默认绑定到 `127.0.0.1:8090`。如需在本地机器以外公开,请有意使用 `-listen`;身份验证和 TLS 应在部署边界处进行。
### 端点
#### `GET /healthz`
如果进程正常且健康,则返回 `200 OK`。
**响应**:
```json
{
"status": "ok"
}
```
#### `POST /v1/route`
路由单个语句,无会话状态。
**请求**:
```json
{
"utterance": "明天我需要带伞去 Bengaluru 吗?",
"context": "用户时区:Asia/Kolkata",
"final": true
}
```
**响应**:
```json
{
"decision": "selected",
"confidence": 0.854,
"margin": 0.352,
"candidates": [
{
"tool": {
"id": "weather-service.get_forecast",
"server": "weather-service",
"name": "get_forecast",
"domain": "weather",
"description": "领域:weather\n用途:获取预报...",
"input_schema": {
"type": "object",
"properties": {
"location": { "type": "string" }
},
"required": ["location"]
}
},
"score": 0.854,
"lexical_score": 0.9,
"semantic_score": 0.8,
"rank": 1
}
],
"reason": "top candidate passed confidence and margin thresholds",
"trace": {
"registry_version": 1,
"domains": ["weather"],
"domain_latency": 1500000,
"select_latency": 2500000,
"total_latency": 4000000,
"used_embeddings": true,
"used_reranker": false
}
}
```
*(注意:`trace` 中的延迟值以纳秒表示。)*
#### `POST /v1/stream`
路由与会话相关的增量用户转录。
**请求**:
```json
{
"session_id": "session-101",
"transcript": "检查 Bengaluru 的天气",
"confidence": 0.91,
"final": false
}
```
**响应**:
```json
{
"triggered": true,
"final": false,
"stable": true,
"stability_count": 2,
"result": {
"decision": "selected",
"confidence": 0.854,
"margin": 0.352,
"candidates": [
{
"tool": {
"id": "weather-service.get_forecast",
"server": "weather-service",
"name": "get_forecast",
"domain": "weather",
"description": "领域:weather\n用途:获取预报...",
"input_schema": {
"type": "object",
"properties": {
"location": { "type": "string" }
},
"required": ["location"]
}
},
"score": 0.854,
"lexical_score": 0.9,
"semantic_score": 0.8,
"rank": 1
}
],
"reason": "top candidate passed confidence and margin thresholds",
"trace": {
"registry_version": 1,
"domains": ["weather"],
"domain_latency": 1500000,
"select_latency": 2500000,
"total_latency": 4000000,
"used_embeddings": true,
"used_reranker": false
}
}
}
```
*(注意:发送带有 `"final": true` 的请求会自动关闭服务器上的会话;未使用的会话在 2 分钟后过期。)*
## 生产部署
将动态路由器 (`routerd`) 作为 sidecar 容器部署(例如,在 Kubernetes、ECS 或 Docker Compose 中)。
### 🐳 容器化
构建基于 Alpine 的最小镜像:
```bash
docker build -t mcp-dynamic-router .
```
运行容器,挂载您的 `mcp.toml` 配置:
```bash
docker run -d -p 8090:8090 \
-v $(pwd)/mcp.toml:/etc/routerd/mcp.toml:ro \
mcp-dynamic-router \
-listen 0.0.0.0:8090 -mcp /etc/routerd/mcp.toml
```
或通过 [docker-compose.yml](file:///Users/kavin/Projects/MCP-Dynamic-router/docker-compose.yml) 运行:
```yaml
services:
routerd:
build: .
ports:
- "8090:8090"
volumes:
- ./mcp.toml:/etc/routerd/mcp.toml:ro
healthcheck:
test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:8090/healthz || exit 1"]
restart: unless-stopped
```
### ⚙️ 最佳实践
* **热加载**:sidecar 会轮询 `-mcp` 文件。修改它会触发下游连接的零停机时间热加载。
* **健康检查**:查询 `GET /healthz` 进行存活和就绪探测。
* **安全**:绑定到 `127.0.0.1`(默认)用于本地 sidecar。如果外部公开,请使用 API 网关或反向代理进行 TLS/身份验证。
* **远程 LLM / 嵌入**:传递 `-ollama http://ollama:11434` 或实现自定义 Go `Embedder`/`Reranker` 适配器,在生产中运行云模型(OpenAI、Gemini、Cohere)。
---
## 集成蓝图和示例
对于实时语音、流式 STT/ASR 和嵌入式应用程序管道,您可以在 `/examples` 目录下找到完整的、可运行的实现蓝图:
* **Go 应用程序嵌入:** [main.go](examples/go_embed/main.go) — 演示如何直接在 Go 中导入 `dynamicrouter` 库、重新加载配置并在不使用 sidecar 的情况下运行无状态 `Route` 或有状态 `streamrag.Session` 调用。
* **Go 自定义 HTTP 网关:** [main.go](examples/go_http_server/main.go) — 展示如何构建一个自定义的 Go HTTP JSON API 服务器,封装动态路由器库(mini-`routerd`)。
* **Go 自定义嵌入器和重新排序器:** [main.go](examples/go_custom_llm/main.go) — 编写和注入自定义 `router.Embedder` 和 `router.Reranker` 接口的实现(例如,接入 HuggingFace 或 OpenAI)的详细蓝图。
* **Pipecat(Python):** [pipecat_router.py](examples/pipecat/pipecat_router.py) — 演示如何将语音转录更新管道到 `routerd` 以处理实时预取和提交的工具执行。
* **LiveKit 代理(Python):** [livekit_agent.py](examples/livekit/livekit_agent.py) — 接入用户语音转录和提交事件,以流式传输部分并执行最终工具决策。
* **OpenAI 实时 API(Python):** [openai_realtime_session.py](examples/openai_realtime/openai_realtime_session.py) — 与 OpenAI 实时 WebSockets 会话交互,拦截 `invoke_tool` 意图并通过 sidecar 执行它们。
* **Gemini 多模态实时 API(Python):** [gemini_live.py](examples/gemini/gemini_live.py) — 通过 WebSockets 使用 `google-genai` SDK 与 Gemini 多模态实时 API 交互,将用户意图映射到动态工具执行。
* **Gemini SDK(Go):** [main.go](examples/gemini_go/main.go) — 演示如何使用官方 `google.golang.org/genai` SDK 在 Go 中集成标准 Gemini 函数调用,通过嵌入式注册表路由调用。
## 仓库地图
| 路径 | 责任 |
|---|---|
| `dynamicrouter.go` | 单构造函数 Go 外观。 |
| `router/` | 注册表、审计、领域路由、选择、放弃、模式检查。 |
| `streamrag/` | 可取消的部分路由、稳定性、安全预取、最终提交。 |
| `mcpclient/` | `mcp.toml`、官方 MCP SDK、热发现、执行。 |
| `embedding/` | 可选的 Ollama 批量嵌入。 |
| `selector/` | 可选的 Ollama 约束输出重新排序器。 |
| `cmd/routerd/` | 提供者中立的 HTTP sidecar。 |
| `cmd/router-audit/` | 描述质量 CI 门控。 |
| `cmd/router-eval/` | 准确性、拒绝和延迟评估器。 |
## 🎯 核心原则
* **质量描述:** 工具描述被视为可执行代码,而不是装饰。
* **广泛检索,狭窄推理:** 在阶段 1 检索中投放广泛的网络,然后积极修剪。
* **流安全:** 部分转录仅预取安全只读工具;它们从不授权修改。
* **安全放弃:** 我们更倾向于返回 `clarify` 或 `no_tool` 而不是执行自信的错误操作。
* **策略分离:** 路由决策和工具执行保持独立的边界。
* **可检查和可基准:** 每个路由路径和延迟预算都必须完全可审计。
## 🚀 路线图
* [ ] 公共语音路由基准和混淆集生成器。
* [ ] 保有置信度校准。
* [ ] 模式约束参数绑定器和自我修复循环。
* [ ] 多意图依赖 DAG 并行执行。
* [ ] LiveKit、Pipecat、OpenAI 实时和 Gemini Live 的生产集成。
* [ ] OpenTelemetry 和 Prometheus 仪表盘。
* [ ] Voxa 集成,感知延迟测量。
## 🤝 贡献和良好第一问题
我们欢迎贡献!无论您是添加中间件遥测、编写新的语音代理包装器(例如 LiveKit 或 Pipecat),还是实现新的自定义嵌入缓存,请查看我们的 [CONTRIBUTING.md](CONTRIBUTING.md) 指南以了解如何开始。
高优先级机会包括:
* **Prometheus 和 OpenTelemetry 集成**(添加延迟和决策指标)。
* **基于 SQLite 的嵌入缓存**(在重启之间持久化向量)。
* **自定义 LLM 适配器**(Hugging Face、Cohere、OpenAI)。
* **LiveKit / Pipecat 适配器中间件**(Python)。
运行验证命令:
```bash
go test -race ./...
go vet ./...
go run ./cmd/router-audit
go run ./cmd/router-eval
```
在更改任何排名策略时,请包含基准测试影响。
## License
MIT. 见 [LICENSE](LICENSE)。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器