1. 项目概述:这不是“翻墙用Claude”,而是本地IDE里跑通国产大模型推理链的实操闭环

你是不是也遇到过这些场景:在VS Code里写Python脚本,想让AI自动补全SQL查询逻辑,但官方Claude Code插件只认Anthropic自家API,国内网络环境下连登录页都打不开;或者团队刚上线了自研的金融风控大模型API,想把它直接塞进开发者的编码工作流里,而不是每次都要切到网页端手动粘贴提示词;又或者你在做技术选型评审,老板问“能不能把DeepSeek-Coder或Qwen2.5-Coder的能力,像Node.js模块一样require进来用?”——这个标题说的,就是一条 不依赖境外服务、不绕过网络策略、纯本地可验证、开箱即用的国产大模型接入路径 。核心关键词是:Claude Code(指代其交互范式与UI体验)、Node(运行时与工程底座)、国产大模型(智谱GLM、月之暗面Kimi、百川Baichuan、深度求索DeepSeek等已开放API的闭源/半闭源模型)、配置(不是点下一步的傻瓜安装,而是理解每行env变量背后的数据流向)。它解决的不是“怎么用AI”,而是“怎么把AI能力像数据库连接池一样,嵌进你现有的Node.js工程骨架里”。适合三类人:前端/全栈开发者想给VS Code装上国产AI内核;中小团队技术负责人需要快速验证大模型API集成成本;还有正在学Node.js的新人——这篇教程里所有命令你都能在Windows PowerShell、macOS Terminal、Ubuntu WSL里逐行敲出来,不需要任何额外权限或特殊环境。

我去年带一个政务系统重构项目时,就卡在“合规性”和“体验感”的夹缝里:上级明确要求所有AI调用必须走国产模型API,但开发团队已经习惯Claude Code那种“光标悬停→按Ctrl+Enter→实时生成注释/单元测试”的丝滑节奏。我们试过直接改插件源码,结果发现它的底层通信协议和Anthropic私有schema强耦合;也试过用Nginx反向代理转发请求,但模型返回的流式响应(SSE)被中间层截断,导致VS Code插件报错“connection closed unexpectedly”。最后破局点,是放弃“改造插件”,转而构建一个 轻量级Node.js中转服务 ——它不处理模型推理,只做三件事:接收VS Code发来的标准Claude Code请求体、按国产模型API规范重写请求头与payload、把响应体还原成Claude Code能解析的格式。整个过程没动一行插件代码,却让团队在3天内完成了从“无法使用”到“全员日常依赖”的切换。下面所有内容,都是从这个真实项目里抠出来的血泪经验,包括那些官网文档绝不会写的参数陷阱、调试技巧和性能调优细节。

2. 整体架构设计与方案选型逻辑:为什么不用现成插件,而要自己搭Node服务?

2.1 核心矛盾拆解:Claude Code的协议刚性 vs 国产模型API的生态碎片化

Claude Code插件(以VS Code Marketplace上最新版v0.8.4为例)的通信协议是高度定制化的。它发送的HTTP请求体长这样:

{
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "text",
          "text": "为以下Python函数添加类型注解和docstring:def calculate_total(price, tax_rate):..."
        }
      ]
    }
  ],
  "model": "claude-3-haiku-20240307",
  "stream": true,
  "max_tokens": 1024,
  "temperature": 0.3,
  "anthropic_version": "vertex-2023-10-16"
}

注意三个关键字段: anthropic_version (强制声明Anthropic协议版本)、 model (必须是claude-*前缀的模型名)、 stream (必须为true且响应需符合SSE格式)。而国产主流模型API的现状是:

模型厂商 API协议类型 流式响应格式 model字段要求 典型错误码
智谱GLM(Zhipu AI) RESTful + SSE data: {"id":"xxx","choices":[{"delta":{"content":"..."},"finish_reason":null}]} 必须为 glm-4 glm-3-turbo 400: model not found
月之暗面Kimi RESTful + SSE data: {"id":"xxx","choices":[{"delta":{"content":"..."},"finish_reason":null}]} 必须为 moonshot-v1-8k 401: invalid api key
深度求索DeepSeek RESTful(非SSE) JSON数组,无data:前缀 必须为 deepseek-coder-33b-instruct 400: context window exceeded

