🐱煤球接入Deepseek
在此之前,煤球的模型是Gemini:
[**my-blog-manager/app/api/chat/route.ts**](vscode-webview://1cte5emmbpca15lv39mqrfijum16bt8hnmbiov069074au52roah/my-blog-manager/app/api/chat/route.ts)
这是小猫 AI 的**后端路由**,直接对接 **Google Gemini API**:
* 第 13 行:从环境变量 `GEMINI_API_KEY` 或 `OPENAI_API_KEY` 读取密钥
* 第 21-22 行:从 `siteConfig.geminiConfig` 读取模型 ID,构建请求 URL:
```
https://generativelanguage.googleapis.com/v1beta/models/{modelId}:generateContent?key={apiKey}
```
* 第 29-42 行:发送请求体,包含 `system_instruction`(猫设 prompt)、用户消息、`generationConfig`(token 上限、temperature)
---
### 2. API 配置(模型参数 + 猫设 Prompt)
```
geminiConfig: {
modelId: "",
systemPrompt: "",
maxOutputTokens: ,
temperature: ,
},
```
---
### 3. 前端调用方
* [**my-blog-manager/components/CyberCat.tsx**](vscode-webview://1cte5emmbpca15lv39mqrfijum16bt8hnmbiov069074au52roah/my-blog-manager/components/CyberCat.tsx) — 页面右下角的赛博小猫组件,`handleFeed()`和 `handleChatSubmit()`都向 `/api/chat` 发 POST 请求
* [**my-blog-manager/components/settings/AICatSection.tsx**](vscode-webview://1cte5emmbpca15lv39mqrfijum16bt8hnmbiov069074au52roah/my-blog-manager/components/settings/AICatSection.tsx) — 后台设置页面,可修改 modelId、systemPrompt、temperature、maxOutputTokens,点"暂存至队列"写入 `geminiConfig`
---
而接入Deepseek有两个需要注意的点:
* DeepSeek 用的是 OpenAI 兼容接口,跟 Gemini 的请求体结构完全不同:
* **端点,鉴别权限都不相同**
此外:CMS 管理后台(Settings 页面 → AI 小猫配置)点「暂存至队列」并应用,**会丢失** `apiKey` **和** `baseUrl`。
原因是 [cms\_core/api/config.py:178-185](vscode-webview://1cte5emmbpca15lv39mqrfijum16bt8hnmbiov069074au52roah/my-blog-manager/cms_core/api/config.py#L178) 的写入逻辑——前端只传 4 个字段:
```
{ modelId, systemPrompt, maxOutputTokens, temperature }
```
后端用正则直接把整个 `geminiConfig` 块替换掉,新增的 `apiKey` 和 `baseUrl` 不在前端传的字段里
解决问题:在 config.py 的 update\_site\_config 里加一个合并逻辑 —— 更新 dict 之前先保留已有字段,缺少的 key 不被丢弃。不影响现有任何功能。
```
existing = {}
m = re.search(rf"{key}\s*:\s*\{{([\s\S]*?)\}}", content)
if m:
existing = parse_ts_dict(m.group(1))
merged = {**existing, **value}
```
不过!!!把 key 明文写在代码里相当于把房门钥匙贴在门上。🐖
所以我在**在 Vercel Dashboard → Settings → Environment Variables 加入环境变量,这样就不用把API放在仓库里面**

搞定!