npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@wangjy_john/domainrouter

v0.2.0

Published

Domain-Aware Smart LLM Router — 12-domain classification with per-domain model rankings, Chinese LLM support, user-owned API key routing

Readme

DomainRouter

领域感知智能大模型路由器 — 12 领域分类 × 14 维难度评估 × 加权模型打分,将每个问题自动路由到最优模型。

npm version License: MIT Node.js >= 20


核心原理

DomainRouter 解决的核心问题是:你手里有多个模型的 API Key,每个问题应该发给哪个模型?

简单做法是"全发给最强的模型"(浪费钱)或"全发给最便宜的模型"(复杂问题得不到好回答)。DomainRouter 的做法是先理解问题,再选择模型——分五步:

第一步:领域分类 — 这是什么类型的问题?

系统用分类器判断问题属于 12 个领域中的哪一个(或多个),输出一个 12 维相似度向量

| 领域 | 说明 | |------|------| | math_reasoning | 数学证明、定理推导、方程求解 | | code_generation | 编写代码、实现功能、创建应用 | | code_debugging | 修复 bug、排查错误、调试代码 | | data_analysis | 数据分析、统计、SQL、机器学习 | | creative_writing | 故事、诗歌、文案、内容创作 | | translation | 语言翻译、本地化 | | factual_qa | 事实问答、定义查询、常识 | | summarization | 文本摘要、要点提炼 | | system_design | 架构设计、系统设计、技术选型 | | instruction_following | 格式遵循、模板输出、严格指令 | | multimodal | 图像理解、OCR、视觉识别 | | agentic_task | 多步骤自主操作、工具调用 |

四种可选的分类器:

| 分类器 | 延迟 | 准确率 | 中文 | 原理 | 依赖 | |--------|------|--------|------|------|------| | ngram ⭐ | <1ms | ~82% | 好 | 字符级 TF-IDF n-gram,中英双语混合特征空间余弦相似度 | 零依赖 | | keyword | 0ms | ~75% | 好 | 中英双语关键词匹配,分段命中数映射 | 零依赖 | | embedding-minilm | ~5ms | ~85% | 一般 | WASM 本地运行 all-MiniLM-L6-v2,余弦相似度 | 需安装 @xenova/transformers | | embedding-bge | ~5ms | ~88% | 很好 | WASM 本地运行 bge-small-zh-v1.5,中文语义更好 | 需安装 @xenova/transformers |

ngram 分类器原理: 将每个领域的 250+ 中英双语关键词拼接为"原型文档",提取字符 bigram + trigram + 单词特征构建 TF-IDF 加权向量(模块加载时预计算)。用户输入同样提取 n-gram 后计算与 12 个领域向量的余弦相似度。IDF 自动降低跨领域常见词权重,比纯关键词匹配更细粒度。

第二步:难度评估 — 这个问题有多难?

系统用 14 个维度 对问题加权评分,输出 0~1 的难度分数和四个等级:

| 难度等级 | 分数区间 | 典型场景 | |----------|----------|----------| | SIMPLE | < 0.05 | "1+1 等于几?" | | MEDIUM | 0.05 ~ 0.30 | "写一个排序函数" | | COMPLEX | 0.30 ~ 0.55 | "设计一个分布式缓存系统" | | REASONING | ≥ 0.55 | "证明黎曼猜想" |

14 个评估维度:

| 维度 | 权重 | 说明 | |------|------|------| | reasoningMarkers | 0.20 | 含"证明"/"prove"/"推导"等 → 难度⬆ | | codePresence | 0.15 | 含 function/class/import 等 → 难度⬆ | | technicalTerms | 0.10 | 含"分布式"/"kubernetes"等 → 难度⬆ | | multiStepPatterns | 0.10 | 含"第一步…第二步…"/step 1 等 → 难度⬆ | | tokenCount | 0.08 | 输入长度 >500 token → ⬆;<50 token → ⬇ | | constraintCount | 0.06 | 含"不超过"/"至少"/"限制"等 → ⬆ | | imperativeVerbs | 0.05 | 含"构建"/"创建"/"部署"等 → ⬆ | | questionComplexity | 0.05 | 含 ≥3 个问号 → ⬆ | | outputFormat | 0.05 | 要求 JSON/YAML/表格等 → ⬆ | | simpleIndicators | 0.05 | 含"什么是"/"define"等 → ⬇ | | creativeMarkers | 0.03 | 含"故事"/"创意"等 → ↑ | | referenceComplexity | 0.03 | 含"上文"/"之前"等 → ↑ | | domainSpecificity | 0.03 | 含"量子"/"基因组"等 → ↑ | | negationComplexity | 0.02 | 含"不要"/"避免"等 → ↑ |