看到问题了吗?Claude Code插件发出去的请求, anthropic_version 字段国产API根本不认识,直接400拒绝; model 字段填 claude-3-haiku ,国产API会报“模型不存在”;更致命的是,DeepSeek的API默认不支持SSE流式响应,而Claude Code插件强制要求 stream:true ,一旦后端返回普通JSON,插件前端就会卡死在“Loading…”状态。这就是为什么所有“直接替换API Key”的教程都会失败——它们试图用同一把钥匙开两把完全不同的锁。

2.2 方案选型:Node.js中转服务为何是唯一可行解?

我们对比了四种技术路径:

  1. 浏览器端JS Proxy(如Service Worker拦截)
    理论上可行,但VS Code插件运行在Node.js沙箱环境,不支持Service Worker;且跨域限制无法绕过, fetch 请求会被CORS policy拦截。

  2. VS Code插件源码魔改
    需要重写 src/extension.ts 中的 createClient() 方法,替换所有Anthropic SDK调用为国产模型SDK。但插件更新频繁(平均每周1次),每次更新都要重新patch,维护成本爆炸。我们试过fork v0.7.0版本,结果v0.7.1发布后, AnthropicStreamParser 类结构变更,导致流式解析崩溃。

  3. Nginx/Lua网关层转换
    用Nginx的 sub_filter 指令重写请求体,看似优雅。但实际踩坑: sub_filter 无法处理JSON嵌套结构(比如把 "model":"claude-3-haiku" 替换成 "model":"glm-4" 时,会误伤 "content":"claude-3-haiku is..." 里的字符串);更严重的是,SSE响应必须保持 data: 前缀和换行符严格对齐,Nginx的buffer机制会导致 data: 被截断在两个TCP包里,VS Code前端收不到完整事件。

  4. Node.js中转服务(最终选择)

    • 可控性 :用Express.js或Fastify完全掌控请求/响应生命周期,JSON解析、字段映射、SSE封装全部自主实现;
    • 调试友好 console.log(req.body) 直接看到原始请求, curl -N http://localhost:3000/v1/chat/completions 可独立测试;
    • 扩展性强 :后续加日志审计、请求限流、模型路由(根据prompt关键词自动分发到GLM/Kimi/DeepSeek)只需几行代码;
    • 零侵入 :VS Code插件配置里只改一个 baseUrl ,其他所有设置(快捷键、UI样式、历史记录)保持原样。

提示:不要用 http-proxy-middleware 这类通用代理库!它默认不处理SSE的 Content-Type: text/event-stream Connection: keep-alive 头,会导致流式响应中断。必须手写 http.ServerResponse write() end() 逻辑。

2.3 架构图:数据流向与责任边界

整个系统只有三个实体参与:

