介绍
# LLM Router
一个智能代理,根据复杂度对传入请求进行分类,并将其路由到合适的 LLM 模型。对简单任务使用更便宜/更快的模型,并将昂贵的模型留给复杂任务。
**与 [OpenClaw](https://github.com/openclaw/openclaw) 配合使用**,通过将简单请求路由到更小的模型来减少 token 使用量和 API 成本。
**状态:** 已在 Anthropic、OpenAI、Google Gemini、Kimi/Moonshot 和 Ollama 上测试。
## 快速开始
### 前置条件
1. **Python 3.10+** 并安装了 pip 2. **Ollama**(可选 - 仅在使用本地分类时需要) 3. **Anthropic API 密钥** 或 Claude Code OAuth 令牌(或其他提供商密钥)
### 安装
```bash # Clone if not already present git clone https://github.com/alexrudloff/llmrouter.git cd llmrouter
# Create virtual environment (required on modern Python) python3 -m venv venv source venv/bin/activate
# Install dependencies pip install -r requirements.txt
# Pull classifier model (if using local classification) ollama pull qwen2.5:3b
# Copy and customize config cp config.yaml.example config.yaml # Edit config.yaml with your API key and model preferences ```
### 验证安装
```bash # Start the server source venv/bin/activate python server.py
# In another terminal, test health endpoint curl http://localhost:4001/health # Should return: {"status": "ok", ...} ```
### 启动服务器
```bash python server.py ```
选项: - `--port PORT` - 监听端口(默认:4001) - `--host HOST` - 绑定主机(默认:127.0.0.1) - `--config PATH` - 配置文件路径(默认:config.yaml) - `--log` - 启用详细日志 - `--openclaw` - 启用 OpenClaw 兼容性(在系统提示词中重写模型名称)
## 配置
编辑 `config.yaml` 进行自定义:
### 模型路由
```yaml # Anthropic routing models: super_easy: "anthropic:claude-haiku-4-5-20251001" easy: "anthropic:claude-haiku-4-5-20251001" medium: "anthropic:claude-sonnet-4-20250514" hard: "anthropic:claude-opus-4-20250514" super_hard: "anthropic:claude-opus-4-20250514"
# OpenAI routing models: super_easy: "openai:gpt-4o-mini" easy: "openai:gpt-4o-mini" medium: "openai:gpt-4o" hard: "openai:o3-mini" super_hard: "openai:o3"
# Google Gemini routing models: super_easy: "google:gemini-2.0-flash" easy: "google:gemini-2.0-flash" medium: "google:gemini-2.0-flash" hard: "google:gemini-2.0-flash" super_hard: "google:gemini-2.0-flash" ```
**注意:** 推理模型会被自动检测,并使用正确的 API 参数。
### 分类器
有三种选项可用于分类请求的复杂度:
**本地(默认)** - 免费,需要 Ollama: ```yaml classifier: provider: "local" model: "qwen2.5:3b" ```
**Anthropic** - 使用 Haiku,快速且便宜: ```yaml classifier: provider: "anthropic" model: "claude-haiku-4-5-20251001" ```
**OpenAI** - 使用 GPT-4o-mini: ```yaml classifier: provider: "openai" model: "gpt-4o-mini" ```
**Google** - 使用 Gemini: ```yaml classifier: provider: "google" model: "gemini-2.0-flash" ```
**Kimi** - 使用 Moonshot: ```yaml classifier: provider: "kimi" model: "moonshot-v1-8k" ```
如果您的机器无法运行本地模型,请使用远程分类(anthropic/openai/google/kimi)。
### 支持的提供商
- `anthropic:claude-*` - Anthropic Claude 模型(已测试) - `openai:gpt-*`、`openai:o1-*`、`openai:o3-*` - OpenAI 模型(已测试) - `google:gemini-*` - Google Gemini 模型(已测试) - `kimi:kimi-k2.5`、`kimi:moonshot-*` - Kimi/Moonshot 模型(已测试) - `local:model-name` - 本地 Ollama 模型(已测试)
## 复杂度级别
| 级别 | 使用场景 | 默认模型 | |-------|----------|---------------| | super_easy | 问候、确认 | Haiku | | easy | 简单问答、提醒 | Haiku | | medium | 编码、邮件、研究 | Sonnet | | hard | 复杂推理、调试 | Opus | | super_hard | 系统架构、证明 | Opus |
## 自定义分类
编辑 `ROUTES.md` 以调整消息分类方式。分类器读取该文件中的表格来确定复杂度级别。
## API 使用
路由器公开了一个兼容 OpenAI 的 API:
```bash curl http://localhost:4001/v1/chat/completions \ -H "Authorization: Bearer $ANTHROPIC_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "llm-router", "messages": [{"role": "user", "content": "Hello!"}] }' ```
## 测试分类
```bash python classifier.py "Write a Python sort function" # Output: medium
python classifier.py --test # Runs test suite ```
## 作为 macOS 服务运行
创建 `~/Library/LaunchAgents/com.llmrouter.plist`:
```xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.llmrouter</string> <key>ProgramArguments</key> <array> <string>/path/to/llmrouter/venv/bin/python</string> <string>/path/to/llmrouter/server.py</string> <string>--openclaw</string> </array> <key>RunAtLoad</key> <true/> <key>KeepAlive</key> <true/> <key>WorkingDirectory</key> <string>/path/to/llmrouter</string> <key>StandardOutPath</key> <string>/path/to/llmrouter/logs/stdout.log</string> <key>StandardErrorPath</key> <string>/path/to/llmrouter/logs/stderr.log</string> </dict> </plist> ```
**重要:** 将 `/path/to/llmrouter` 替换为您的实际安装路径。必须使用 venv 中的 python,而不是系统 python。
```bash # Create logs directory mkdir -p ~/path/to/llmrouter/logs
# Load the service launchctl load ~/Library/LaunchAgents/com.llmrouter.plist
# Verify it's running curl http://localhost:4001/health
# To stop/restart launchctl unload ~/Library/LaunchAgents/com.llmrouter.plist launchctl load ~/Library/LaunchAgents/com.llmrouter.plist ```
## OpenClaw 配置
在 `~/.openclaw/openclaw.json` 中将路由器添加为提供商:
```json { "models": { "providers": { "localrouter": { "baseUrl": "http://localhost:4001/v1", "apiKey": "via-router", "api": "openai-completions", "models": [ { "id": "llm-router", "name": "LLM Router (Auto-routes by complexity)", "reasoning": false, "input": ["text", "image"], "cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }, "contextWindow": 200000, "maxTokens": 8192 } ] } } } } ```
**注意:** 成本设置为 0,因为实际成本取决于路由器选择的模型。路由器会记录哪个模型处理了每个请求。
### 设为默认模型(可选)
要在所有代理中默认使用路由器,请添加:
```json { "agents": { "defaults": { "model": { "primary": "localrouter/llm-router" } } } } ```
### 使用 OAuth 令牌
如果您的 `config.yaml` 使用了来自 OpenClaw 的 `~/.openclaw/auth-profiles.json` 的 Anthropic OAuth 令牌,路由器会自动处理 Claude Code 身份标头。
### OpenClaw 兼容模式(必需)
**如果与 OpenClaw 一起使用,您必须使用 `--openclaw` 启动服务器:**
```bash python server.py --openclaw ```
此标志启用 OpenClaw 所需的兼容性功能: - 重写响应中的模型名称,以便 OpenClaw 显示实际使用的模型 - 处理工具名称和 ID 重新映射,以实现正确的工具调用路由
如果没有此标志,在使用路由器与 OpenClaw 交互时可能会遇到错误。
## 常见任务
- **检查服务器状态**:`curl http://localhost:4001/health` - **查看当前配置**:`cat config.yaml` - **测试分类**:`python classifier.py "your message"` - **运行分类测试**:`python classifier.py --test` - **重启服务器**:停止并再次运行 `python server.py` - **查看日志**(如果作为服务运行):`tail -f logs/stdout.log`
## 故障排除
### "externally-managed-environment" 错误 Python 3.11+ 需要虚拟环境。创建一个: ```bash python3 -m venv venv source venv/bin/activate pip install -r requirements.txt ```
### 4001 端口出现 "Connection refused" 服务器未运行。启动它: ```bash source venv/bin/activate && python server.py ```
### 分类返回错误的复杂度 编辑 `ROUTES.md` 以调整分类规则。分类器读取此文件来确定复杂度级别。
### Ollama 错误 / "model not found" 确保 Ollama 正在运行并且模型已拉取: ```bash ollama serve # Start Ollama if not running ollama pull qwen2.5:3b ```
### OAuth 令牌不起作用 确保您在 `config.yaml` 中的令牌以 `sk-ant-oat` 开头。路由器会自动检测 OAuth 令牌并添加所需的身份标头。
### LaunchAgent 未启动 检查日志并确保路径是绝对路径: ```bash cat ~/Library/LaunchAgents/com.llmrouter.plist # Verify paths cat /path/to/llmrouter/logs/stderr.log # Check for errors ```