命中 ≥2 个推理关键词时,难度直接提升至 ≥0.55。

第三步:加权模型打分 — 哪个模型最适合?

针对你配置的每个可用模型,从四个维度独立打分,然后按偏好加权求和:

① 领域匹配度 — 对于每个领域 d:问题相似度 × 模型在该领域的能力评分,取加权平均。模型能力数据来源于公开 benchmark(MMLU、HumanEval、MATH 等)综合评估。

② 难度适配度 — 模型能力等级与问题难度比对:REASONING 问题遇到弱模型 → 严厉惩罚;SIMPLE 问题遇到强模型 → 适度惩罚。

③ 价格效率 — 对数尺度比较所有模型价格,最便宜的得 1.0。

④ 延迟评分 — 线性归一化,最快的得 1.0。

加权公式依赖于你的路由偏好:

| 权重项 | cheapest(省钱) | balanced(均衡) | best_quality(质量优先) | |--------|-------------------|--------------------|--------------------------| | 领域匹配 | 0.30 | 0.45 | 0.50 | | 难度适配 | 0.15 | 0.25 | 0.30 | | 价格效率 | 0.45 | 0.20 | 0.05 | | 延迟 | 0.05 | 0.05 | 0.10 | | 用户偏好 | 0.05 | 0.05 | 0.05 |

totalScore = domainMatch × w₁ + difficultyFit × w₂ + priceEfficiency × w₃ + latency × w₄

所有模型按 totalScore 降序排列。第一名当选,第 2~6 名组成容错链。

第四步:Provider 适配与调用

根据模型的 provider 字段选择 SDK:

| Provider | 适配方式 | |----------|----------| | anthropic | Anthropic SDK 原生调用 | | openai | OpenAI SDK 原生调用 | | google | Gemini SDK 原生调用 | | deepseek | OpenAI 兼容 API(含 R1 推理模型 reasoning_content 处理) | | 其他 10+ 厂商 | 通用 OpenAI 兼容适配器(自动推断 baseUrl) |

所有适配器统一接收 OpenAI 兼容格式的 messages,内部翻译为各厂商原生格式,响应再翻译回 OpenAI 兼容格式。对使用者完全透明。

第五步:自动容错

如果首选模型调用失败,系统自动尝试容错链中的下一个模型,最多尝试 4 个(首选 + 3 个备选)。全部失败才返回错误。


快速开始

1. 安装

npm install -g @wangjy_john/domainrouter

2. 配置模型

domainrouter init

交互式向导会引导你选择分类器、路由偏好,并逐一配置模型的 API Key。

也可以手动创建 domainrouter.config.json

{
  "classifier": "ngram",
  "routingPreference": "balanced",
  "models": {
    "deepseek/deepseek-chat": {
      "apiKey": "你的 DeepSeek API Key"
    },
    "openai/gpt-4o": {
      "apiKey": "你的 OpenAI API Key"
    },
    "anthropic/claude-sonnet-4.6": {
      "apiKey": "你的 Anthropic API Key"
    }
  }
}

运行 domainrouter list-models 查看全部 35 个支持的模型 ID。

3. 启动

# 先测试路由是否正常(不消耗 API 额度)
domainrouter test "写一个快速排序算法" --verbose

# 启动代理服务器
domainrouter start --port 8080

然后将你的工具指向 http://localhost:8080/v1 即可:

# curl
curl http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"messages":[{"role":"user","content":"你好!"}]}'

# Python
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8080/v1", api_key="any")
response = client.chat.completions.create(
    model="auto",
    messages=[{"role": "user", "content": "你好!"}]
)

CLI 命令

| 命令 | 说明 | |------|------| | domainrouter init | 交互式配置向导 | | domainrouter test "prompt" | Dry-run 路由测试(不调用 LLM) | | domainrouter test "prompt" --verbose | 详细模式:领域柱状图 + 14 维难度明细 + Top-10 候选 | | domainrouter test "prompt" --classifier keyword --preference best_quality | 指定分类器和偏好 | | domainrouter start --port 8080 | 启动代理服务器 | | domainrouter list-models | 查看全部 35 个支持的模型 |


