基于LiteLLM的Claude Code智能代理:多模型路由与AI工作流优化实践
1. 项目概述如果你和我一样日常重度依赖 Claude Code 进行编程和思考那你一定遇到过这样的困境Claude Code 本身虽然强大但它本质上是一个“单模型”客户端。当你想把超长上下文的任务丢给 Gemini 2M 的窗口或者想让 Web 搜索请求走 Perplexity 的在线模型时就不得不手动切换工具打断流畅的工作流。更别提那些需要“思考”模式的复杂推理任务如果能让它们自动路由到更强大的 Claude Opus 模型而日常对话继续用 Sonnet 或 Haiku岂不是能最大化利用每个模型的优势同时控制成本这就是ccproxy诞生的初衷——它不是一个简单的转发代理而是一个智能的 AI 模型流量调度器让你手中的 Claude Code 客户端瞬间变成一个可以按需调用不同大模型的“超级终端”。简单来说ccproxy在 Claude Code 和你配置的多个大模型 API如 Anthropic Claude 系列、OpenAI GPT、Google Gemini 等之间架起了一座桥梁。它通过一个轻量级的代理服务器基于 LiteLLM拦截 Claude Code 发出的所有请求然后根据你预先设定好的规则比如请求的模型名称、是否启用了“思考”模式、上下文长度、是否调用了特定工具等动态地将请求路由到最合适的后端模型。对于 Claude Code 而言它只是在和“本地的一个 Claude API”对话完全无感知但对于你却实现了模型能力的无缝混合与匹配。我使用它已经有一段时间最大的感受就是“静默的智能提升”——你不再需要关心该用哪个模型ccproxy会根据任务特性自动做出最优选择让你专注于问题本身。2. 核心架构与工作原理拆解要理解ccproxy如何工作我们需要深入到它的架构层面。它不是一个黑盒其设计清晰地分为了配置层、规则引擎层和代理执行层。理解这三层如何协同是后续灵活配置和故障排查的关键。2.1 三层架构解析第一层是配置层由~/.ccproxy/目录下的两个核心 YAML 文件构成。ccproxy.yaml是你的“调度策略中心”在这里你定义各种路由规则Rules和处理钩子Hooks。config.yaml则是 LiteLLM 的“模型部署清单”在这里你声明所有可用的后端模型及其 API 密钥、端点等信息。这两个文件分工明确一个管“怎么分”规则一个管“分给谁”模型。第二层是规则引擎层这是ccproxy的“大脑”。当请求到达时rule_evaluator这个核心钩子会依次检查你定义的规则。这些规则就像一系列的“条件判断语句”。例如MatchModelRule检查请求中的model字段是否匹配claude-3-5-haiku-20241022ThinkingRule检查请求的 JSON 体中是否包含thinking: {enabled: true}这样的结构TokenCountRule会估算请求的令牌数是否超过你设定的阈值如 60k。请求会被打上第一个匹配成功的规则所对应的标签如background,think如果没有规则匹配则标记为default。第三层是代理执行层由model_router钩子和 LiteLLM 代理服务器共同完成。model_router的工作很简单它读取请求被打上的标签然后去config.yaml中寻找同名的“模型别名”model alias并将请求中的原始model字段替换成这个别名。随后请求被交给 LiteLLM 代理服务器LiteLLM 根据这个别名找到对应的真实模型部署并完成向 Anthropic、OpenAI 等供应商 API 的转发。整个过程中OAuth 令牌或 API Key 的传递由forward_oauth或forward_apikey钩子透明处理。2.2 请求生命周期全景让我们跟踪一个典型“思考”请求的完整旅程这能帮你建立起清晰的调试心智模型发起你在 Claude Code 中输入一个复杂问题并暗示需要深度思考。Claude Code 内部逻辑决定启用“思考”模式于是它向配置的 API 基址http://localhost:4000发送一个 HTTP POST 请求请求体中包含了thinking: {enabled: true, budget_tokens: 31999}等字段。拦截与标签请求到达本地 4000 端口的 LiteLLM 代理。LiteLLM 在将请求转发给供应商前先调用ccproxy注册的钩子链。rule_evaluator钩子运行它识别出thinking字段并且该请求没有先匹配其他规则如特定模型名因此给请求打上think标签。路由改写model_router钩子接收到带有think标签的请求。它查阅config.yaml发现有一个别名为think的配置项其litellm_params.model值为claude-opus-4-5-20251101。于是它将请求中的model字段可能是claude-3-5-sonnet-20241022改写为think。代理转发LiteLLM 接收到修改后的请求看到model: think。它在model_list中查找名为think的项发现其litellm_params.model指向claude-opus-4-5-20251101。接着它找到model_name为claude-opus-4-5-20251101的部署配置使用其中定义的api_base和通过钩子传递的认证信息将请求转发给 Anthropic 的 Opus 模型 API。流式响应Anthropic API 返回流式响应。数据流经 LiteLLM 和ccproxy的响应钩子如果有的话原路返回最终呈现给 Claude Code 客户端。对你而言整个过程毫无感知只是感觉“思考”回答的质量特别高。实操心得理解这个流程至关重要。当路由出现问题时你可以清晰地定位是规则没匹配查ccproxy.yaml和请求日志、别名映射错误查config.yaml还是底层 API 调用失败查 LiteLLM 日志和供应商状态。3. 从零开始环境准备与安装详解虽然官方文档给出了安装命令但在实际部署中环境隔离和工具链的选择会直接影响后续使用的稳定性。这里我分享一套经过验证的、清晰可靠的安装流程。3.1 基础环境与工具选型首先我强烈推荐使用uv作为 Python 包管理工具。它不仅安装速度极快更重要的是其“可安装应用”Installable Applications的特性能将ccproxy及其依赖包括litellm完美地封装在一个独立的环境中生成一个全局可用的ccproxy命令。这从根本上避免了“ccproxy和litellm不在同一个 Python 环境”这个最常见的安装错误。如果你还没有uv可以通过以下命令安装# 在 Linux/macOS 上安装 uv curl -LsSf https://astral.sh/uv/install.sh | sh # 安装完成后重启你的终端或执行 source ~/.bashrc (或 ~/.zshrc) # 在 Windows 上 (PowerShell) powershell -c irm https://astral.sh/uv/install.ps1 | iex接下来你需要确保 Claude Code 本身已正确安装并配置了 OAuth 登录。ccproxy依赖于 Claude Code 本地存储的 OAuth 令牌来访问 Anthropic API。通常运行一次claude auth login并完成浏览器认证即可。3.2 分步安装与验证安装过程本身很简单但每一步的验证能确保一切就绪。# 1. 使用 uv 从 PyPI 安装 ccproxy并同时安装 litellm[proxy] uv tool install claude-ccproxy --with litellm[proxy] # 安装完成后验证 ccproxy 命令是否可用 ccproxy --help # 你应该能看到 start, stop, install, run 等子命令的说明 # 2. 验证 litellm 是否与 ccproxy 在同一环境 which litellm # 输出可能类似/Users/yourname/.local/bin/litellm # 这个路径应该和 which ccproxy 的路径在同一个父目录下 # 更彻底的验证用 litellm 所在环境的 Python 导入 ccproxy $(dirname $(which litellm))/python -c import ccproxy; print(ccproxy.__file__) # 应该成功打印出 ccproxy 模块的路径而不是报 ImportError如果上述验证中最后一步报错说明安装的环境隔离有问题。请务必使用uv tool install并确保包含了--with litellm[proxy]参数。这是最稳妥的方式。3.3 初始化配置与首次运行安装好二进制工具后接下来需要生成配置文件。# 生成默认配置文件到 ~/.ccproxy 目录 ccproxy install执行后检查~/.ccproxy目录tree ~/.ccproxy # 预期输出 # /Users/yourname/.ccproxy # ├── ccproxy.yaml # 路由规则和钩子配置 # └── config.yaml # LiteLLM 模型部署配置 # ccproxy.py 文件会在首次启动时自动生成现在你可以启动代理服务器了。建议在首次启动时不要使用--detach后台运行以便观察启动日志。# 前台启动观察日志 ccproxy start如果一切正常你将看到 LiteLLM 服务器启动的日志最后一行通常是INFO: Application startup complete.并监听在http://127.0.0.1:4000。此时打开另一个终端测试 Claude Code 是否能通过代理工作# 方法一使用 ccproxy run 包装命令 ccproxy run claude --version # 应该能正确输出 Claude Code 的版本号 # 方法二设置环境变量后直接运行 export ANTHROPIC_BASE_URLhttp://localhost:4000 claude -p Hello, world! # 应该能收到来自代理的回复如果测试通过你就可以用CtrlC停止前台进程改用后台模式运行# 停止当前进程 (如果在前台) # 按 CtrlC # 以后台守护进程方式启动 ccproxy start --detach # 检查状态 ccproxy status # 应显示 running 状态和 URL注意事项ccproxy install生成的config.yaml是一个示例里面只配置了 Anthropic 的模型并且没有填写有效的api_key。你需要根据下一节的指导修改这个文件添加你自己的 API 密钥并配置其他模型供应商。直接使用示例配置会因认证失败而导致请求错误。4. 核心配置实战打造你的智能路由策略安装只是第一步让ccproxy真正发挥威力的关键在于配置。本节将深入ccproxy.yaml和config.yaml手把手教你如何根据实际需求定制路由规则和模型池。4.1 规则配置详解打开~/.ccproxy/ccproxy.yaml我们重点关注rules部分。每个规则由name、rule规则类和params参数组成。规则按定义顺序评估第一个匹配的规则生效。基础规则配置示例与解析rules: # 规则1匹配特定模型用于后台任务 - name: background rule: ccproxy.rules.MatchModelRule params: - model_name: claude-3-5-haiku-20241022 # 当请求的模型字段为此值时触发 # 规则2匹配“思考”请求 - name: think rule: ccproxy.rules.ThinkingRule # 此规则无参数只要请求体包含 thinking: {enabled: true} 即触发 # 规则3基于令牌数路由 - name: long_context rule: ccproxy.rules.TokenCountRule params: - threshold: 60000 # 估算令牌数超过此阈值时触发 # 注意这是基于字符的粗略估算非精确值。 # 规则4匹配工具使用 - name: web_search rule: ccproxy.rules.MatchToolRule params: - tool_name: WebSearch # 当请求的 tools 列表中包含此工具时触发 # 规则5匹配特定系统提示词自定义规则示例需自行实现 # - name: code_review # rule: my_custom_rules.SystemPromptRule # params: # - contains: Please review the following code配置逻辑与陷阱顺序至关重要如果把TokenCountRule(阈值 60000) 放在ThinkingRule前面那么一个需要“思考”且令牌数超过 6万的请求会被标记为long_context而不是think。你需要根据优先级决定顺序。通常更具体、更特殊的规则如匹配特定工具应放在前面更通用的规则如令牌数放在后面。default标签如果请求不匹配任何规则它会自动获得default标签。因此你必须在config.yaml中配置一个名为default的模型别名作为所有未匹配请求的“兜底”路由。令牌估算的局限性TokenCountRule使用的是基于字符的启发式估算对于混合代码、文本的复杂内容可能不准。它更适合作为一个“防止上下文过长导致主流模型失败”的保险机制而不是精确的成本优化工具。对于精确路由更推荐使用MatchModelRule或MatchToolRule。4.2 模型部署配置实战config.yaml是 LiteLLM 的配置文件。ccproxy利用其中的“模型别名”功能实现路由。一个完整的、支持多供应商的配置如下model_list: # --- 模型别名区ccproxy 路由的目标 --- - model_name: default # 兜底路由 litellm_params: model: claude-3-5-sonnet-20241022 # 指向下面的实际部署 - model_name: think # 思考任务路由 litellm_params: model: claude-opus-4-5-20251101 - model_name: background # 后台/廉价任务路由 litellm_params: model: claude-3-5-haiku-20241022 - model_name: long_context # 长上下文路由 litellm_params: model: gemini-2.0-flash-exp # 使用 Gemini 的长上下文模型 - model_name: web_search # 联网搜索路由 litellm_params: model: perplexity/llama-3.1-sonar-large-128k-online # 使用 Perplexity 在线模型 # --- 实际模型部署区 --- # Anthropic Claude - model_name: claude-3-5-sonnet-20241022 litellm_params: model: anthropic/claude-3-5-sonnet-20241022 api_base: https://api.anthropic.com # api_key 通过 ccproxy 的 forward_oauth 钩子从 Claude Code 凭据自动获取 - model_name: claude-opus-4-5-20251101 litellm_params: model: anthropic/claude-opus-4-5-20251101 api_base: https://api.anthropic.com - model_name: claude-3-5-haiku-20241022 litellm_params: model: anthropic/claude-3-5-haiku-20241022 api_base: https://api.anthropic.com # Google Gemini (需要 API Key) - model_name: gemini-2.0-flash-exp litellm_params: model: gemini/gemini-2.0-flash-exp api_key: ${GEMINI_API_KEY} # 从环境变量读取或直接写密钥不推荐 api_base: https://generativelanguage.googleapis.com/v1beta # Perplexity 在线模型 (需要 API Key) - model_name: perplexity/llama-3.1-sonar-large-128k-online litellm_params: model: perplexity/llama-3.1-sonar-large-128k-online api_key: ${PERPLEXITY_API_KEY} api_base: https://api.perplexity.ai # OpenAI GPT (示例) - model_name: gpt-4o-mini litellm_params: model: openai/gpt-4o-mini api_key: ${OPENAI_API_KEY} api_base: https://api.openai.com/v1 litellm_settings: callbacks: - ccproxy.handler # 关键启用 ccproxy 的钩子系统 drop_params: true # 建议启用防止不支持的参数被传递给供应商 max_budget: 10.0 # 设置预算上限美元防止意外开销 general_settings: master_key: sk-123456 # 可选设置 LiteLLM 代理的管理密钥 database_url: sqlite:///./litellm.db # 可选启用使用量追踪 otel: true # 可选启用 OpenTelemetry 追踪关键配置解析与避坑指南别名与部署的映射model_name: default是一个别名它的litellm_params.model值claude-3-5-sonnet-20241022必须与下方某个实际部署的model_name完全一致。LiteLLM 通过这个字符串进行查找。API 密钥管理Anthropic通常不需要在config.yaml中配置api_key。ccproxy的forward_oauth钩子会自动从~/.claude/.credentials.json提取 OAuth 令牌并添加到请求头中。这是最安全、最方便的方式。其他供应商Gemini, OpenAI, Perplexity必须提供api_key。强烈建议使用环境变量如${GEMINI_API_KEY}而非硬编码并在启动ccproxy前设置好这些变量。你也可以在litellm_params下使用api_key: “your-key-here”但存在安全风险。callbacks配置litellm_settings.callbacks中必须包含ccproxy.handler否则ccproxy的规则和钩子不会生效。这是连接 LiteLLM 和ccproxy逻辑的桥梁。多供应商兼容性LiteLLM 支持数十种模型供应商。在添加新供应商时务必查阅 LiteLLM 文档 以确认正确的model参数格式如gemini/gemini-2.0-flash-exp和api_base。4.3 钩子配置与高级用法钩子Hooks是ccproxy的插件系统允许你在请求/响应的不同阶段插入自定义逻辑。默认配置已经包含了最常用的几个。hooks: - ccproxy.hooks.rule_evaluator # 必须规则评估 - ccproxy.hooks.model_router # 必须模型路由 - ccproxy.hooks.forward_oauth # 推荐转发 Anthropic OAuth 令牌 - ccproxy.hooks.extract_session_id # 可选提取会话ID用于LangFuse等追踪系统 # - ccproxy.hooks.capture_headers # 可选记录请求头脱敏后 # - ccproxy.hooks.forward_apikey # 可选转发 x-api-key 头用于非OAuth认证forward_oauth的进阶配置默认情况下它只处理 Anthropic。但如果你有其他需要 OAuth 的供应商或者需要自定义 User-Agent可以这样配置oat_sources: anthropic: jq -r .claudeAiOauth.accessToken ~/.claude/.credentials.json my_custom_provider: command: cat /path/to/token.txt user_agent: MyCustomClient/1.0自定义钩子与规则这是ccproxy真正强大的地方。假设你想实现一个规则当用户消息中包含“翻译”关键字时路由到专门的翻译模型。在~/.ccproxy/目录下创建custom_rule.py# ~/.ccproxy/custom_rule.py from ccproxy.rules import BaseRule class TranslateRule(BaseRule): def matches(self, request_body: dict) - bool: # 检查用户消息中是否包含“翻译” messages request_body.get(messages, []) for msg in messages: if msg.get(role) user and 翻译 in msg.get(content, ): return True return False在ccproxy.yaml的rules列表中添加- name: translate rule: custom_rule.TranslateRule在config.yaml中添加对应的模型别名和部署model_list: - model_name: translate litellm_params: model: gpt-4o # 假设用 GPT-4 做翻译 - model_name: gpt-4o litellm_params: model: openai/gpt-4o api_key: ${OPENAI_API_KEY}重启ccproxy使配置生效。5. 日常使用、运维与问题排查配置完成后ccproxy应该能在后台稳定运行。以下是日常使用的命令和遇到问题时系统的排查方法。5.1 常用 CLI 命令速查ccproxy提供了一组直观的命令来管理代理生命周期。# 1. 服务管理 ccproxy start # 前台启动查看日志 ccproxy start --detach # 后台启动 ccproxy stop # 停止后台服务 ccproxy restart # 重启服务等同于 stop start --detach ccproxy status # 查看运行状态和监听的URL # 2. 日志查看 ccproxy logs # 查看最近日志 ccproxy logs -f # 实时跟踪日志类似 tail -f ccproxy logs -n 50 # 查看最近50行日志 # 3. 运行命令 ccproxy run claude -p Hello # 通过代理运行 Claude Code ccproxy run curl http://localhost:4000/health # 测试代理健康状态 ccproxy run python my_script_that_uses_openai.py # 包装任何使用 OpenAI SDK 的脚本 # 4. 配置管理 ccproxy install # 初始生成配置文件通常只需一次 ccproxy install --force # 强制覆盖现有配置文件谨慎使用一个高效的工作流是将export ANTHROPIC_BASE_URLhttp://localhost:4000添加到你的 shell 配置文件~/.zshrc或~/.bashrc中。这样每次打开终端Claude Code 都会自动使用代理。当你需要临时绕过代理时只需unset ANTHROPIC_BASE_URL。5.2 系统化问题排查指南即使配置正确你也可能会遇到问题。下面是一个从表象到根源的排查流程图。问题现象可能原因排查步骤与命令ccproxy start失败提示Address already in use端口 4000 被占用lsof -i :4000查看占用进程kill -9 PID结束它或修改ccproxy.yaml中的litellm.port。Claude Code 报错Failed to connect to API代理服务未运行或网络不通1.ccproxy status确认服务状态。2.curl -v http://localhost:4000/health测试本地连通性。请求成功但返回认证错误如 401OAuth 令牌失效或未正确传递1.ccproxy logs -n 20查看最近日志寻找认证相关错误。2. 确认~/.claude/.credentials.json文件存在且有效。可尝试claude auth login重新登录。3. 检查ccproxy.yaml中forward_oauth钩子是否启用。路由未按预期工作如思考请求未走 Opus规则未匹配或配置错误1.开启调试在ccproxy.yaml中设置debug: true重启服务观察请求日志。日志会显示请求体、匹配的规则标签等信息。2. 检查规则顺序ccproxy.yaml中rules列表的顺序决定了优先级。3. 检查config.yaml确认think等别名是否正确映射到目标模型部署。出现ImportError: Could not import handler from ccproxyccproxy和litellm环境隔离这是最常见问题执行uv tool install claude-ccproxy --with litellm[proxy] --force这会强制在同一个 uv 环境中重装两者。修改ccproxy.yaml后规则未生效钩子文件未更新ccproxy stop ccproxy start --detach。ccproxy.py钩子文件只在启动时生成。使用非 Anthropic 模型如 Gemini时报错API Key requiredAPI 密钥未配置或未传递1. 确认config.yaml中对应模型的api_key已设置建议用环境变量。2. 对于需要x-api-key头的供应商确保ccproxy.yaml中启用了forward_apikey钩子并且你的请求中包含了该头。深度调试技巧当规则逻辑复杂时仅看日志可能不够。你可以临时在自定义钩子或规则中添加print语句打印到ccproxy logs的输出中或者直接使用ccproxy start前台运行在控制台实时观察每一个请求的详细处理过程。LiteLLM 的detailed_debug: true设置也能提供更底层的网络请求信息。5.3 性能监控与优化建议对于长期运行的服务一些简单的监控措施能帮你了解其状态。基础监控ccproxy status命令可以快速检查服务是否存活。结合ccproxy logs -n 5可以查看最近有无错误。资源使用如果发现响应变慢可以用top或htop查看litellm进程的 CPU 和内存占用。LiteLLM 代理本身很轻量但并发请求多时可能会增加负载。配置调优在ccproxy.yaml的litellm部分可以调整num_workers工作进程数默认为 4。对于性能较强的机器可以适当增加如 8以提升并发处理能力。但注意过多的 worker 可能不会带来线性提升反而增加上下文切换开销。网络考虑所有请求都经过本地代理转发理论上会增加微小的延迟通常 1ms。但对于需要调用远程 API 的 LLM 请求来说这部分开销几乎可以忽略不计。确保你的网络到各大模型 API 服务api.anthropic.com, api.openai.com 等的连通性良好。6. 进阶场景与自定义开发当你熟悉了ccproxy的基本用法后可以探索一些更高级的用法甚至参与其开发。6.1 集成其他 AI 工具与工作流ccproxy不仅服务于 Claude Code。任何使用 Anthropic SDK 或 OpenAI SDK通过兼容的基址配置的工具都可以通过它进行路由。集成 OpenAI SDK 的脚本如果你有使用openaiPython 库的脚本可以通过设置环境变量让其走ccproxy代理。# 在脚本运行前设置 export OPENAI_API_BASEhttp://localhost:4000 export OPENAI_BASE_URLhttp://localhost:4000 python your_script.py # 或者使用 ccproxy run 包装 ccproxy run python your_script.py这样脚本中对openai.ChatCompletion.create的调用会被ccproxy拦截并应用你定义的路由规则。你可以让脚本中的某些请求自动使用 Gemini 或 Claude。作为通用的 LLM 网关你可以将ccproxyLiteLLM视为一个本地的、可配置的 LLM 网关。其他应用如自动化流程、聊天机器人后端可以将请求发送到http://localhost:4000并通过在请求头或参数中传递特定的模型名间接利用你配置的多模型路由策略。6.2 参与开发与代码贡献ccproxy是一个开源项目如果你发现了 Bug 或有新功能的想法完全可以参与到开发中。项目使用uv管理依赖和虚拟环境开发流程非常顺畅。# 1. 克隆仓库 git clone https://github.com/starbased-co/ccproxy.git cd ccproxy # 2. 以可编辑模式安装开发环境强烈推荐 uv tool install --editable . --with litellm[proxy] --force # --editable 意味着你对源码的修改会立即生效无需重装 # 3. 运行测试 uv run pytest # 4. 代码风格检查与格式化 uv run ruff format . # 格式化 uv run ruff check --fix . # 检查并自动修复 # 5. 测试你的修改 # 修改代码后只需重启代理即可 ccproxy stop ccproxy start --detach # 然后用你的 Claude Code 测试新功能开发注意事项钩子文件生成~/.ccproxy/ccproxy.py这个主钩子文件是每次ccproxy start时根据ccproxy.yaml中的hooks配置自动生成的。如果你在开发新的钩子需要确保它可以通过 Python 的模块导入路径访问例如放在src/ccproxy/hooks.py中或者放在~/.ccproxy/目录下并通过custom_hook这样的相对路径引用。版本注意官方 README 提到了正在开发的 v2.0这是一个完全重写的版本不再依赖 LiteLLM而是使用 WireGuard 命名空间和网络层拦截。如果你需要更底层、更通用的拦截能力支持任何 LLM 客户端可以关注dev分支。但当前生产稳定使用的仍是基于 LiteLLM 的 v1.x 系列。在我自己的使用中ccproxy已经从一个“有趣的小工具”变成了 AI 工作流中不可或缺的基础设施。它那种“设置好就忘记”的透明感正是优秀工具的标志。最初你可能需要花点时间理解规则和配置但一旦跑通它就能在后台持续地、智能地为你分配计算资源让你更专注于 prompt 本身和要解决的问题而不是在多个模型客户端之间来回切换。这种效率提升是实实在在的。如果你也厌倦了手动切换模型的割裂感不妨花上一个小时按照上面的步骤部署一套属于自己的智能模型路由网关。