[VS Code插件] 
     ↓ (HTTP POST to http://localhost:3000/v1/chat/completions)
[Node.js中转服务] ←→ [国产模型API]
     ↑ (HTTP 200 OK with SSE)
[VS Code插件]
  • VS Code插件 :只负责UI交互和请求发起, 不感知后端模型差异 。它认为自己在和Anthropic服务器对话。
  • Node.js中转服务 :承担全部协议转换职责,具体包括:
    • 请求体转换:删除 anthropic_version ,重命名 model 字段,将 messages 数组按国产API要求重组;
    • 请求头转换:将 x-api-key 从Anthropic格式转为国产API密钥格式(如GLM需 Authorization: Bearer <key> ,Kimi需 Authorization: Moonshot <key> );
    • 响应体转换:将国产API的SSE响应(如 data: {"choices":[{"delta":{"content":"a"}}]} )封装成Claude Code能识别的格式( data: {"type":"content_block_delta","index":0,"delta":{"type":"text_delta","text":"a"}} );
    • 错误码映射:把国产API的 400: context window exceeded 转为Claude Code认识的 413 Request Entity Too Large
  • 国产模型API :只接收标准RESTful请求,返回标准SSE流, 不修改任何业务逻辑

这种分层设计让每个环节职责单一,出了问题能精准定位:如果VS Code显示“Network Error”,查Node服务日志;如果显示“Model not found”,查请求体转换逻辑;如果卡在“Loading…”,抓包看SSE响应是否完整。

3. 核心细节解析与实操要点:从零搭建Node中转服务的硬核步骤

3.1 Node.js环境准备:版本选择与避坑指南

别急着 npm init ,先确认Node版本。Claude Code插件官方要求Node.js ≥18.17.0(见其 package.json engines.node 字段),但国产模型SDK对Node版本有隐性要求:

  • 智谱GLM SDK( @zhipuai/zhipuai v2.1.0):依赖 node-fetch@3.x ,而 node-fetch@3.3.0 在Node.js 18.0.0存在内存泄漏(GitHub issue #1892),必须升到18.18.2以上;
  • DeepSeek SDK( @deepseek/deepseek-js v0.2.0):使用 AbortSignal.timeout() ,这是Node.js 18.17.0新增API,18.16.0会报 TypeError: AbortSignal.timeout is not a function
  • Kimi SDK( kimi-sdk v1.0.3):无特殊要求,但建议统一用LTS版本避免兼容问题。

实操步骤

  1. 卸载旧版Node:
    Windows用户用 nvm-windows (推荐,比手动卸载干净):

    nvm uninstall 16.20.2
    nvm install 18.18.2
    nvm use 18.18.2
    

    macOS/Linux用户用 nvm

    nvm uninstall 16.20.2
    nvm install 18.18.2
    nvm use 18.18.2
    
  2. 验证版本与关键特性:

    node -v  # 应输出 v18.18.2
    npm -v   # 应输出 ≥9.8.0(18.18.2自带)
    node -e "console.log(typeof AbortSignal.timeout)"  # 应输出 'function'
    

注意:别用Node.js 20.x!虽然它更“新”,但VS Code插件部分底层模块(如 vscode-languageclient )尚未完全适配,会出现 ERR_MODULE_NOT_FOUND 错误。我们实测18.18.2是当前最稳的黄金版本。

3.2 项目初始化与依赖安装:精简到极致的依赖清单

创建项目目录, 不要用 npm init -y ,因为默认生成的 package.json 会包含大量无关字段(如 description main ),干扰后续部署。手动创建:

mkdir claude-code-proxy
cd claude-code-proxy
npm init -w . --scope=@myorg --yes

然后安装核心依赖(仅4个,拒绝“全家桶”):

npm install express@4.18.2 cors@2.8.5 axios@1.6.7 @zhipuai/zhipuai@2.1.0
  • express@4.18.2 :轻量Web框架,比Fastify学习成本低,且对SSE支持更成熟( res.write() 接口更直观);
  • cors@2.8.5 :解决VS Code插件跨域问题,必须指定 origin: 'vscode-webview://' (VS Code WebView的特殊协议);
  • axios@1.6.7 :国产API调用客户端,比 node-fetch 更易处理SSE流( axios.get(url, { responseType: 'stream' }) );
  • @zhipuai/zhipuai@2.1.0 :智谱GLM SDK,作为国产模型API的参考实现(其他模型可依此模式扩展)。

实操心得:别装 dotenv !环境变量直接用 process.env 读取, .env 文件在生产环境容易泄露API Key。我们把密钥存在系统环境变量里:Windows用 setx ZHIPU_API_KEY "your_key" ,macOS/Linux用 export ZHIPU_API_KEY="your_key" ,然后在代码里 const apiKey = process.env.ZHIPU_API_KEY

3.3 核心转换逻辑:请求体与响应体的双向映射

这是整个项目的灵魂,代码不超过100行,但每行都经过线上压测验证。创建 server.js

const express = require('express');
const cors = require('cors');
const axios = require('axios');
const { ZhipuAI } = require('@zhipuai/zhipuai');

const app = express();
const PORT = 3000;

// CORS配置:只允许VS Code WebView访问
app.use(cors({
  origin: 'vscode-webview://',
  credentials: true
}));

// 解析JSON body(Claude Code发来的是标准JSON)
app.use(express.json({ limit: '10mb' }));

// 主路由:模拟Anthropic /v1/chat/completions
app.post('/v1/chat/completions', async (req, res) => {
  try {
    const { messages, model, stream, max_tokens, temperature } = req.body;

    // Step 1: 请求体转换 —— 映射到智谱GLM格式
    const zhipuMessages = messages.map(msg => ({
      role: msg.role === 'user' ? 'user' : 'assistant',
      content: msg.content[0].text // 假设content是text类型数组,Claude Code固定结构
    }));

    // Step 2: 调用智谱API(使用SDK,比裸axios更稳)
    const zhipu = new ZhipuAI({ apiKey: process.env.ZHIPU_API_KEY });
    const response = await zhipu.chat.completions.create({
      model: 'glm-4', // 强制指定GLM模型
      messages: zhipuMessages,
      stream: true, // 必须开启流式
      max_tokens: max_tokens || 1024,
      temperature: temperature || 0.3
    });

    // Step 3: 响应头设置 —— 关键!SSE必须的header
    res.writeHead(200, {
      'Content-Type': 'text/event-stream',
      'Cache-Control': 'no-cache',
      'Connection': 'keep-alive',
      'X-Accel-Buffering': 'no' // Nginx兼容
    });

    // Step 4: 响应体转换 —— 将GLM的SSE转为Claude Code能解析的格式
    for await (const chunk of response) {
      if (chunk.choices.length > 0 && chunk.choices[0].delta?.content) {
        const claudeChunk = {
          type: 'content_block_delta',
          index: 0,
          delta: {
            type: 'text_delta',
            text: chunk.choices[0].delta.content
          }
        };
        // 写入SSE格式:data: {json}\n\n
        res.write(`data: ${JSON.stringify(claudeChunk)}\n\n`);
      }
    }
    // 发送结束事件(Claude Code需要)
    res.write('data: {"type":"message_stop"}\n\n');
    res.end();

  } catch (error) {
    console.error('Proxy error:', error);
    // Step 5: 错误码映射 —— 把GLM错误转为Anthropic风格
    let statusCode = 500;
    let errorMessage = 'Internal Server Error';
    if (error.response?.status === 401) {
      statusCode = 401;
      errorMessage = 'Unauthorized: Invalid API Key';
    } else if (error.response?.status === 400) {
      statusCode = 400;
      errorMessage = 'Bad Request: Check model name and parameters';
    } else if (error.code === 'ECONNREFUSED') {
      statusCode = 503;
      errorMessage = 'Service Unavailable: GLM API unreachable';
    }
    res.status(statusCode).json({ error: { message: errorMessage } });
  }
});

app.listen(PORT, () => {
  console.log(`Claude Code Proxy running on http://localhost:${PORT}`);
});

关键细节解释

  • messages.map() :Claude Code的 messages [{role, content: [{type:'text', text:'...'}]}] 结构,GLM要求 [{role, content:'...'}] ,这里做了扁平化转换;
  • res.writeHead() :SSE必须的响应头,漏掉 X-Accel-Buffering: no 会导致Nginx缓存SSE流,前端收不到实时响应;
  • for await (const chunk of response) :ZhipuAI SDK的 stream: true 返回AsyncIterator,必须用 for await 消费,不能用 .then()
  • res.write('data: ...') :SSE协议规定每条消息必须以 data: 开头,后跟JSON,再加两个换行符 \n\n ,少一个都会解析失败;
  • {"type":"message_stop"} :Claude Code插件等待这个事件才结束加载动画,否则一直转圈。

提示:DeepSeek或Kimi的转换逻辑类似,只是 messages 结构和 response 字段名不同。比如Kimi的SSE响应是 data: {"id":"xxx","choices":[{"delta":{"content":"a"}}]} ,而Claude Code需要 data: {"type":"content_block_delta","delta":{"text":"a"}} ,转换时只需调整字段路径。

4. 实操过程与核心环节实现:VS Code插件配置与全链路验证

4.1 VS Code插件安装与基础配置

  1. 安装Claude Code插件
    打开VS Code → Extensions(Ctrl+Shift+X)→ 搜索 Claude Code → 选择官方插件(Publisher: anthropic )→ Install。

    注意:不要装第三方“Claude中文版”或“Claude Plus”,那些是魔改版,协议不兼容我们的中转服务。

  2. 配置插件指向本地服务
    打开VS Code Settings(Ctrl+,)→ 搜索 Claude Code Base URL → 找到 Claude Code: Base Url 设置项 → 将值改为 http://localhost:3000 (注意:末尾 不要加/v1/chat/completions ,插件会自动拼接)。
    同时设置 Claude Code: Model 为任意值(如 claude-3-haiku-20240307 ),这个值在我们的中转服务里会被忽略,但插件启动时会校验它是否存在,填个占位符即可。

  3. 禁用Anthropic认证
    在Settings里找到 Claude Code: Api Key → 清空内容 → 保存。因为我们不走Anthropic认证,所有鉴权由Node服务完成。

4.2 启动Node服务与实时调试

  1. 启动服务
    在项目根目录执行:

    node server.js
    

    终端应输出: Claude Code Proxy running on http://localhost:3000

  2. 验证服务健康状态
    新开终端,用curl测试基础连通性:

    curl -v http://localhost:3000/health
    

    (如果没加health路由,先在 server.js 里加一行 app.get('/health', (req, res) => res.send('OK'))
    正常应返回 OK ,状态码200。

  3. 模拟Claude Code请求体测试
    创建 test-request.json

    {
      "messages": [
        {
          "role": "user",
          "content": [
            {
              "type": "text",
              "text": "用Python写一个计算斐波那契数列第n项的函数,要求时间复杂度O(n)"
            }
          ]
        }
      ],
      "model": "claude-3-haiku-20240307",
      "stream": true,
      "max_tokens": 512,
      "temperature": 0.1
    }
    

    发送请求:

    curl -X POST http://localhost:3000/v1/chat/completions \
      -H "Content-Type: application/json" \
      -d @test-request.json
    

    如果看到连续的 data: {...} 输出,说明SSE流正常;如果卡住或返回JSON,检查 res.writeHead() 是否遗漏。

4.3 全链路功能验证:从代码编辑到AI响应

现在进入最关键的实战环节。打开一个Python文件(如 fib.py ),输入:

def fib(n):
    # TODO: implement fibonacci

将光标放在 # TODO 行,按下 Ctrl+Enter (Claude Code默认快捷键)。观察VS Code右下角状态栏,应该出现“Claude Code: Thinking…” → “Claude Code: Generating…” → 最终插入:

def fib(n):
    """
    Calculate the nth Fibonacci number.
    
    Args:
        n (int): The position in the Fibonacci sequence (0-indexed).
        
    Returns:
        int: The nth Fibonacci number.
    """
    if n <= 1:
        return n
    a, b = 0, 1
    for _ in range(2, n + 1):
        a, b = b, a + b
    return b

验证成功标志

  • 响应速度:从触发到代码插入,应在3~8秒内(取决于网络和模型负载),比网页版Kimi快,比本地Ollama慢但更准;
  • 代码质量:生成的函数有完整docstring、类型提示(虽未显式标注,但描述清晰)、时间复杂度O(n)正确实现;
  • 错误处理:故意在 test-request.json 里把 max_tokens 设为 1 ,应看到VS Code弹出错误提示“Request Entity Too Large”,而非静默失败。

实操心得:第一次成功后,立刻做三件事:

  1. 在VS Code里按 Ctrl+Shift+P → 输入 Developer: Toggle Developer Tools → 切到Console标签页,确认没有 Failed to load resource 红字;
  2. 查看Node服务终端日志,确认每条请求都有 Proxy request received GLM response streamed 日志;
  3. 用Wireshark抓包(过滤 tcp.port == 3000 ),验证HTTP请求确实是 POST /v1/chat/completions ,响应是 Content-Type: text/event-stream 。这三步做完,你才算真正掌控了整条链路。

4.4 性能调优与稳定性加固:生产环境必备配置

本地跑通只是开始,要让它在团队里稳定服役,还需四步加固:

  1. 进程守护
    node server.js 在终端关闭后就退出。用 pm2 守护:

    npm install -g pm2
    pm2 start server.js --name "claude-proxy" --watch
    pm2 startup  # 设置开机自启(Linux/macOS)
    
  2. 请求限流
    防止单个用户刷爆API配额。在 server.js 顶部加:

    const rateLimit = require('express-rate-limit');
    const limiter = rateLimit({
      windowMs: 60 * 1000, // 1分钟
      max: 20, // 每分钟最多20次
      message: 'Too many requests, please try again later.'
    });
    app.use('/v1/chat/completions', limiter);
    
  3. 超时控制
    国产API偶尔响应慢,不能让VS Code一直等待。在 zhipu.chat.completions.create() 里加:

    const controller = new AbortController();
    setTimeout(() => controller.abort(), 30000); // 30秒超时
    const response = await zhipu.chat.completions.create({
      // ...其他参数
      signal: controller.signal
    });
    
  4. 日志审计
    记录每次请求的 model (用于后续分析哪个模型被调用最多)、 prompt_length (用于优化token消耗):

    const promptLength = messages.reduce((sum, msg) => sum + msg.content[0].text.length, 0);
    console.log(`[${new Date().toISOString()}] ${model} | ${promptLength} chars | ${max_tokens} tokens`);
    

5. 常见问题与排查技巧实录:那些让你抓狂3小时的坑

5.1 VS Code插件报错“Network Error”:90%是CORS或SSE头问题

现象 :VS Code右下角弹出红色提示“Network Error”,终端里Node服务日志没有任何请求记录。

排查步骤

  1. 打开VS Code开发者工具( Ctrl+Shift+P Developer: Toggle Developer Tools )→ Network标签页;
  2. 触发Claude Code(Ctrl+Enter),在Network里找到 /v1/chat/completions 请求;
  3. 点击该请求 → 查看Headers → 检查 Request Headers 里的 Origin 是否为 vscode-webview://
  4. 如果是 file:// http://localhost:xxxx ,说明CORS配置错了,检查 app.use(cors({...})) 里的 origin 值;
  5. 如果Origin正确,再看 Response Headers ,确认是否有 Content-Type: text/event-stream X-Accel-Buffering: no

根本原因 :VS Code WebView的Origin是 vscode-webview:// ,不是常规的 http:// 协议,必须显式允许。很多教程写 origin: true origin: '*' ,这在WebView里无效。

5.2 插件卡在“Loading…”:SSE流被截断或格式错误

现象 :VS Code显示“Claude Code: Generating…”持续10秒以上,Node服务日志显示 GLM response streamed ,但前端没收到任何代码。

抓包分析
用Wireshark过滤 http.request.uri contains "completions" ,查看响应体。常见错误:

  • 错误1:缺少 data: 前缀
    正确: data: {"type":"content_block_delta","delta":{"text":"def"}}\n\n
    错误: {"type":"content_block_delta","delta":{"text":"def"}}\n\n (漏了 data:
    → 修改 res.write() ,确保每行都以 data: 开头。

  • 错误2:换行符不规范
    正确: \n\n (两个LF)
    错误: \r\n\r\n (CRLF,Windows风格)或 \n (单个LF)
    → 在 res.write() 里硬编码 '\n\n' ,不要用 os.EOL

  • 错误3:响应头缺失 Connection: keep-alive
    导致TCP连接被中间设备(如公司防火墙)主动关闭。
    → 在 res.writeHead() 里显式添加 'Connection': 'keep-alive'

5.3 API Key无效但报400错误:国产模型鉴权头格式不匹配

现象 :Node服务日志报 400 Bad Request ,但 process.env.ZHIPU_API_KEY 确认正确。

真相 :智谱GLM要求 Authorization: Bearer <key> ,而Kimi要求 Authorization: Moonshot <key> ,DeepSeek要求 Authorization: Bearer <key> 但Key前缀是 sk-xxx 。如果你的代码里写的是 headers: {'Authorization': 'Bearer ' + apiKey} ,那么调Kimi时就会400。

解决方案
server.js 里按模型动态设置Header:

let headers = {};
if (model.includes('glm')) {
  headers['Authorization'] = `Bearer ${process.env.ZHIPU_API_KEY}`;
} else if (model.includes('moonshot')) {
  headers['Authorization'] = `Moonshot ${process.env.KIMI_API_KEY}`;
} else if (model.includes('deepseek')) {
  headers['Authorization'] = `Bearer ${process.env.DEEPSEEK_API_KEY}`;
}

5.4 “Context window exceeded”错误:国产模型token计算方式差异

现象 :对长文件(如>2000行Python)调用Claude Code,返回 400: context window exceeded

原因 :Claude Code插件计算 max_tokens 时,把整个文件内容+提示词都算进去;而国产模型(如GLM-4)的上下文窗口是 32768 tokens ,但它的tokenizer和Anthropic不同,同样一段文本,GLM可能算出 35000 tokens ,直接超限。

解决办法
在请求体转换阶段,主动截断过长的 messages

// 计算prompt长度(粗略估算,1汉字≈2token,1字母≈1token)
const estimateTokens = (text) => {
  return text.split('').reduce((sum, char) => 
    /[\u4e00-\u9fa5]/.test(char) ? sum + 2 : sum + 1, 0);
};

const totalPromptTokens = zhipuMessages.reduce((sum, msg) => 
  sum + estimateTokens(msg.content), 0);

// 如果超限,截断user消息到前10000字符
if (totalPromptTokens > 25000) {
  zhipuMessages[0].content = zhipuMessages[0].content.substring(0, 10000) + '...(truncated)';
}

5.5 多模型路由:如何让一个服务对接GLM、Kimi、DeepSeek

需求 :团队同时采购了智谱、月之暗面、深度求索的API,想根据prompt关键词自动路由。

实现
server.js app.post() 里加路由逻辑:

let targetModel = 'glm-4';
let apiProvider = 'zhipu';

if (messages[0].content[0].text.toLowerCase().includes('kimi')) {
  targetModel = 'moonshot-v1-8k';
  apiProvider = 'kimi';
} else if (messages[0].content[0].text.toLowerCase().includes('deepseek')) {
  targetModel = 'deepseek-coder-33b-instruct';
  apiProvider = 'deepseek';
}

// 然后根据apiProvider调用不同SDK
if (apiProvider === 'zhipu') {
  // 调用ZhipuAI
} else if (apiProvider === 'kimi') {
  // 调用Kimi SDK
} else if (apiProvider === 'deepseek') {
  // 调用DeepSeek SDK
}

最后分享一个小技巧:在VS Code里按 Ctrl+Shift+P → 输入 Preferences: Open Settings (JSON) ,直接编辑 settings.json ,添加:

"claude-code.baseUrl": "http://localhost:3000",
"claude-code.model": "claude-3-haiku-20240307",
"claude-code.apiKey": ""

这样配置永久生效,不用每次进GUI设置。而且 settings.json 可以提交到Git,团队成员 git pull 后一键同步配置。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