配置参考

配置文件格式

domainrouter.config.json

| 字段 | 类型 | 必填 | 默认值 | 说明 | |------|------|------|--------|------| | classifier | string | 否 | "ngram" | ngram / keyword / embedding-minilm / embedding-bge | | routingPreference | string | 否 | "balanced" | cheapest / balanced / best_quality | | port | number | 否 | 0(随机) | 代理服务器端口 | | models | object | | — | 模型 ID → 配置的映射 | | journal.enabled | boolean | 否 | true | 是否记录路由日志 | | journal.maxEntries | number | 否 | 500 | 内存中最多保留条数 | | journal.file | boolean | 否 | false | 设为 true 持久化到磁盘 |

每个模型的配置:

| 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | apiKey | string | | 你的 API Key | | baseUrl | string | 否 | 自定义 API 地址(大部分厂商自动推断) | | enabled | boolean | 否 | 设为 false 临时禁用此模型 |

OpenClaw 插件模式

openclaw.yaml 中配置:

plugins:
  domainrouter:
    enabled: true
  config:
    domainrouter:
      classifier: ngram
      routingPreference: balanced
      models:
        deepseek/deepseek-chat:
          apiKey: sk-xxxxxxxxxxxxxxxx
        openai/gpt-4o:
          apiKey: sk-xxxxxxxxxxxxxxxx

重启 OpenClaw 后可使用斜杠命令:

  • /domain-router — 查看路由状态
  • /my-models — 列出已配置模型及状态

API 端点

启动代理后可用:

| 端点 | 方法 | 说明 | |------|------|------| | /v1/chat/completions | POST | 路由查询并返回 OpenAI 兼容响应 | | /v1/models | GET | 列出你已配置的可用模型 | | /health | GET | 健康检查 | | /dashboard | GET | Web Dashboard | | /test-route | POST | Dry-run 路由测试(不调用 LLM) | | /journal | GET | 查询路由日志(支持 ?limit=&domain=&model=&difficulty=) | | /journal/:id | GET | 查看单条日志详情 | | /journal/stats | GET | 聚合统计 | | /journal/config | GET | Journal 配置 | | /journal | DELETE | 清空日志 | | /config/models | POST | 从 Dashboard 编辑模型配置并写入文件 |

响应头会携带路由信息:

  • X-Routed-Model — 实际调用的模型 ID
  • X-Routing-Reason — 路由决策文本摘要

Dashboard

浏览器打开 http://localhost:<port>/dashboard,提供四个标签页:

| 标签页 | 功能 | |--------|------| | Route Test | 输入 prompt → 查看完整路由决策(领域柱状图、难度详情、Top-10 候选、容错链) | | Journal | 所有路由记录的时间线表格,可按领域/难度筛选,点击查看详情 | | Stats | 聚合统计卡片 + 模型/领域/难度分布柱状图 | | Settings | 编辑模型配置(API Key、Base URL、启用开关),一键保存到配置文件 |

Route Test 页面支持 Ctrl+Enter 快捷键触发,测试结果自动记入 Journal。


Journal 日志

每次路由决策自动记录到内存环形缓冲区(默认 500 条)。开启 journal.file: true 后持久化到 ~/.domainrouter/journal.jsonl

# 通过 API 查询
curl http://localhost:8080/journal?limit=20
curl http://localhost:8080/journal?domain=code_generation
curl http://localhost:8080/journal/stats

# 持久化后直接查看文件
cat ~/.domainrouter/journal.jsonl | jq '.'
tail -f ~/.domainrouter/journal.jsonl

支持的模型

国际模型 (21 个)

| 厂商 | 模型 ID | 特点 | |------|---------|------| | Anthropic | anthropic/claude-opus-4.7 | 最佳:创意写作、指令遵循、智能代理 | | Anthropic | anthropic/claude-sonnet-4.6 | 最佳:代码生成、代码调试 | | Anthropic | anthropic/claude-haiku-4.5 | 轻量快速 | | OpenAI | openai/gpt-5.5 | 综合最强 | | OpenAI | openai/gpt-5.4 | 综合能力强 | | OpenAI | openai/gpt-5.4-mini | 高性价比 | | OpenAI | openai/gpt-5.4-nano | 超低价 | | OpenAI | openai/gpt-5.3-codex | 代码生成最强 | | OpenAI | openai/gpt-4o | 经典多模态 | | OpenAI | openai/gpt-4o-mini | 轻量多模态 | | OpenAI | openai/o3 | 最强数学推理 | | OpenAI | openai/o4-mini | 轻量推理 | | Google | google/gemini-3.1-pro | 百万上下文 | | Google | google/gemini-2.5-pro | 性价比高 | | Google | google/gemini-2.5-flash | 低延迟 | | Google | google/gemini-2.5-flash-lite | 超低价 | | xAI | xai/grok-4-0709 | 事实问答突出 | | xAI | xai/grok-4.1-fast-reasoning | 极低价推理 | | xAI | xai/grok-3 | — | | Meta | meta/llama-4-maverick | 开源低价 | | Mistral | mistral/mistral-large | 翻译出色 |

中国模型 (14 个)

| 厂商 | 模型 ID | 特点 | |------|---------|------| | DeepSeek | deepseek/deepseek-chat | 高性价比通用 | | DeepSeek | deepseek/deepseek-reasoner | 顶级数学推理 | | 阿里 Qwen | qwen/qwen-max | 综合顶级 | | 阿里 Qwen | qwen/qwen-plus | 冲量 | | 阿里 Qwen | qwen/qwen3-coder-480b | 顶级代码生成,免费 | | 阿里 Qwen | qwen/qwen3-next-80b-a3b-thinking | 推理,免费 | | 智谱 Z.AI | zai/glm-5.1 | 新一代综合 | | 智谱 Z.AI | zai/glm-5 | 全能力均衡 | | 月之暗面 | moonshot/kimi-k2.6 | 综合强,含视觉 | | 月之暗面 | moonshot/kimi-k2.5 | 性价比 | | MiniMax | minimax/minimax-m2.7 | 高性价比 | | 字节豆包 | bytedance/doubao-pro | 创意写作突出 | | 百度 | baidu/ernie-4.0 | 翻译出色 | | 零一万物 | 01ai/yi-large | 均衡 |


项目结构

src/
├── index.ts                     # OpenClaw 插件入口(薄层)
├── cli.ts                       # CLI 工具(start / test / list-models / init)
├── server.ts                    # HTTP 服务器工厂(插件与 CLI 共用)
├── types.ts                     # OpenClaw 插件 API 类型
├── router/
│   ├── types.ts                 # Domain、ScoringWeights、RoutingDecision 等核心类型
│   ├── classifier.ts            # IClassifier 接口 + getClassifier() 注册工厂
│   ├── classifier-ngram.ts      # TF-IDF n-gram 分类器(默认,零依赖)
│   ├── classifier-keyword.ts    # 关键词分类器(0ms 延迟)
│   ├── classifier-embed.ts      # 嵌入分类器(MiniLM / BGE,可选依赖)
│   ├── difficulty.ts            # 14 维难度评估器
│   └── scorer.ts                # 加权模型打分器 + route() 全流程
├── models/
│   ├── index.ts                 # 重导出
│   └── capabilities.ts          # 35 模型 × 12 领域能力矩阵
├── providers/
│   ├── types.ts                 # ProviderAdapter 接口
│   ├── index.ts                 # getAdapter(provider) 工厂
│   ├── anthropic.ts             # Anthropic SDK 适配器
│   ├── openai.ts                # OpenAI SDK 适配器
│   ├── google.ts                # Gemini SDK 适配器
│   ├── deepseek.ts              # DeepSeek 适配器(含 R1 推理)
│   └── generic-openai-compat.ts # 通用 OpenAI 兼容适配器(10+ 厂商)
├── journal/
│   ├── types.ts                 # JournalEntry / JournalConfig / JournalStats
│   └── store.ts                 # 环形缓冲 + query + stats + JSONL 持久化
├── dashboard/
│   └── static/
│       ├── index.html           # 页面结构(4 标签页)
│       ├── app.js               # 前端逻辑(含 Settings 配置编辑)
│       └── styles.css           # 全部样式
└── config/
    └── wizard.ts                # 交互式 CLI 配置向导

开发指南

git clone <your-repo-url> && cd DomainRouter
npm install
npm run build          # tsup 编译
npm run typecheck      # TypeScript 检查
npm run dev            # 开发模式(自动重编译)
node dist/cli.js test "你的测试 prompt" --verbose
node dist/cli.js start --port 8080

License

MIT

作者

wangjy_john