# AI-Agent

# 在阿里云创建agent实现建立各个专业智能体

这个思路是非常可行的，而且对于您这样的企业运维和技术团队来说，比单纯购买SaaS更有价值。

如果已经有阿里云账号，可以利用阿里云的：

- 百炼（Agent应用开发平台）
- 通义千问大模型
- OSS对象存储
- 函数计算FC
- ECS服务器
- RDS数据库
- 向量检索服务
- 企业知识库

构建企业级AI智能体平台。

## 一、总体架构

```text
                     企业AI门户

          ┌─────────────────────┐
          │ Flask / Vue WebUI   │
          └──────────┬──────────┘
                     │
                     ▼

          ┌─────────────────────┐
          │ 阿里云百炼 Agent平台 │
          └──────────┬──────────┘

     ┌───────────────┼───────────────┐
     ▼               ▼               ▼

写作Agent      图片Agent      合同Agent

     ▼               ▼               ▼

通义千问      通义万相       RAG知识库
Qwen3         文生图         OCR+LLM

     ▼               ▼               ▼

     OSS            OSS           企业文档库

```

---

# 二、建议建设的智能体

按照企业需求优先级排序：

## 1. 企业公文写作Agent

用途：

- 工作总结
- 周报月报
- 招投标文件
- 运维方案
- 应急预案
- 技术文档

知识库来源：

```text
公司历史文档
运维规范
项目方案
招投标文件

```

能力：

```text
输入：
项目名称

输出：
完整Word方案

```

例如：

```text
请生成：

智慧路灯平台运维方案

要求：
20页
包含架构图

```

自动生成：

```text
项目背景
实施方案
网络架构
运维保障
应急预案

```

---

## 2. 图片设计Agent

调用：

- 通义万相

用途：

```text
网站Banner
产品宣传图
公众号配图
PPT插图

```

例如：

```text
生成一张：

科技感
蓝色风格
智慧路灯云平台

```

自动输出PNG。

---

## 3. 视频生成Agent

调用：

- 通义万相视频模型

用途：

```text
企业宣传片
产品演示视频
培训视频

```

输入：

```text
智慧路灯系统
1分钟宣传视频

```

自动生成：

```text
MP4
字幕
配音

```

---

## 4. 合同审查Agent

这是企业最有价值的应用之一。

流程：

```text
上传PDF

↓
OCR识别

↓
大模型分析

↓
风险输出

```

自动识别：

```text
付款条款
违约责任
保密协议
知识产权
续约条款

```

输出：

```text
风险等级

高风险：
第12条

建议修改：
......

```

---

## 5. 运维专家Agent（强烈推荐）

结合您的专业领域。

导入：

```text
Linux知识库
MySQL知识库
MongoDB知识库
PostgreSQL知识库
Wazuh知识库
网络设备知识库

```

知识来源：

```text
Markdown
Word
PDF
Sphinx文档

```

然后实现：

```text
上传日志

↓

自动分析

↓

输出解决方案

```

例如：

```text
上传：

nf_conntrack日志

```

直接输出：

```text
连接数异常

原因：
RabbitMQ连接泄漏

建议：
...

```

这对您当前工作最有帮助。

---

## 6. 代码助手Agent

支持：

- Shell
- Python
- SQL
- Ansible
- Docker
- Kubernetes

例如：

```text
生成Ubuntu20.04安装脚本

```

自动输出：

```bash
#!/bin/bash
...

```

---

## 7. 企业知识库Agent

类似企业版ChatGPT。

上传：

```text
PDF
Word
Excel
Sphinx
Wiki

```

员工可以直接提问：

```text
VPN怎么申请？

数据库备份流程是什么？

```

智能体直接回答。

---

# 三、实施路线（推荐）

### 第一阶段（1周）

部署：

- 阿里云百炼
- 通义千问

先做：

```text
运维Agent
写作Agent

```

投入最低。

---

### 第二阶段（2周）

接入：

```text
OSS
企业知识库
向量数据库

```

实现：

```text
合同审查
企业问答

```

---

### 第三阶段（1个月）

开发统一门户：

```text
https://ai.company.com

```

菜单：

```text
AI写作
AI图片
AI视频
AI合同
AI运维
AI知识库

```

统一登录。

---

# 四、成本估算

100人以内企业：

<table id="bkmrk-%E9%A1%B9%E7%9B%AE-%E6%9C%88%E8%B4%B9%E7%94%A8-%E9%80%9A%E4%B9%89%E5%8D%83%E9%97%AEapi-200%7E1"><thead><tr><th>项目</th><th>月费用</th></tr></thead><tbody><tr><td>通义千问API</td><td>200~1000元</td></tr><tr><td>通义万相图片</td><td>100~500元</td></tr><tr><td>视频生成</td><td>300~2000元</td></tr><tr><td>OSS</td><td>50元左右</td></tr><tr><td>向量数据库</td><td>200~500元</td></tr><tr><td>ECS服务器</td><td>200~500元</td></tr></tbody></table>

总计：

```text
约1000~5000元/月

```

相比购买多个第三方AI产品，成本通常更低，而且数据留在企业体系内。

---

结合您目前已经在使用 Ubuntu、Flask、Sphinx 知识库、MySQL/MongoDB/PostgreSQL 和运维文档体系，我建议优先建设：

1. 运维专家Agent（知识库问答+日志分析）
2. 企业文档写作Agent
3. 合同审查Agent
4. 图片设计Agent
5. 视频生成Agent

这样 1~2 个月内就能形成一个完整的企业AI平台，并且能直接服务于运维、项目实施和管理部门。

# 完全可以由运维团队主导落地企业AI智能体平台，不一定需要开发团队

以您目前的背景来看（30多年运维经验、熟悉Linux、Docker、数据库、中间件、服务器部署），**完全可以由运维团队主导落地企业AI智能体平台，不一定需要开发团队**。

不过要分阶段实施，否则容易投入几十万最后变成一个没人用的平台。

# 一、先回答核心问题

## 1. 仅靠运维人员能实现吗？

答案：

**80%能实现。**

以下场景基本不用开发：

<table id="bkmrk-%E6%99%BA%E8%83%BD%E4%BD%93-%E9%9A%BE%E5%BA%A6-%E8%BF%90%E7%BB%B4%E8%83%BD%E5%90%A6%E5%AE%8C%E6%88%90-%E5%86%99%E6%96%87%E7%AB%A0-%E2%98%85-"><thead><tr><th>智能体</th><th>难度</th><th>运维能否完成</th></tr></thead><tbody><tr><td>写文章</td><td>★</td><td>√</td></tr><tr><td>写方案</td><td>★</td><td>√</td></tr><tr><td>PPT生成</td><td>★★</td><td>√</td></tr><tr><td>图片生成</td><td>★★</td><td>√</td></tr><tr><td>视频生成</td><td>★★</td><td>√</td></tr><tr><td>文档总结</td><td>★</td><td>√</td></tr><tr><td>知识库问答</td><td>★★</td><td>√</td></tr><tr><td>运维助手</td><td>★★</td><td>√</td></tr><tr><td>SQL分析</td><td>★★</td><td>√</td></tr><tr><td>合同审查</td><td>★★★</td><td>√</td></tr><tr><td>OA流程审批</td><td>★★★★</td><td>需开发</td></tr><tr><td>ERP集成</td><td>★★★★</td><td>需开发</td></tr><tr><td>CRM集成</td><td>★★★★</td><td>需开发</td></tr></tbody></table>

所以：

### 第一阶段

完全不需要开发团队

直接用：

- 阿里云百炼Agent
- Dify
- FastGPT
- Coze
- MaxKB

即可。

---

# 二、推荐方案

如果公司规模：

### 100人以下

推荐：

## 方案A

阿里云百炼 + 企业知识库

架构：

```text
员工
  │
  ▼
阿里云百炼Agent
  │
  ├── 写文章Agent
  ├── 法务Agent
  ├── 运维Agent
  ├── HR Agent
  ├── PPT Agent
  └── 客服Agent

```

优点：

- 不用买GPU
- 不用训练模型
- 直接开通

1周内可上线

---

# 三、如果公司想做长期AI平台

我更推荐：

## 方案B

Dify + 阿里百炼API

架构：

```text
用户
 │
 ▼
Dify
 │
 ├── Qwen3
 ├── DeepSeek
 ├── Claude
 ├── GPT
 │
 └── 企业知识库

```

优点：

### 1

所有Agent统一管理

例如：

```text
AI写作助手

AI法务助手

AI运维助手

AI人事助手

AI销售助手

```

都在一个平台。

---

### 2

支持RAG知识库

上传：

```text
Word

PDF

Excel

制度文件

合同模板

运维手册

SOP文档

```

即可。

---

### 3

无需编程

拖拽式。

运维即可维护。

---

# 四、合同审查Agent怎么实现

这是很多企业最需要的。

例如上传：

```text
采购合同.pdf

```

Agent自动分析：

```text
付款条款

违约责任

风险点

知识产权

保密条款

争议解决

```

输出：

```text
高风险

中风险

低风险

```

实现方式：

```text
Dify
 +
Qwen-Max
 +
合同知识库

```

即可。

无需训练模型。

---

# 五、图片和视频Agent

## 图片

推荐：

- 通义万相
- Flux
- Midjourney

阿里云体系：

[通义万相官网](https://tongyi.aliyun.com/wanxiang?utm_source=chatgpt.com)

可实现：

```text
宣传海报

公众号配图

产品效果图

PPT插图

```

---

## 视频

推荐：

- 通义万相视频
- 即梦
- Kling

生成：

```text
宣传视频

培训视频

产品演示

```

---

# 六、是否需要自建服务器

我的建议：

## 第一阶段

不要自建GPU

直接云端API。

原因：

假设用Qwen3 235B：

```text
单机部署

至少：
4 × A800

或

4 × H20

```

硬件：

```text
50万~100万+

```

还不算：

```text
机房
电力
维护
升级

```

不划算。

---

## 第二阶段

如果员工大量使用

例如：

```text
200+
员工

每天：
5000+
问答

```

再考虑本地部署：

### 推荐

```text
DeepSeek-R1 70B

Qwen3 32B

Qwen3 72B

```

部署：

```text
Ubuntu 24.04
Docker
vLLM
Ollama
OpenWebUI

```

---

# 七、结合贵公司实际情况的推荐

从您的运维背景来看，我会采用：

```text
阶段1（1个月）

阿里云百炼
+
Dify
+
企业知识库

```

实现：

```text
运维助手
合同助手
写作助手
PPT助手
图片助手

```

---

```text
阶段2（3个月）

统一SSO登录
部门知识库
权限控制
审计日志

```

---

```text
阶段3（半年）

本地私有化部署

OpenWebUI
+
Dify
+
Qwen3
+
DeepSeek

```

形成公司AI平台。

---

# 推荐的最终架构

```text
             员工
               │
               ▼
          Dify门户
               │
 ┌─────────────┼─────────────┐
 │             │             │
 ▼             ▼             ▼

写作Agent   合同Agent   运维Agent

 │             │             │

 └─────────────┼─────────────┘
               │
               ▼

          阿里百炼API

               │

      Qwen3 / DeepSeek

               │

          企业知识库

```

对于大多数中小企业，这是投入最小、见效最快、后期又能平滑升级到私有化部署的方案。以您现有的运维团队能力，部署 Dify、OpenWebUI、向量数据库（如 [Milvus](https://milvus.io/?utm_source=chatgpt.com) 或 [Qdrant](https://qdrant.tech/?utm_source=chatgpt.com)）以及对接阿里云百炼，基本不需要专职开发人员即可完成。

如果您计划在公司内部搭建私有AI平台，采用：

```text
Ubuntu 24.04
Docker
vLLM
Ollama
OpenWebUI

```

这是目前企业私有化部署中比较成熟且维护成本较低的方案。

# 一、整体架构

建议采用如下架构：

```text
                     用户浏览器
                           │
                           ▼
                     OpenWebUI
                           │
          ┌────────────────┴──────────────┐
          │                               │
          ▼                               ▼
      Ollama                        vLLM Server
    （小模型）                     （大模型）
          │                               │
          ▼                               ▼
      Qwen3:8B                     Qwen3:32B
      Qwen3:14B                    DeepSeek-R1
      Gemma3                       Llama3

```

用途：

<table id="bkmrk-%E6%9C%8D%E5%8A%A1-%E4%BD%9C%E7%94%A8-openwebui-chat"><thead><tr><th>服务</th><th>作用</th></tr></thead><tbody><tr><td>OpenWebUI</td><td>ChatGPT风格界面</td></tr><tr><td>Ollama</td><td>管理小模型</td></tr><tr><td>vLLM</td><td>高性能推理</td></tr><tr><td>Docker</td><td>容器化</td></tr><tr><td>Nginx</td><td>反向代理</td></tr><tr><td>PostgreSQL</td><td>数据库</td></tr><tr><td>Redis</td><td>缓存</td></tr></tbody></table>

---

# 二、硬件建议

## 最低配置

测试环境

```text
CPU：
32 Core

内存：
128GB

GPU：
RTX4090 24GB

系统盘：
1TB NVMe

```

可运行：

```text
Qwen3:8B
Qwen3:14B
DeepSeek-R1:8B

```

---

## 推荐配置

企业环境

```text
CPU：
64 Core

内存：
256GB

GPU：
2 × RTX4090

```

可运行：

```text
Qwen3 32B
DeepSeek-R1 32B

```

---

# 三、安装 Docker

更新系统

```bash
apt update
apt upgrade -y

```

安装基础组件

```bash
apt install -y \
curl \
wget \
git \
vim \
unzip

```

安装Docker

```bash
curl -fsSL https://get.docker.com | bash

```

验证

```bash
docker version

```

加入docker组

```bash
usermod -aG docker $USER

```

重新登录。

---

# 四、安装 NVIDIA 驱动

查看显卡

```bash
lspci | grep NVIDIA

```

安装驱动

```bash
ubuntu-drivers autoinstall

```

重启

```bash
reboot

```

检查

```bash
nvidia-smi

```

应看到类似：

```text
Driver Version: 575.xx
CUDA Version: 12.x

```

---

# 五、安装 NVIDIA Container Toolkit

添加仓库

```bash
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
| gpg --dearmor \
-o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

```

安装

```bash
apt install -y nvidia-container-toolkit

```

配置

```bash
nvidia-ctk runtime configure --runtime=docker

```

重启docker

```bash
systemctl restart docker

```

测试

```bash
docker run --rm \
--gpus all \
nvidia/cuda:12.4.1-runtime-ubuntu22.04 \
nvidia-smi

```

---

# 六、安装 Ollama

官方安装

```bash
curl -fsSL https://ollama.com/install.sh | sh

```

查看

```bash
systemctl status ollama

```

开放监听

编辑：

```bash
/etc/systemd/system/ollama.service

```

修改：

```ini
Environment="OLLAMA_HOST=0.0.0.0:11434"

```

重载

```bash
systemctl daemon-reload

systemctl restart ollama

```

验证

```bash
ss -lntp | grep 11434

```

---

# 七、下载模型

例如：

```bash
ollama pull qwen3:8b

```

或

```bash
ollama pull deepseek-r1:8b

```

查看

```bash
ollama list

```

运行

```bash
ollama run qwen3:8b

```

---

# 八、部署 vLLM

推荐Docker方式。

创建目录

```bash
mkdir -p /data/vllm

```

启动

```bash
docker run -d \
--name vllm \
--gpus all \
-p 8000:8000 \
-v /data/models:/models \
vllm/vllm-openai:latest \
--model /models/Qwen3-32B

```

验证

```bash
curl http://127.0.0.1:8000/v1/models

```

返回：

```json
{
  "data":[]
}

```

表示正常。

---

# 九、部署 OpenWebUI

创建目录

```bash
mkdir -p /data/openwebui

```

启动

```bash
docker run -d \
--name open-webui \
--restart always \
-p 3000:8080 \
-v open-webui:/app/backend/data \
-e OLLAMA_BASE_URL=http://IP地址:11434 \
ghcr.io/open-webui/open-webui:main

```

查看

```bash
docker ps

```

访问

```text
http://服务器IP:3000

```

首次访问创建管理员账号。

---

# 十、连接 vLLM

OpenWebUI后台：

```text
Admin Settings
↓
Connections
↓
OpenAI API

```

填写：

```text
URL:
http://服务器IP:8000/v1

API KEY:
EMPTY

```

保存。

---

# 十一、配置 HTTPS

安装 Nginx

```bash
apt install nginx -y

```

配置

```nginx
server {

    listen 443 ssl;
    server_name ai.company.com;

    location / {

        proxy_pass http://127.0.0.1:3000;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;

    }

}

```

重载

```bash
nginx -t

systemctl reload nginx

```

---

# 十二、企业生产环境建议

结合您的运维经验，建议直接使用 Docker Compose 管理。

目录结构：

```text
/data/ai-platform

├── openwebui
├── ollama
├── vllm
├── postgres
├── redis
├── nginx
└── backup

```

推荐增加：

```text
PostgreSQL
Redis
MinIO
OpenWebUI
Ollama
vLLM
Nginx

```

形成完整平台：

```text
OpenWebUI
    │
    ├── Ollama
    │      ├── Qwen3 8B
    │      └── DeepSeek 8B
    │
    └── vLLM
           ├── Qwen3 32B
           ├── Qwen3 72B
           └── DeepSeek-R1

```

对于您公司这种已有 Ubuntu、Docker、Tomcat、MySQL 运维经验的团队，预计 **2~3天即可完成基础平台搭建，1~2周可完成企业知识库和多智能体接入**。后续再增加 Dify 或 MaxKB，即可实现“运维助手、合同助手、知识库助手、写作助手、图片助手”等企业级智能体。

# ubuntu24.04 部署 ragflow + 阿里百炼大模型 + docker ，系统使用阿里源，采用纯cpu 无gpu方案 详细的部署方法1

下面给你一套**在 Ubuntu 24.04（阿里云源）+ Docker + CPU-only（无GPU）环境**部署：

> **RAGFlow + 阿里云百炼（DashScope）大模型接入 + Ollama/可选嵌入模型 + Docker Compose**

这是目前生产里比较稳的一种“CPU RAG方案”。

---

# 一、整体架构（你最终会跑的东西）

你这套系统本质是：

- RAGFlow（RAG框架）
- Elasticsearch（向量/检索）
- Ollama（可选，本地embedding/小模型）
- 阿里百炼 DashScope（LLM 主模型）
- Docker Compose 一键编排

---

# 二、Ubuntu 24.04 基础环境（阿里源优化）

## 1. 替换阿里APT源（建议）

```bash
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo sed -i 's|http://.*ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list
sudo apt update && sudo apt upgrade -y

```

---

## 2. 安装基础依赖

```bash
sudo apt install -y \
  git curl wget vim \
  ca-certificates gnupg lsb-release \
  htop net-tools

```

---

## 3. Docker + Compose（必须24+）

### 安装 Docker（官方方式）

```bash
curl -fsSL https://get.docker.com | bash
sudo usermod -aG docker $USER
newgrp docker

```

### 验证

```bash
docker -v
docker compose version

```

---

## 4. 内核参数（RAGFlow必须）

```bash
sudo sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf

```

---

# 三、部署 RAGFlow（CPU版本）

## 1. 克隆项目

```bash
git clone https://github.com/infiniflow/ragflow.git
cd ragflow

```

---

## 2. 使用 CPU docker-compose

进入 docker 目录：

```bash
cd docker

```

查看 compose：

```bash
ls

```

你会看到类似：

- docker-compose.yml
- .env
- service\_conf.yaml.template

---

## 3. 修改 .env（关键）

打开：

```bash
vim .env

```

重点改这些（CPU模式）：

```env
# CPU模式
RAGFLOW_MODE=cpu

# 端口
RAGFLOW_PORT=80

# 禁用GPU
USE_GPU=false

```

---

## 4. 启动 RAGFlow

```bash
docker compose up -d

```

第一次会拉取：

- Elasticsearch
- RAGFlow backend
- worker
- frontend

---

## 5. 检查状态

```bash
docker ps

```

访问：

```
http://你的服务器IP

```

---

# 四、接入阿里云百炼（DashScope LLM）

这是你最关键的一步。

---

## 1. 获取 API Key

进入阿里云百炼：

- [https://bailian.aliyun.com/](https://bailian.aliyun.com/)

创建：

- API Key（DashScope）

---

## 2. 在 RAGFlow 中配置 LLM

进入 RAGFlow Web UI：

```
Settings → Model Provider → Add Model

```

选择：

> DashScope / Alibaba Cloud

填写：

```text
API Key: sk-xxxx
Base URL: https://dashscope.aliyuncs.com/compatible-mode/v1
Model: qwen-plus 或 qwen-max

```

---

## 3. 推荐模型（CPU RAG稳定）

- qwen-turbo（最快，推荐默认）
- qwen-plus（平衡）
- qwen-max（效果最好，贵）

---

# 五、嵌入模型（CPU方案推荐）

你有两种方式：

---

## 方案A（推荐）：阿里Embedding（省事）

在百炼里选：

```
text-embedding-v3

```

配置：

```
Provider: DashScope
Model: text-embedding-v3

```

---

## 方案B：本地 Ollama（CPU）

安装 Ollama：

```bash
curl -fsSL https://ollama.com/install.sh | sh

```

启动：

```bash
ollama serve

```

拉 embedding：

```bash
ollama pull bge-m3

```

---

### RAGFlow连接 Ollama：

```text
http://host.docker.internal:11434

```

⚠️ CPU机器也能跑，但比阿里 embedding 慢

---

# 六、Docker CPU优化（重要）

编辑：

```bash
docker-compose.yml

```

加：

```yaml
deploy:
  resources:
    limits:
      cpus: "4"
      memory: 8G

```

---

# 七、常见坑（非常重要）

## 1. Elasticsearch 起不来

```bash
vm.max_map_count < 262144

```

解决：

```bash
sudo sysctl -w vm.max_map_count=262144

```

---

## 2. CPU太慢

建议：

- 用 qwen-turbo
- embedding 用 text-embedding-v3
- 不要本地大模型

---

## 3. Docker 内存爆

至少：

- 16GB RAM（最低）
- 推荐 32GB

---

# 八、完整启动流程（总结版）

```bash
# 1. 安装docker
curl -fsSL https://get.docker.com | bash

# 2. clone
git clone https://github.com/infiniflow/ragflow.git
cd ragflow/docker

# 3. 系统参数
sudo sysctl -w vm.max_map_count=262144

# 4. 启动
docker compose up -d

```

---

# 九、推荐生产级组合（CPU最优）

<table id="bkmrk-%E6%A8%A1%E5%9D%97-%E6%96%B9%E6%A1%88-rag%E6%A1%86%E6%9E%B6-ragflow-"><thead><tr><th>模块</th><th>方案</th></tr></thead><tbody><tr><td>RAG框架</td><td>RAGFlow</td></tr><tr><td>LLM</td><td>阿里百炼 qwen-turbo</td></tr><tr><td>Embedding</td><td>text-embedding-v3</td></tr><tr><td>向量</td><td>Elasticsearch</td></tr><tr><td>部署</td><td>Docker Compose</td></tr><tr><td>OS</td><td>Ubuntu 24.04（阿里源）</td></tr></tbody></table>

---

# 如果你要进阶（我可以继续帮你）

我可以再帮你细化这三块：

### 🚀 1. 生产级 docker-compose（含Nginx + HTTPS）

### 🚀 2. RAGFlow + 百炼 prompt 最佳实践（中文知识库优化）

### 🚀 3. Elasticsearch 调优（CPU 低配提速 3-5倍）

只要你说你机器配置（CPU/内存/磁盘），我可以给你一套“可直接上线版本”。

# ubuntu24.04 部署 ragflow + 阿里百炼大模型 + docker ，系统使用阿里源，采用纯cpu 无gpu方案 详细的部署方法2

可以，而且**这是目前企业知识库比较推荐的一种方案**。

你的环境（根据之前的聊天记录）：

- Ubuntu 24.04 LTS
- Docker / Docker Compose
- 纯 CPU（无 GPU）
- 希望使用阿里云百炼（DashScope）作为大模型
- 公司内部知识库
- 后续可能接入 OpenWebUI、Agent、企业智能体

这种情况下**不建议部署 Ollama/vLLM**，因为你已经使用阿里百炼，大模型推理全部走云端 API，本地服务器仅负责：

- RAGFlow
- Elasticsearch
- MySQL
- MinIO
- Redis
- 文档解析
- 向量检索

CPU 即可，8C16G 起步即可运行，小型企业推荐 16C32G。RAGFlow 官方支持通过 Docker Compose 部署，并可配置外部模型服务。([ragflow.com.cn](https://ragflow.com.cn/docs/configurations?utm_source=chatgpt.com "配置 | RAGFlow 引擎"))

---

# 一、整体架构

```
                用户浏览器
                      │
                http://IP:9380
                      │
                ┌────────────┐
                │ RAGFlow UI │
                └─────┬──────┘
                      │
      ┌───────────────┼──────────────┐
      │               │              │
      ▼               ▼              ▼
 Elasticsearch      MySQL         Redis
      │
      ▼
   MinIO(文件)

      │
      ▼

阿里百炼 API
(Qwen3 / Qwen-Max /
Embedding)

```

整个推理流程：

```
上传PDF
↓

RAGFlow解析

↓

Embedding（调用百炼）

↓

ES存向量

↓

提问

↓

检索ES

↓

把上下文发送给百炼

↓

返回答案

```

---

# 二、服务器配置建议

最低配置：

```
CPU：8 Core
内存：16GB
SSD：100GB
Ubuntu24.04

```

推荐：

```
CPU：16 Core
RAM：32GB
SSD：500GB NVMe

```

因为：

- OCR
- PDF解析
- Elasticsearch

都比较吃CPU。

---

# 三、更换Ubuntu阿里源

先备份：

```bash
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak

```

Ubuntu24.04：

```bash
sudo tee /etc/apt/sources.list >/dev/null <<EOF
deb https://mirrors.aliyun.com/ubuntu/ noble main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ noble-updates main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ noble-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu noble-security main restricted universe multiverse
EOF

```

更新：

```bash
sudo apt update
sudo apt upgrade -y

```

---

# 四、安装Docker

```bash
sudo apt install \
docker.io \
docker-compose-v2 \
git \
curl \
wget \
unzip \
vim \
htop \
net-tools \
jq \
-y

```

启动：

```bash
sudo systemctl enable docker

sudo systemctl start docker

```

检查：

```bash
docker version

```

---

# 五、优化Docker镜像源

编辑：

```bash
sudo mkdir -p /etc/docker

```

```bash
sudo vim /etc/docker/daemon.json

```

例如：

```json
{
  "registry-mirrors": [
    "https://docker.m.daocloud.io",
    "https://dockerproxy.com"
  ]
}

```

然后：

```bash
sudo systemctl restart docker

```

---

# 六、下载RAGFlow

```bash
cd /opt

git clone https://github.com/infiniflow/ragflow.git

```

进入：

```bash
cd ragflow/docker

```

官方提供 Docker Compose 和配置模板，可通过 `.env`、`docker-compose.yml`、`service_conf.yaml.template` 调整端口及服务配置。([ragflow.com.cn](https://ragflow.com.cn/docs/configurations?utm_source=chatgpt.com "配置 | RAGFlow 引擎"))

---

# 七、修改.env

例如：

```bash
vim .env

```

建议：

```ini
RAGFLOW_IMAGE=infiniflow/ragflow:latest

SVR_HTTP_PORT=9380

MYSQL_PASSWORD=ragflow123

MINIO_PASSWORD=ragflow123

REDIS_PASSWORD=ragflow123

#如果无法pull启用下行
RAGFLOW_IMAGE=swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:v0.26.1
```

CPU模式：

不用配置

```
CUDA

GPU

NVIDIA

```

全部保持默认。

---

# 八、启动

```bash
docker compose up -d

```

第一次需要下载：

```
ragflow

mysql

redis

minio

elasticsearch

# 逐个拉取，无并发，不会触发请求超限
docker compose pull redis
docker compose pull es01
docker compose pull minio
docker compose pull mysql
docker compose pull ragflow-cpu

```

约4~6GB。

查看：

```bash
docker ps

```

正常会看到：

```
ragflow-server

mysql

redis

minio

es01

```

---

# 九、访问

浏览器：

```
http://服务器IP:9380

```

首次：

```
admin

password

```

（实际以当前镜像默认账号为准，如官方镜像更新请参考发布说明。）

---

# 十、申请阿里百炼API

登录阿里云百炼：

```
https://bailian.console.aliyun.com

```

创建：

```
API Key

```

得到：

```
sk-xxxxxxxx

```

---

# 十一、RAGFlow配置百炼

后台：

```
Model Providers

↓

OpenAI Compatible

```

百炼兼容 OpenAI API，可在 RAGFlow 中配置兼容接口。

填写：

```
Base URL

https://dashscope.aliyuncs.com/compatible-mode/v1

API Key

sk-xxxxxxxx

```

Chat Model 可选择：

```
qwen-max

或者

qwen-plus

或者

qwen3

```

Embedding 推荐：

```
text-embedding-v4

或者官方当前推荐Embedding模型

```

---

# 十二、测试

创建：

```
Knowledge Base

```

上传：

```
PDF

Word

Excel

TXT

```

等待：

```
Parsing...

Embedding...

Completed

```

然后：

```
Chat

```

提问：

```
公司的请假制度是什么？

```

流程：

```
ES

↓

召回TopK

↓

发送百炼

↓

回答

```

---

# 十三、CPU部署建议

建议：

```
Document Parser

4线程

```

Worker：

```
2

```

不要：

```
16线程

32线程

```

否则 ES 会占满 CPU。

---

# 十四、生产环境建议

建议将数据目录映射到宿主机：

```
/data/ragflow/

├── mysql
├── redis
├── minio
├── elasticsearch
├── logs
└── ragflow

```

这样容器升级时数据不会丢失。

建议每天备份：

```
MySQL

MinIO

ES Snapshot

```

---

## 十五、针对你的企业场景的推荐架构

结合你之前提到的目标（企业 AI 平台、多个专业智能体、Ubuntu + Docker、自建运维），我更建议采用下面这套统一架构：

```
Ubuntu24.04
│
├── Docker
│
├── RAGFlow（企业知识库）
│
├── Open WebUI（统一聊天入口）
│
├── Nginx（反向代理）
│
├── Redis
│
├── Elasticsearch
│
├── MySQL
│
├── MinIO
│
└── 阿里百炼
      ├── Qwen3
      ├── Qwen-Max
      └── Embedding

```

这种方案的优点是：

- **服务器无需 GPU**，降低硬件成本。
- **所有模型能力由阿里百炼提供**，无需维护本地模型。
- 后续可以继续接入 **Open WebUI、MCP、Agent、企业微信/钉钉** 等组件，形成统一的企业 AI 平台，而无需更换底层架构。

# 把 Keycloak + AD + RAGFlow 做成“可生产部署版本

很好，你现在这个需求已经是**标准企业级SSO架构落地设计**了，我给你一套可以直接生产用的方案（不是demo，是能稳定跑的）。

目标是：

> ✔ Keycloak 统一认证中心  
> ✔ Windows AD（shuncom.local）作为用户源  
> ✔ RAGFlow Docker单机接入OIDC登录  
> ✔ 一套可维护、可扩展的企业架构

---

# 🧠 一、整体生产架构（必须先理解）

```text
Windows AD (192.168.0.5)
        │ LDAP
        ▼
Keycloak（SSO中心 / Identity Broker）
        │ OIDC / OAuth2
        ▼
RAGFlow（Docker单机）

```

---

# 🏗️ 二、生产级部署拓扑（推荐）

你现在服务器是：

- Ubuntu 24.04
- RAGFlow Docker 单机 ✔

建议增加：

<table id="bkmrk-%E6%9C%8D%E5%8A%A1-%E8%AF%B4%E6%98%8E-keycloak-iam%E8%AE%A4%E8%AF%81"><thead><tr><th>服务</th><th>说明</th></tr></thead><tbody><tr><td>Keycloak</td><td>IAM认证中心</td></tr><tr><td>PostgreSQL</td><td>Keycloak数据库</td></tr><tr><td>RAGFlow</td><td>业务系统</td></tr><tr><td>AD</td><td>用户源</td></tr></tbody></table>

---

# 🚀 三、一键生产级 docker-compose（Keycloak + DB）

## ✔ 新建目录

```bash
mkdir -p /opt/sso
cd /opt/sso

```

---

## ✔ docker-compose.yml（生产推荐版）

```yaml
version: '3.8'

services:

  postgres:
    image: postgres:15
    container_name: keycloak-db
    restart: always
    environment:
      POSTGRES_DB: keycloak
      POSTGRES_USER: keycloak
      POSTGRES_PASSWORD: keycloak123
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks:
      - sso-net

  keycloak:
    image: quay.io/keycloak/keycloak:24.0
    container_name: keycloak
    restart: always
    command: start-dev
    environment:
      KEYCLOAK_ADMIN: admin
      KEYCLOAK_ADMIN_PASSWORD: admin123

      KC_DB: postgres
      KC_DB_URL_HOST: postgres
      KC_DB_URL_DATABASE: keycloak
      KC_DB_USERNAME: keycloak
      KC_DB_PASSWORD: keycloak123

      KC_HOSTNAME: 192.168.4.16
      KC_HTTP_ENABLED: "true"
      KC_PROXY: edge

    ports:
      - "8081:8080"

    depends_on:
      - postgres

    networks:
      - sso-net

volumes:
  pgdata:

networks:
  sso-net:

```

---

## ✔ 启动

```bash
docker compose up -d

```

---

# 🔐 四、Keycloak对接 AD（shuncom.local）

进入：

```
http://192.168.4.16:8081

```

---

## ✔ 创建 LDAP

路径：

```
User Federation → LDAP

```

---

## ✔ 配置（关键参数）

<table id="bkmrk-%E9%A1%B9%E7%9B%AE-%E5%80%BC-vendor-active-d"><thead><tr><th>项目</th><th>值</th></tr></thead><tbody><tr><td>Vendor</td><td>Active Directory</td></tr><tr><td>Connection URL</td><td>ldap://192.168.0.5</td></tr><tr><td>Bind DN</td><td>CN=Administrator,CN=Users,DC=shuncom,DC=local</td></tr><tr><td>Bind Password</td><td>AD密码</td></tr><tr><td>Users DN</td><td>DC=shuncom,DC=local</td></tr><tr><td>Username LDAP attribute</td><td>sAMAccountName</td></tr></tbody></table>

---

## ✔ 开启

- Import Users = ON
- Sync Registrations = ON
- Trust Email = ON（可选）

---

## ✔ 测试

点击：

```
Test connection
Test authentication

```

必须全部 ✔

---

# 🔑 五、创建 RAGFlow Client（OIDC）

Keycloak：

```
Clients → Create

```

---

## ✔ 配置

<table id="bkmrk-%E9%A1%B9%E7%9B%AE-%E5%80%BC-client-id-ragfl"><thead><tr><th>项目</th><th>值</th></tr></thead><tbody><tr><td>Client ID</td><td>ragflow</td></tr><tr><td>Protocol</td><td>openid-connect</td></tr><tr><td>Access Type</td><td>confidential</td></tr></tbody></table>

---

## ✔ Redirect URI（非常关键）

```text
http://192.168.4.16:9380/*

```

---

## ✔ 获取 Secret

```
Credentials → Client Secret

```

---

# 🧩 六、RAGFlow Docker 配置（关键）

修改你的 `.env`：

```env
AUTH_TYPE=oauth2

OAUTH_PROVIDER=keycloak
OAUTH_CLIENT_ID=ragflow
OAUTH_CLIENT_SECRET=xxxxxxxx

OAUTH_AUTH_URL=http://192.168.4.16:8081/realms/shuncom/protocol/openid-connect/auth
OAUTH_TOKEN_URL=http://192.168.4.16:8081/realms/shuncom/protocol/openid-connect/token
OAUTH_USERINFO_URL=http://192.168.4.16:8081/realms/shuncom/protocol/openid-connect/userinfo

OAUTH_REDIRECT_URI=http://192.168.4.16:9380/oauth/callback

```

---

# 🔄 七、完整登录流程

```text
用户访问 RAGFlow
        ↓
跳转 Keycloak
        ↓
输入 AD账号密码
        ↓
Keycloak LDAP验证 AD
        ↓
返回 Token
        ↓
RAGFlow登录成功

```

---

# ⚠️ 八、生产级关键优化（非常重要）

## ✔ 1. 时间同步（必须）

```bash
timedatectl set-ntp true

```

---

## ✔ 2. Keycloak必须固定hostname

```env
KC_HOSTNAME=192.168.4.16
KC_PROXY=edge

```

---

## ✔ 3. 防止回调失败（常见坑）

确认：

- 9380端口开放
- firewall关闭或放行

---

## ✔ 4. AD账号映射策略

建议：

<table id="bkmrk-ad%E5%AD%97%E6%AE%B5-keycloak-samacc"><thead><tr><th>AD字段</th><th>Keycloak</th></tr></thead><tbody><tr><td>sAMAccountName</td><td>username</td></tr><tr><td>mail</td><td>email</td></tr></tbody></table>

---

# 🧱 九、生产级增强（可选但推荐）

如果你要企业级：

### 🔥 1. AD Group → RAGFlow Role映射

### 🔥 2. 多系统SSO（GitLab / Jenkins）

### 🔥 3. Keycloak HA（双机）

### 🔥 4. LDAP Failover

---

# 🧠 十、最终推荐架构（最佳实践）

```text
        Windows AD
             │
             ▼
        Keycloak (SSO)
             │
     ┌───────┼────────┐
     ▼       ▼        ▼
 RAGFlow   GitLab   Jenkins

```

---

# 🚨 十一、你当前最容易踩的坑（提前提醒）

1. ❌ Keycloak没数据库（你之前已经踩过）
2. ❌ 没 start-dev
3. ❌ Redirect URI写错
4. ❌ AD LDAP Bind DN错误
5. ❌ 时间不同步导致token失败

---

# 🚀 如果你下一步要继续，我可以帮你做：

### ✔ Keycloak + AD 完整可运行配置（可复制）

### ✔ RAGFlow OIDC 一键配置文件

### ✔ Nginx HTTPS + SSO反代

### ✔ 企业统一登录架构图（含权限设计）

只要你说一句：

👉 **“我要生产级SSO完整落地”**

我可以直接给你一套“复制就能跑”的最终版本。

# 企业级 AD + Keycloak + RAGFlow 完整闭环

很好，这一步就是**企业级 AD + Keycloak + RAGFlow 完整闭环**了，我给你一套可以直接落地的标准方案（生产可用）。

---

# 一、目标架构（最终形态）

```text
Windows AD (192.168.0.5)
        │ LDAP / LDAPS
        ▼
   Keycloak（身份中台）
        │ OIDC
        ▼
   RAGFlow（自动建用户 + 角色映射）

```

---

# 二、你要实现的3个能力

必须同时完成：

## ✔ 1. AD用户自动同步

## ✔ 2. 首次登录自动创建RAGFlow用户

## ✔ 3. AD Group → RAGFlow Role 映射

---

# 三、Keycloak 配置（核心）

## 1️⃣ LDAP 接入 AD

进入：

```
User Federation → LDAP

```

配置：

<table id="bkmrk-%E5%8F%82%E6%95%B0-%E5%80%BC-vendor-active-d"><thead><tr><th>参数</th><th>值</th></tr></thead><tbody><tr><td>Vendor</td><td>Active Directory</td></tr><tr><td>Connection URL</td><td>ldap://192.168.0.5:389</td></tr><tr><td>Bind DN</td><td>CN=ldapbind,OU=ServiceAccounts,DC=shuncom,DC=local</td></tr><tr><td>Bind Credential</td><td>\*\*\*\*\*\*</td></tr><tr><td>Users DN</td><td>DC=shuncom,DC=local</td></tr><tr><td>Import Users</td><td>✔ ON</td></tr><tr><td>Edit Mode</td><td>READ\_ONLY</td></tr></tbody></table>

---

# 四、关键：开启“自动用户导入”

在 LDAP 设置中：

## ✔ 必须开启：

```text
Import Users = ON

```

否则不会同步 AD 用户

---

# 五、Keycloak Role / Group 映射（关键步骤）

---

## 2️⃣ 创建 Mapper（重点）

进入：

```
LDAP → Mappers

```

新增：

---

### ✔ Mapper 1：用户名

<table id="bkmrk-name-value-ldap-attr"><thead><tr><th>Name</th><th>value</th></tr></thead><tbody><tr><td>ldap attribute</td><td>sAMAccountName</td></tr><tr><td>user attribute</td><td>username</td></tr></tbody></table>

---

### ✔ Mapper 2：邮箱

| LDAP | mail |  
| RAGFlow | email |

---

### ✔ Mapper 3：AD Group → Keycloak Group

<table id="bkmrk-mapper-type-group-ld"><thead><tr><th>Mapper Type</th><th>group-ldap-mapper</th></tr></thead><tbody><tr><td>Groups DN</td><td>OU=Groups,DC=shuncom,DC=local</td></tr><tr><td>Membership attribute</td><td>member</td></tr></tbody></table>

---

# 六、Keycloak → RAGFlow 角色映射

---

## 3️⃣ 在 Keycloak 创建 Realm Roles

例如：

- ragflow-admin
- ragflow-user
- ragflow-reader

---

## 4️⃣ Group → Role 映射

Keycloak：

```
Group → Role Mapping

```

示例：

<table id="bkmrk-ad-group-ragflow-rol"><thead><tr><th>AD Group</th><th>RAGFlow Role</th></tr></thead><tbody><tr><td>IT\_Admin</td><td>ragflow-admin</td></tr><tr><td>AI\_User</td><td>ragflow-user</td></tr></tbody></table>

---

# 七、RAGFlow 配置（关键修改）

你现在 docker-compose 需要改这几个：

---

## ✔ 1. 改用户ID来源（非常关键）

```bash
OAUTH2_USER_ID_CLAIM=email

```

❗不要用 sub

---

## ✔ 2. 开启自动注册（关键）

```bash
REGISTER_ENABLED=1

```

---

## ✔ 3. 保留 OIDC

```bash
OAUTH2_ENABLE=True
OAUTH2_TYPE=oidc

```

---

## ✔ 4. 建议补充（重要）

```bash
OAUTH2_AUTO_CREATE_USER=true

```

（如果版本支持）

---

# 八、RAGFlow 角色映射方式（核心）

RAGFlow 本身是靠 OIDC claims：

你需要在 Keycloak 加：

---

## 5️⃣ Client Mapper（重点）

进入：

```
Client → ragflow → Mappers

```

添加：

---

### ✔ Mapper 1：roles

<table id="bkmrk-name-roles-mapper-ty"><thead><tr><th>Name</th><th>roles</th></tr></thead><tbody><tr><td>Mapper Type</td><td>User Realm Role</td></tr><tr><td>Token Claim Name</td><td>roles</td></tr><tr><td>Add to ID token</td><td>ON</td></tr><tr><td>Add to access token</td><td>ON</td></tr></tbody></table>

---

### ✔ Mapper 2：groups

<table id="bkmrk-name-groups-mapper-t"><thead><tr><th>Name</th><th>groups</th></tr></thead><tbody><tr><td>Mapper Type</td><td>Group Membership</td></tr><tr><td>Token Claim</td><td>groups</td></tr></tbody></table>

---

# 九、RAGFlow 侧角色识别

RAGFlow 会读取：

```json
{
  "email": "8108@shuncom.local",
  "groups": ["AI_User"],
  "roles": ["ragflow-user"]
}

```

---

# 十、用户自动创建逻辑（关键机制）

当用户第一次登录：

```text
Keycloak 登录成功
        ↓
RAGFlow 收到 email
        ↓
检查用户是否存在
        ↓
不存在 → 自动创建
        ↓
绑定 role/group

```

---

# 十一、你必须改的最终配置（直接可用）

## docker-compose.yml（最终建议）

```yaml
environment:
  - OAUTH2_ENABLE=True
  - OAUTH2_TYPE=oidc
  - OAUTH2_DISPLAY_NAME=AD域账号登录

  - OAUTH2_AUTHORIZATION_URL=http://192.168.4.16:8081/realms/shuncom/protocol/openid-connect/auth
  - OAUTH2_TOKEN_URL=http://192.168.4.16:8081/realms/shuncom/protocol/openid-connect/token
  - OAUTH2_USERINFO_URL=http://192.168.4.16:8081/realms/shuncom/protocol/openid-connect/userinfo

  - OAUTH2_CLIENT_ID=ragflow
  - OAUTH2_CLIENT_SECRET=xxxx

  - OAUTH2_REDIRECT_URI=http://192.168.4.16/oauth/callback

  - OAUTH2_USER_ID_CLAIM=email
  - REGISTER_ENABLED=1

```

---

# 十二、最终效果（你会得到）

## ✔ AD账号登录RAGFlow

## ✔ 首次登录自动创建用户

## ✔ AD组自动映射权限

## ✔ Keycloak统一身份中心

## ✔ RAGFlow无需本地维护账号

---

# 十三、如果你要更进一步（推荐升级）

我可以帮你再升级成：

### ✔ AD组 → RAGFlow菜单权限控制

### ✔ 多租户隔离（部门级权限）

### ✔ 自动禁用离职AD用户

### ✔ LDAP双向同步

### ✔ HTTPS + 企业SSO统一入口

只需要说一句：

> “升级成企业级SSO完整方案”

我可以给你一套**生产环境标准架构（含Keycloak导入模板 + LDAP配置 + RAGFlow最终docker-compose）**。

# 业级 SSO（AD → Keycloak → RAGFlow）完整生产方案

下面给你一套**企业级 SSO（AD → Keycloak → RAGFlow）完整生产方案**，目标是：

> ✔ AD账号即开即用登录  
> ✔ 自动创建RAGFlow用户  
> ✔ AD组 → 角色 → 权限全映射  
> ✔ 支持离职禁用、权限收敛  
> ✔ 可扩展多系统统一SSO

我按“可落地生产标准”给你拆 4 层架构。

---

# 一、企业级最终架构（标准模型）

```text
            ┌────────────────────────┐
            │ Windows AD             │
            │ 192.168.0.5            │
            └─────────┬──────────────┘
                      │ LDAP/LDAPS
                      ▼
            ┌────────────────────────┐
            │ Keycloak (SSO中台)     │
            │ 192.168.4.16:8081      │
            │                        │
            │ ✔ 用户同步             │
            │ ✔ Group管理           │
            │ ✔ Token签发           │
            └─────────┬──────────────┘
                      │ OIDC
      ┌───────────────┼────────────────┐
      ▼               ▼                ▼
 RAGFlow         其他AI系统        运维平台
 (你的系统)

```

---

# 二、整体能力设计（企业级必须具备）

## ✔ 身份层（Identity）

- AD 作为唯一身份源
- Keycloak 做统一身份中心

## ✔ 认证层（Authentication）

- OIDC（标准 OAuth2）
- Token JWT

## ✔ 授权层（Authorization）

- AD Group → Keycloak Role
- Role → RAGFlow 权限

## ✔ 用户生命周期（关键）

- 自动创建用户
- 自动禁用离职账号
- 自动同步组织架构

---

# 三、Keycloak 企业级配置（核心）

---

## 1️⃣ LDAP 接入 AD（生产级配置）

```text
User Federation → LDAP

```

### 核心参数

<table id="bkmrk-%E9%A1%B9%E7%9B%AE-%E5%80%BC-vendor-active-d"><thead><tr><th>项目</th><th>值</th></tr></thead><tbody><tr><td>Vendor</td><td>Active Directory</td></tr><tr><td>Connection URL</td><td>ldap://192.168.0.5:389</td></tr><tr><td>Bind DN</td><td>CN=ldapbind,OU=ServiceAccounts,DC=shuncom,DC=local</td></tr><tr><td>Users DN</td><td>DC=shuncom,DC=local</td></tr><tr><td>Import Users</td><td>✔ ON</td></tr><tr><td>Sync Registrations</td><td>✔ ON</td></tr><tr><td>Edit Mode</td><td>READ\_ONLY</td></tr></tbody></table>

---

## 2️⃣ 用户同步策略（企业关键）

```text
Periodic Full Sync: 1h
Periodic Changed Users Sync: 10min

```

---

## 3️⃣ 必须开启：用户自动导入

```text
Import Users = ON

```

---

# 四、AD Group → 权限体系（核心设计）

---

## 3️⃣ AD组织结构示例

```text
IT_Admins
AI_Users
AI_ReadOnly
Security_Team

```

---

## 4️⃣ Keycloak Group 映射

LDAP Mapper：

- group-ldap-mapper
- memberOf

---

## 5️⃣ 映射关系设计

<table id="bkmrk-ad-group-keycloak-ro"><thead><tr><th>AD Group</th><th>Keycloak Role</th><th>RAGFlow权限</th></tr></thead><tbody><tr><td>IT\_Admins</td><td>ragflow-admin</td><td>全权限</td></tr><tr><td>AI\_Users</td><td>ragflow-user</td><td>创建/查询</td></tr><tr><td>AI\_ReadOnly</td><td>ragflow-reader</td><td>只读</td></tr></tbody></table>

---

# 五、Keycloak → Token 设计（非常关键）

---

## 6️⃣ Client Mapper（必须配置）

Client：ragflow

### Mapper 1：email（用户唯一ID）

```text
email → email

```

---

### Mapper 2：groups（关键）

```text
groups → groups

```

---

### Mapper 3：roles

```text
realm roles → roles

```

---

### Token最终结构：

```json
{
  "email": "8108@shuncom.local",
  "groups": ["AI_Users"],
  "roles": ["ragflow-user"]
}

```

---

# 六、RAGFlow 企业级配置（核心）

---

## 7️⃣ docker-compose 关键配置

你必须统一成下面结构：

```yaml
environment:
  - AUTH_TYPE=oauth2
  - OAUTH2_ENABLE=True
  - OAUTH2_TYPE=oidc

  - OAUTH2_AUTHORIZATION_URL=http://192.168.4.16:8081/realms/shuncom/protocol/openid-connect/auth
  - OAUTH2_TOKEN_URL=http://192.168.4.16:8081/realms/shuncom/protocol/openid-connect/token
  - OAUTH2_USERINFO_URL=http://192.168.4.16:8081/realms/shuncom/protocol/openid-connect/userinfo

  - OAUTH2_CLIENT_ID=ragflow
  - OAUTH2_CLIENT_SECRET=xxxx

  - OAUTH2_REDIRECT_URI=http://192.168.4.16/oauth/callback

  # ⭐关键
  - OAUTH2_USER_ID_CLAIM=email
  - REGISTER_ENABLED=1
  - AUTO_CREATE_USER=true

```

---

# 七、RAGFlow 权限模型设计（企业级重点）

---

## 8️⃣ 权限结构

RAGFlow 用户：

```text
User
 ├── role
 │    ├── admin
 │    ├── user
 │    └── reader
 ├── group
 │    ├── AI_Users
 │    └── IT_Admins

```

---

## 9️⃣ 绑定规则

<table id="bkmrk-keycloak%E5%AD%97%E6%AE%B5-ragflow%E6%98%A0%E5%B0%84"><thead><tr><th>Keycloak字段</th><th>RAGFlow映射</th></tr></thead><tbody><tr><td>groups</td><td>role group</td></tr><tr><td>roles</td><td>permission</td></tr><tr><td>email</td><td>user identity</td></tr></tbody></table>

---

# 八、自动用户创建机制（核心能力）

---

## 10️⃣ 登录流程

```text
AD登录
 ↓
Keycloak认证
 ↓
返回JWT
 ↓
RAGFlow解析 email
 ↓
查用户表
 ↓
不存在 → 自动创建
 ↓
绑定 role/group

```

---

# 九、企业级增强能力（强烈建议）

---

## ✔ 1. 离职自动禁用

Keycloak LDAP：

```text
User Disabled = AD disabled

```

---

## ✔ 2. 权限自动收敛

用户离开 AD group → 自动降权

---

## ✔ 3. 多系统SSO扩展

同一 Keycloak：

- RAGFlow
- Jenkins
- GitLab
- 运维平台
- 内部AI Agent

---

## ✔ 4. HTTPS（必须）

生产必须加：

```text
Nginx + SSL

```

---

# 十、推荐生产部署拓扑（最终版）

```text
                ┌──────────────┐
                │  Nginx HTTPS │
                └──────┬───────┘
                       │
        ┌──────────────┴──────────────┐
        │                             │
   RAGFlow UI                    Keycloak
   192.168.4.16                 192.168.4.16:8081
        │                             │
        └──────────────┬──────────────┘
                       │ LDAP
                 Windows AD
              192.168.0.5

```

---

# 十一、你当前系统升级完成后能力

你会得到：

## ✔ 企业统一账号登录

## ✔ AD账号即开即用

## ✔ 自动用户创建

## ✔ AD组自动权限映射

## ✔ 多系统SSO统一

## ✔ 无本地账号维护

## ✔ 支持组织架构同步

---

# 十二、如果你下一步要继续升级（我可以帮你做）

我可以继续帮你做更高级企业能力：

### ✔ AD组织架构自动同步到RAGFlow空间

### ✔ 多租户隔离（部门级AI空间）

### ✔ API级RBAC权限控制

### ✔ 审计日志 + 登录追踪

### ✔ LDAP双向同步（写回AD）

只要你说一句：

> “升级多租户+权限审计”

我可以帮你把这一套直接升级成**完整企业AI平台身份体系**。

# 可落地的 RAGFlow v0.26.x + Keycloak + AD（LDAP）企业级 SSO 标准架构部署方案

下面给你一套**可落地的 RAGFlow v0.26.x + Keycloak + AD（LDAP）企业级 SSO 标准架构部署方案**。这套是按“生产可用”设计的，不是 demo。

我会直接按你当前环境（Docker + 同机 Keycloak + AD 已同步）给出完整结构。

---

# 🧱 一、目标架构（企业级标准）

```text
                ┌──────────────┐
                │   Browser    │
                └──────┬───────┘
                       │
                       ▼
            ┌────────────────────┐
            │   RAGFlow Web UI   │
            └────────┬───────────┘
                     │
                     ▼
        ┌──────────────────────────┐
        │   RAGFlow API Gateway    │  ← ★核心（你现在缺的）
        │   /api /auth /oauth      │
        └───────┬───────────┬──────┘
                │           │
                ▼           ▼
        Worker/CPU      Keycloak (OIDC)
                          │
                          ▼
                        AD/LDAP

```

---

# 🧨 二、你当前问题总结（必须先修）

你现在只有：

```text
ragflow-cpu（worker/adminserver）

```

缺少：

```text
❌ ragflow-api（SSO入口）
❌ ragflow-web（UI正确版本）

```

👉 所以你所有 OAUTH2 配置都不会生效

---

# 🧩 三、完整 docker-compose（企业版）

下面是**可用标准结构（重点）**

---

## 📦 1. 基础服务

```yaml
version: "3.9"

services:

  mysql:
    image: mysql:8.0
    container_name: ragflow-mysql
    environment:
      MYSQL_ROOT_PASSWORD: ragflow
      MYSQL_DATABASE: ragflow
    volumes:
      - ./data/mysql:/var/lib/mysql

  redis:
    image: redis:7
    container_name: ragflow-redis

  elasticsearch:
    image: elasticsearch:8.11.3
    container_name: ragflow-es
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
    volumes:
      - ./data/es:/usr/share/elasticsearch/data

  minio:
    image: minio/minio
    container_name: ragflow-minio
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: minio
      MINIO_ROOT_PASSWORD: minio123456
    ports:
      - "9000:9000"
      - "9001:9001"

```

---

## 🚀 2. RAGFlow API（关键）

```yaml
  ragflow-api:
    image: swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:v0.26.1
    container_name: ragflow-api
    command: ["./entrypoint.sh", "--api-server"]
    depends_on:
      - mysql
      - redis
      - elasticsearch
    environment:
      - DB_HOST=mysql
      - REDIS_HOST=redis
      - ES_HOST=elasticsearch
      - MINIO_HOST=minio

```

---

## 🖥️ 3. RAGFlow Web UI

```yaml
  ragflow-web:
    image: swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow-web:v0.26.1
    container_name: ragflow-web
    ports:
      - "80:80"
    depends_on:
      - ragflow-api

```

---

## ⚙️ 4. Worker（你现在这个）

```yaml
  ragflow-worker:
    image: swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:v0.26.1
    container_name: ragflow-worker
    command: ["./entrypoint.sh", "--worker"]
    depends_on:
      - ragflow-api

```

---

# 🔐 四、Keycloak 企业级配置（重点）

---

## 1️⃣ Client 配置

Client ID：

```text
ragflow

```

Settings：

- Client type: OpenID Connect
- Access type: confidential
- Standard flow: ON
- Direct access: OFF

---

## 2️⃣ Redirect URI（必须）

```text
http://192.168.4.16/oauth/callback
http://192.168.4.16/*

```

---

## 3️⃣ Mapper（关键）

必须添加：

<table id="bkmrk-name-mapper-username"><thead><tr><th>Name</th><th>Mapper</th></tr></thead><tbody><tr><td>username</td><td>preferred\_username</td></tr><tr><td>email</td><td>email</td></tr><tr><td>groups</td><td>group membership</td></tr></tbody></table>

---

## 4️⃣ Scope

必须：

```text
openid email profile

```

---

# ⚙️ 五、RAGFlow API SSO配置（核心）

在 **ragflow-api**：

```yaml
environment:
  - OAUTH2_ENABLE=true
  - OAUTH2_TYPE=oidc
  - OAUTH2_DISPLAY_NAME=AD域登录
  - OAUTH2_CLIENT_ID=ragflow
  - OAUTH2_CLIENT_SECRET=xxxx

  - OAUTH2_METADATA_URL=http://192.168.4.16:8081/realms/shuncom/.well-known/openid-configuration

  - OAUTH2_REDIRECT_URI=http://192.168.4.16/oauth/callback

  - OAUTH2_SCOPES=openid email profile

  # ⭐关键
  - OAUTH2_USER_ID_CLAIM=preferred_username

  # 自动建用户
  - OAUTH2_AUTO_CREATE_USER=true
  - REGISTER_ENABLED=1

```

---

# 🧠 六、关键修复点（你之前全部踩坑）

## ❌ 错误1：用 worker 容器做 SSO

✔ 正确：SSO 在 API，不在 worker

---

## ❌ 错误2：email 作为 user\_id

✔ 正确：

```text
preferred_username

```

---

## ❌ 错误3：缺 API gateway

✔ 必须有：

```text
/ api / auth / oauth endpoints

```

---

# 🌐 七、验证是否成功

---

## 1️⃣ API是否正常

```bash
curl http://192.168.4.16/api/health

```

---

## 2️⃣ OIDC provider

```bash
curl http://192.168.4.16/api/auth/providers

```

---

## 3️⃣ Keycloak redirect

访问：

```text
http://192.168.4.16

```

应该看到：

- 本地登录
- ⭐ AD域账号登录按钮

---

# 🔥 八、企业级增强（推荐）

---

## 1️⃣ 自动角色映射（RBAC）

Keycloak groups → RAGFlow roles：

```text
AD Group → Keycloak Group → RAGFlow Role

```

---

## 2️⃣ 自动部门隔离

```text
group = IT / Finance / Ops

```

---

## 3️⃣ 审计日志

开启：

- login logs
- token logs
- API logs

---

# 🧨 九、你当前必须做的事（非常重要）

你现在不要再调：

- ❌ OAUTH2参数
- ❌ Keycloak
- ❌ AD

👉 先做：

## 🚨 补齐 RAGFlow API 层

否则所有 SSO 都是无效的

---

# 📌 十、如果你要我帮你下一步升级

我可以继续帮你做三件更高级的：

### 🔐 1. AD → Keycloak 自动同步（含OU映射）

### 🔐 2. Keycloak → RAGFlow RBAC自动绑定

### 🔐 3. 多租户 + 部门级权限隔离

### 🔐 4. 一键 docker-compose 企业版（可直接生产）

只要你说一句：

> “升级企业级SSO+RBAC”

我可以给你一套**可以直接上线生产的版本（含全部yaml + keycloak导入文件）**。

# 可以直接落地生产的 RAGFlow + Keycloak + AD + RBAC 企业级 SSO 方案

下面给你一套**可以直接落地生产的 RAGFlow + Keycloak + AD + RBAC 企业级 SSO 方案**，重点是：**不仅能登录，还能做到“按组分权 + 自动建用户 + 权限隔离”**。

我按“可直接部署”为标准给你，不讲概念，全部是结构级配置。

---

# 🧱 一、企业级目标架构（最终形态）

```text
                 ┌──────────────┐
                 │   Browser    │
                 └──────┬───────┘
                        │
                        ▼
              ┌──────────────────┐
              │   RAGFlow Web    │
              └────────┬─────────┘
                       │
                       ▼
        ┌────────────────────────────┐
        │     RAGFlow API Gateway    │
        │  Auth + RBAC + User Mgmt   │
        └───────┬───────────┬────────┘
                │           │
                ▼           ▼
         Keycloak        RAGFlow Worker
            │
            ▼
         AD (LDAP)

```

---

# 🔐 二、企业级核心能力

你这套方案实现：

## ✔ SSO能力

- Keycloak OIDC 登录
- AD 用户同步登录
- 自动创建本地用户

## ✔ RBAC能力

- AD Group → Keycloak Group → RAGFlow Role
- 自动权限映射

## ✔ 多层权限控制

- Tenant（租户级）
- Department（部门级）
- Role（功能级）

## ✔ 审计能力

- 登录日志
- token审计
- API调用记录

---

# 🧩 三、完整 docker-compose（企业生产版）

---

## 1️⃣ 基础依赖

```yaml
services:

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: ragflow
      MYSQL_DATABASE: ragflow
    volumes:
      - ./data/mysql:/var/lib/mysql

  redis:
    image: redis:7

  elasticsearch:
    image: elasticsearch:8.11.3
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false

  minio:
    image: minio/minio
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: minio
      MINIO_ROOT_PASSWORD: minio123456

```

---

## 2️⃣ RAGFlow API（核心SSO+RBAC）

```yaml
  ragflow-api:
    image: swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:v0.26.1
    container_name: ragflow-api

    command: ["./entrypoint.sh", "--api-server"]

    depends_on:
      - mysql
      - redis
      - elasticsearch
      - minio

    environment:

      # =========================
      # 基础服务
      # =========================
      - DB_HOST=mysql
      - REDIS_HOST=redis
      - ES_HOST=elasticsearch
      - MINIO_HOST=minio

      # =========================
      # SSO（OIDC）
      # =========================
      - OAUTH2_ENABLE=true
      - OAUTH2_TYPE=oidc
      - OAUTH2_DISPLAY_NAME=AD域登录

      - OAUTH2_CLIENT_ID=ragflow
      - OAUTH2_CLIENT_SECRET=xxxxxx

      - OAUTH2_METADATA_URL=http://192.168.4.16:8081/realms/shuncom/.well-known/openid-configuration

      - OAUTH2_REDIRECT_URI=http://192.168.4.16/oauth/callback

      - OAUTH2_SCOPES=openid email profile

      # ⭐关键：统一身份
      - OAUTH2_USER_ID_CLAIM=preferred_username

      # 自动建用户
      - OAUTH2_AUTO_CREATE_USER=true
      - REGISTER_ENABLED=1

      # =========================
      # RBAC映射（关键）
      # =========================
      - OAUTH2_GROUP_CLAIM=groups
      - OAUTH2_ROLE_MAPPING_ENABLED=true

```

---

## 3️⃣ RAGFlow Web

```yaml
  ragflow-web:
    image: swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow-web:v0.26.1
    ports:
      - "80:80"
    depends_on:
      - ragflow-api

```

---

## 4️⃣ Worker

```yaml
  ragflow-worker:
    image: swr.cn-north-4.myhuaweicloud.com/infiniflow/ragflow:v0.26.1
    command: ["./entrypoint.sh", "--worker"]
    depends_on:
      - ragflow-api

```

---

# 🔐 四、Keycloak 企业级配置（重点）

---

## 1️⃣ Client（ragflow）

```text
Client ID: ragflow
Type: OpenID Connect
Access Type: confidential
Standard Flow: ON

```

---

## 2️⃣ Redirect URI

```text
http://192.168.4.16/oauth/callback
http://192.168.4.16/*

```

---

## 3️⃣ Scope

```text
openid email profile groups

```

---

## 4️⃣ Mapper（必须）

### 用户基础信息

<table id="bkmrk-mapper-value-preferr"><thead><tr><th>Mapper</th><th>Value</th></tr></thead><tbody><tr><td>preferred\_username</td><td>username</td></tr><tr><td>email</td><td>email</td></tr></tbody></table>

---

### ⭐关键：RBAC group mapper

```text
Mapper Type: Group Membership
Token Claim Name: groups
Full group path: OFF
Add to ID token: ON
Add to access token: ON

```

---

# 🧠 五、AD（LDAP）对接 Keycloak

---

## LDAP 配置

```text
Vendor: Active Directory
Connection URL: ldap://192.168.x.x:389
Bind DN: CN=admin,CN=Users,DC=xxx,DC=local
Bind Credential: ****
Users DN: CN=Users,DC=xxx,DC=local

```

---

## 同步策略

- Import Users: ON
- Sync Registrations: ON
- Periodic Sync: ON

---

# 🧩 六、RBAC 权限设计（核心）

---

## 1️⃣ AD Group 设计

```text
IT-Admin
IT-User
Finance-User
Ops-User

```

---

## 2️⃣ Keycloak Group 同步

```text
AD Group → Keycloak Group

```

---

## 3️⃣ RAGFlow Role 映射

```text
IT-Admin → admin
IT-User → power_user
Finance → finance_user
Ops → ops_user

```

---

# 🔥 七、权限控制效果

---

## 登录后自动：

### ✔ 用户自动创建

```text
preferred_username = AD账号

```

---

### ✔ 自动分组

```text
groups = ["IT-Admin"]

```

---

### ✔ 自动权限

```text
role = admin

```

---

# 🧪 八、验证清单（必须逐项检查）

---

## 1️⃣ SSO按钮

```text
登录页必须出现：AD域登录

```

---

## 2️⃣ Keycloak token

必须包含：

```json
{
  "preferred_username": "xxx",
  "email": "xxx",
  "groups": ["IT-Admin"]
}

```

---

## 3️⃣ API验证

```bash
curl http://192.168.4.16/api/auth/providers

```

---

## 4️⃣ 自动建用户

首次登录：

- 自动创建用户
- 自动分配角色

---

# 🧨 九、你之前失败的根本原因（总结）

你之前的问题不是配置错，而是：

## ❌ 用错层级

<table id="bkmrk-%E5%B1%82%E7%BA%A7-%E4%BD%A0%E4%B9%8B%E5%89%8D-%E6%AD%A3%E7%A1%AE-worker-%E2%9D%8C-%E9%85%8D"><thead><tr><th>层级</th><th>你之前</th><th>正确</th></tr></thead><tbody><tr><td>Worker</td><td>❌ 配SSO</td><td>❌ 不支持</td></tr><tr><td>API</td><td>❌ 缺失</td><td>✔ 必须</td></tr><tr><td>Keycloak</td><td>✔ 正确</td><td>✔ 正确</td></tr></tbody></table>

---

# 🚀 十、最终升级结果

完成后你会得到：

## ✔ 企业SSO

- AD登录
- Keycloak统一认证

## ✔ RBAC

- 自动权限分配
- 按组控制功能

## ✔ 自动化

- 自动建用户
- 自动分配角色

## ✔ 安全

- token认证
- session隔离
- 审计日志

---

# 📌 如果你下一步要继续升级（推荐）

我可以再帮你做更高阶企业架构：

### 🔐 1. 多租户隔离（Tenant级别）

### 🔐 2. 文档权限控制（部门级RAG隔离）

### 🔐 3. Keycloak Realm 多域隔离

### 🔐 4. LDAP + HR系统自动同步

### 🔐 5. 零信任访问架构（ZTNA）

只要你说一句：

> “升级多租户+零信任”

我可以帮你直接升级到下一层企业架构。

# RAGFlow + Keycloak 生产级 HTTPS 标准接入方案

下面给你一套**RAGFlow + Keycloak 生产级 HTTPS 标准接入方案（可落地）**。我按“正确架构 → Keycloak → Nginx → RAGFlow → 验证步骤”完整给你一步一步拆开。

---

# 一、标准企业架构（必须先搞清）

推荐结构：

```text
Browser
   ↓ HTTPS（443）
Nginx（TLS终止）
   ↓ HTTP 内网
RAGFlow (9380)
Keycloak (8081)
PostgreSQL

```

---

# 二、核心原则（避免你现在的坑）

必须统一三点：

### ✔ 1. 外部必须 HTTPS

### ✔ 2. 内部全部 HTTP

### ✔ 3. Keycloak 必须信任 X-Forwarded headers

---

# 三、第一步：准备 HTTPS（Nginx）

## 1. 生成证书（测试环境）

```bash
cd /home/shuncom/ragflow-main/docker

mkdir -p /nginx/ssl

openssl req -x509 -nodes -days 365 \
  -newkey rsa:2048 \
  -keyout ./nginx/ssl/key.pem \
  -out ./nginx/ssl/cert.pem \
  -subj "/CN=192.168.4.16"

```

---

## 2. Nginx HTTPS 配置（核心）

```nginx
server {
    listen 80;
    server_name 192.168.4.16;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name 192.168.4.16;

    ssl_certificate     /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;

    # =========================
    # RAGFlow 前端
    # =========================
    root /ragflow/web/dist;

    location / {
        try_files $uri $uri/ /index.html;
    }

    # =========================
    # RAGFlow API
    # =========================
    location ^~ /api/ {
        proxy_pass http://127.0.0.1:9380;
        include proxy.conf;

        proxy_set_header X-Forwarded-Proto https;
    }

    location ^~ /v1/ {
        proxy_pass http://127.0.0.1:9380;
        include proxy.conf;

        proxy_set_header X-Forwarded-Proto https;
    }

    location ^~ /api/v1/admin {
        proxy_pass http://127.0.0.1:9381;
        include proxy.conf;
    }

    # =========================
    # Keycloak 反代（重点）
    # =========================
    location /auth/ {
        proxy_pass http://127.0.0.1:8081/;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-Port 443;
    }
}

```

---

# 四、第二步：Keycloak HTTPS 正确配置（关键）

你的 docker-compose：

```yaml
keycloak:
  image: quay.io/keycloak/keycloak:24.0
  command: start-dev

  environment:
    KEYCLOAK_ADMIN: admin
    KEYCLOAK_ADMIN_PASSWORD: admin123

    KC_DB: postgres
    KC_DB_URL_HOST: postgres
    KC_DB_URL_DATABASE: keycloak
    KC_DB_USERNAME: keycloak
    KC_DB_PASSWORD: keycloak123

    # =========================
    # 核心HTTPS/代理配置
    # =========================
    KC_PROXY: edge
    KC_PROXY_HEADERS: xforwarded

    KC_HTTP_ENABLED: "true"
    KC_HOSTNAME: 192.168.4.16
    KC_HOSTNAME_STRICT: "false"
    KC_HOSTNAME_STRICT_HTTPS: "false"

    KC_HOSTNAME_PORT: 443

  ports:
    - "8081:8080"

```

---

# 五、第三步：RAGFlow OIDC 配置

在 `service_conf.yaml.template`：

```yaml
oauth:
  oidc:
    display_name: "SSO Login"
    client_id: "ragflow"
    client_secret: "xxx"

    issuer: "https://192.168.4.16/auth/realms/shuncom"

    scope: "openid email profile"

    redirect_uri: "https://192.168.4.16/api/v1/auth/login/oidc"

```

---

# 六、第四步：Keycloak 客户端配置（关键）

在 Keycloak 控制台：

## Client 配置：

### ✔ Valid Redirect URIs（必须）

```text
https://192.168.4.16/api/v1/auth/login/oidc

```

或（推荐通配）：

```text
https://192.168.4.16/*

```

---

### ✔ Web Origins

```text
https://192.168.4.16

```

---

### ✔ Access Type

```
confidential

```

---

### ✔ Standard Flow

```
ON

```

---

# 七、第五步：必须避免的坑（非常重要）

## ❗ 坑1：不能混 HTTP / HTTPS

必须统一：

- ❌ [http://192.168.4.16](http://192.168.4.16/)
- ✔ [https://192.168.4.16](https://192.168.4.16/)

---

## ❗ 坑2：Keycloak 必须信任 X-Forwarded-Proto

否则 cookie 会错：

```text
Secure cookie rejected

```

---

## ❗ 坑3：redirect\_uri 必须 HTTPS

---

# 八、第六步：验证流程

## 1. 测试 HTTPS

```bash
curl -k https://192.168.4.16

```

---

## 2. 测试 Keycloak

```text
https://192.168.4.16/auth

```

---

## 3. 测试 OIDC

登录：

```
https://192.168.4.16

```

---

# 九、你当前问题本质总结

你之前的问题全部来自：

> ❌ Keycloak + Nginx 没统一 HTTPS scheme（X-Forwarded-Proto错误）

---

# 十、企业级稳定版架构（推荐最终形态）

```text
Nginx（HTTPS）
   ↓
Keycloak（HTTP 内网）
   ↓
RAGFlow（HTTP 内网）

```

---

# 十一、如果你要一步到位（强烈建议）

我可以帮你直接升级成：

## ✔ 企业级SSO完整生产架构

包含：

- HTTPS + Nginx标准配置
- Keycloak OIDC 完整修复
- RAGFlow 登录不循环
- AD/LDAP自动同步
- 角色映射
- 多域名SSO

---

只要你说一句：

> “做企业级SSO最终生产架构”

我可以直接给你一套**可以上线用的完整配置（避免你现在所有坑）**。

# WeKnora 内置模型如何对接阿里云百炼

你这个问题本质是：**WeKnora 内置模型如何对接阿里云百炼（DashScope / Qwen / Embedding / Rerank）**。

我直接给你一套“能落地的标准写法”，并把阿里云三类模型（LLM / Embedding / Rerank）一次配齐。

---

# 🧠 一、阿里云在 WeKnora 里的统一映射关系

阿里云百炼（DashScope）在 WeKnora 里通常这样对应：

<table id="bkmrk-%E6%A8%A1%E5%9E%8B%E7%B1%BB%E5%9E%8B-%E9%98%BF%E9%87%8C%E4%BA%91%E6%A8%A1%E5%9E%8B-weknora-t"><thead><tr><th>模型类型</th><th>阿里云模型</th><th>WeKnora type</th></tr></thead><tbody><tr><td>对话模型</td><td>qwen-plus / qwen-max / qwen-turbo</td><td>KnowledgeQA</td></tr><tr><td>向量模型</td><td>text-embedding-v2 / text-embedding-3</td><td>Embedding</td></tr><tr><td>重排序</td><td>qwen-rerank-v2 / gte-rerank-v2</td><td>Rerank</td></tr></tbody></table>

---

# ⚙️ 二、阿里云 DashScope Base URL（统一）

所有模型统一用：

```text
https://dashscope.aliyuncs.com/compatible-mode/v1

```

---

# 🔐 三、API Key

```text
DASHSCOPE_API_KEY=sk-xxxx

```

---

# 🧩 四、WeKnora builtin\_models.yaml（阿里云完整配置）

直接给你生产可用版本：

---

## ✅ 1️⃣ 对话模型（Qwen）

```yaml
builtin_models:
  - id: builtin-qwen-plus
    name: qwen-plus
    type: KnowledgeQA
    source: aliyun
    description: 阿里云百炼 Qwen 对话模型
    is_default: true
    parameters:
      base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
      api_key: ${DASHSCOPE_API_KEY}
      provider: generic

```

---

## ✅ 2️⃣ Embedding（向量模型）

```yaml
  - id: builtin-qwen-embedding
    name: text-embedding-v2
    type: Embedding
    source: aliyun
    parameters:
      base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
      api_key: ${DASHSCOPE_API_KEY}
      provider: generic
      embedding_parameters:
        dimension: 1536
        truncate_prompt_tokens: 8192

```

---

## ⚠️ 如果你用 text-embedding-3-large（新版本）

```yaml
dimension: 1024   # 注意这个要改

```

---

## ✅ 3️⃣ Rerank（Qwen rerank-v2）

```yaml
  - id: builtin-qwen-rerank
    name: qwen-rerank-v2
    type: Rerank
    source: aliyun
    parameters:
      base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
      api_key: ${DASHSCOPE_API_KEY}
      provider: generic

```

---

# 🧠 五、关键坑（非常重要）

## ❌ 1. provider 不能写 openai

阿里云必须用：

```yaml
provider: generic

```

---

## ❌ 2. base\_url 不能写 api.openai.com

必须是：

```text
dashscope.aliyuncs.com

```

---

## ❌ 3. rerank endpoint 不同

WeKnora 会自动拼：

```text
/rerank

```

---

# 🚨 六、环境变量必须补

在 `.env` 加：

```env
DASHSCOPE_API_KEY=你的key

```

---

# 🔥 七、推荐完整企业级配置（你可以直接用）

```yaml
builtin_models:
  - id: qwen-chat
    name: qwen-plus
    type: KnowledgeQA
    source: aliyun
    is_default: true
    parameters:
      base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
      api_key: ${DASHSCOPE_API_KEY}
      provider: generic

  - id: qwen-embedding
    name: text-embedding-v2
    type: Embedding
    source: aliyun
    parameters:
      base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
      api_key: ${DASHSCOPE_API_KEY}
      provider: generic
      embedding_parameters:
        dimension: 1536
        truncate_prompt_tokens: 8192

  - id: qwen-rerank
    name: qwen-rerank-v2
    type: Rerank
    source: aliyun
    parameters:
      base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
      api_key: ${DASHSCOPE_API_KEY}
      provider: generic

```

---

# 🧪 八、验证是否生效

重启：

```bash
docker compose restart

```

检查日志：

```bash
docker logs WeKnora-app | grep -i model

```

---

# 🧠 九、常见问题（你大概率会遇到）

## ❌ 1. 模型不显示

👉 检查：

- yaml 是否挂载
- 文件路径是否正确
- BUILTIN\_MODELS\_CONFIG 是否覆盖

---

## ❌ 2. embedding 报维度错误

👉 99% 是：

```text
dimension 写错

```

---

## ❌ 3. rerank 不生效

👉 DashScope rerank 必须用：

```text
qwen-rerank-v2

```

---

# 🚀 十、如果你下一步要升级（建议）

你现在已经可以继续升级到：

### ✔ 阿里云 + WeKnora 企业级RAG

我可以帮你做：

- ✔ embedding + rerank 优化链路
- ✔ hybrid search（BM25 + vector）
- ✔ rerank 提升召回精度
- ✔ 多模型 fallback
- ✔ 成本控制策略（qwen-turbo / plus切换）

---

# ✔ 一句话总结

> WeKnora 接阿里云 = DashScope compatible-mode + generic provider + 三类模型分别配置

---

如果你愿意，我可以帮你再往下一步做：

👉 **WeKnora + 阿里云 + rerank + 高精度RAG最佳实践配置（生产级）**

很好，这一步已经把问题彻底“反转定位”了——现在不是“没加载模型”，而是：

> 🧠 **模型已经写入数据库，但没有在 UI 被识别为“内置模型”**

我给你直接拆关键点。

---

# 🚨 一、你现在真实状态（非常关键）

数据库里：

```text
models 表 ✔ 存在
3个模型 ✔ 已写入
tenant_id = 10000 ✔
status = active ✔

```

说明：

> ✅ builtin\_models loader **已经成功执行**  
> ✅ 数据已经入库  
> ❌ UI 没显示 = 查询逻辑没匹配

---

# 🧩 二、问题核心（真正原因）

看你数据：

```text
type = KnowledgeQA
type = Embedding
type = Rerank

```

再看一个关键字段：

```text
is_default = f

```

👉 全部是 false

---

# 🔥 三、WeKnora UI 显示模型的规则（重点）

UI 一般不是“显示全部 models”，而是：

## ✔ 过滤条件通常是：

```sql
WHERE is_builtin = true
OR managed_by = 'system'
OR tenant_id = 0
OR is_default = true

```

---

# 🚨 四、你当前模型缺了一个关键标识

你表里有：

```text
is_builtin = f ❌

```

👉 这就是 UI 不显示的根因

---

# 🧠 五、再看 tenant\_id（第二个关键点）

你现在：

```text
tenant_id = 10000

```

但很多 WeKnora 版本 UI 默认：

```text
tenant_id = 0 或 NULL = system models

```

---

# ⚠️ 六、总结真正问题（非常明确）

你现在是：

<table id="bkmrk-%E9%A1%B9%E7%9B%AE-%E7%8A%B6%E6%80%81-%E6%A8%A1%E5%9E%8B%E5%85%A5%E5%BA%93-%E2%9C%94-%E6%88%90%E5%8A%9F-yaml"><thead><tr><th>项目</th><th>状态</th></tr></thead><tbody><tr><td>模型入库</td><td>✔ 成功</td></tr><tr><td>YAML加载</td><td>✔ 成功</td></tr><tr><td>UI可见性标识</td><td>❌ 缺失</td></tr><tr><td>tenant匹配</td><td>❌ 可能不匹配</td></tr></tbody></table>

---

# 🔥 七、最可能的 UI 查询逻辑（真实）

WeKnora UI 很可能在做：

```sql
SELECT * FROM models
WHERE tenant_id = current_tenant
AND is_builtin = true;

```

👉 你的数据：

- tenant\_id = 10000
- is\_builtin = false

👉 所以：

> ❌ 完全被过滤掉

---

# 🛠 八、直接修复方案（推荐）

## ✅ 方案 1：标记为 builtin

执行 SQL：

```sql
UPDATE models
SET is_builtin = true
WHERE tenant_id = 10000;

```

---

## ✅ 方案 2：或者改 tenant\_id（更标准）

```sql
UPDATE models
SET tenant_id = 0
WHERE tenant_id = 10000;

```

---

## ✅ 方案 3：同时设置默认模型（推荐）

```sql
UPDATE models
SET is_builtin = true,
    is_default = true
WHERE name = 'qwen-turbo';

```

---

# 🧪 九、修复后验证

重启：

```bash
docker compose restart

```

然后刷新 UI：

👉 Settings → Models

---

# 🧠 十、为什么你 YAML 看起来“正常但UI不显示”

因为：

```text
YAML ✔
↓
DB写入 ✔
↓
UI过滤 ❌（tenant/is_builtin）
↓
看不到

```

---

# 🚀 十一、给你一个“企业级正确写法”

建议统一：

```sql
tenant_id = 0
is_builtin = true
managed_by = system
status = active

```

---

# ✔ 十二、一句话总结

> 🧨 你的模型不是没加载，而是被 UI 的 tenant + builtin 过滤规则隐藏了

---

# 🚀 如果你下一步要升级（我可以帮你做）

我可以帮你直接优化成：

### ✔ 阿里云 Qwen + WeKnora 标准内置模型结构

### ✔ tenant隔离正确设计

### ✔ rerank + embedding 自动绑定

### ✔ 默认模型自动选中

### ✔ 多租户可见策略

只需要你下一步说一句：

👉 “我要企业级模型规范”

我可以帮你把这一套直接改成生产级结构。

# Dify挂载smb共享试验

可以，但 **Dify 官方 Docker 部署默认不能直接把 `/mnt/smb_doc` 作为知识库数据源路径扫描**。Dify 知识库不是类似 Nextcloud 那种文件浏览器，它的文件导入机制是：

1. 上传文件到 Dify → 存储到 `storage` 目录；
2. 或通过插件/外部数据源读取；
3. Worker 异步解析 → Embedding → 写入向量库。

如果希望使用你的 SMB 共享：

```
\\192.168.0.83\本地知识库
        ↓
Ubuntu挂载
        ↓
/mnt/smb_doc
        ↓
Dify知识库读取

```

有几种方案。

---

## 方案1（推荐）：把 SMB 挂载映射到 Dify 容器

你的宿主机：

```
/mnt/smb_doc

```

已经正常：

```

//192.168.0.83/本地知识库  9.8T  930G  8.9T  /mnt/smb_doc

```

修改：

```
/opt/dify/docker/docker-compose.yaml

```

找到：

```yaml
services:
  api:

```

增加：

```yaml
    volumes:
      - /mnt/smb_doc:/mnt/smb_doc:ro

```

例如：

```yaml
api:
  image: langgenius/dify-api:1.15.0
  volumes:
    - ./volumes/app/storage:/app/api/storage
    - /mnt/smb_doc:/mnt/smb_doc:ro

```

---

同时 worker 也必须挂载，因为真正解析文档的是 worker：

找到：

```yaml
worker:

```

增加：

```yaml
    volumes:
      - /mnt/smb_doc:/mnt/smb_doc:ro

```

---

重启：

```bash
docker compose down

docker compose up -d

```

验证：

```bash
docker exec -it docker-api-1 ls /mnt/smb_doc

```

应该看到：

```
合同
技术文档
PDF
Word
...

```

worker验证：

```bash
docker exec -it docker-worker-1 ls /mnt/smb_doc

```

---

但是注意：

**挂载进去 ≠ Dify知识库自动发现文件**

Dify界面里面不会出现 `/mnt/smb_doc`。

---

# 方案2（企业推荐）：使用 Dify 外部知识库 API

如果你的 SMB 是公司资料库，我更推荐：

```
SMB共享
 |
 | 定时扫描
 |
Python脚本
 |
Dify Knowledge API
 |
向量数据库
 |
员工问答

```

例如每天：

```bash
find /mnt/smb_doc -name "*.pdf"

```

发现新文件：

调用：

```
POST /datasets/{dataset_id}/document/create-by-file

```

自动导入。

优点：

- 不占 Dify 存储
- SMB 保持原样
- 支持增量同步
- 适合几 TB 文件库

你的环境：

```
9.8T容量
930G数据

```

已经属于企业知识库规模，不建议全部手工上传。

---

# 方案3：直接把 SMB 映射成 Dify storage（不推荐）

例如：

```yaml
api:
 volumes:
   - /mnt/smb_doc:/app/api/storage

```

不要这样做。

原因：

Dify storage里面有：

```
storage/
├── documents
├── avatars
├── datasets
├── plugin

```

还有内部元数据。

SMB文件混进去容易导致：

- 权限异常
- 索引混乱
- 升级失败

---

# 方案4：使用 Dify 插件数据源

Dify 1.15 已经有插件机制：

```
知识库
  ↓
数据源插件
  ↓
文件系统

```

可以开发一个：

```
SMB Data Source Plugin

```

逻辑：

```
mount /mnt/smb_doc

读取:
pdf
docx
xlsx
txt

返回:
Document[]

```

这是长期最佳方案。

---

# 你的环境建议

你的服务器：

```
Ubuntu 24.04
Dify 1.15.0
PostgreSQL
pgvector
SMB 9.8T

```

建议架构：

```
             SMB NAS
                |
        /mnt/smb_doc
                |
        同步程序(Python)
                |
          Dify API
                |
       Knowledge Base
                |
          pgvector

```

不要让 Dify 直接管理 900G 文件。

---

## 现在可以先测试挂载

修改 compose 后：

```bash
docker compose up -d

```

检查：

```bash
docker exec docker-worker-1 ls /mnt/smb_doc

```

如果能看到文件，我可以继续给你提供：

1. **SMB自动同步到Dify知识库Python脚本**
2. **支持PDF/Word/Excel增量更新**
3. **定时systemd运行**
4. **自动创建Dify知识库并导入**

这个方案比较适合你的公司内部资料库场景。

# Dify对接钉钉开发者后台添加的机器人

前面给你的版本偏“概念代码”，这里改成**工程化 services 分层结构**。

目标：

- 钉钉 **开发者后台机器人**
- **Stream 模式**
- Python `dingtalk-stream`
- FastAPI 项目结构
- Dify Chat API Streaming
- Service 层隔离
- 后续可扩展 Redis、知识库、权限

`dingtalk-stream` SDK 本身就是针对钉钉 Stream 模式的机器人收消息、事件回调设计的。当前 Python 包版本可直接通过 pip 安装。([PyPI](https://pypi.org/project/dingtalk-stream/?utm_source=chatgpt.com "dingtalk-stream · PyPI"))

---

# 一、项目结构

```text
dify-dingtalk-bot/

├── app/
│
│   ├── main.py
│   │
│   ├── config/
│   │   └── settings.py
│   │
│   ├── services/
│   │   │
│   │   ├── dify_service.py
│   │   │
│   │   ├── dingtalk_service.py
│   │   │
│   │   └── chat_service.py
│   │
│   ├── handlers/
│   │   └── robot_handler.py
│   │
│   └── utils/
│       └── logger.py
│
├── requirements.txt
└── .env

```

---

# 二、依赖

requirements.txt

```txt
fastapi
uvicorn
python-dotenv
requests
dingtalk-stream

```

安装：

```bash
pip install -r requirements.txt

```

---

# 三、配置

## .env

```env
# 钉钉Stream
DING_CLIENT_ID=dingxxxx
DING_CLIENT_SECRET=xxxx


# Dify
DIFY_API_KEY=app-xxxx
DIFY_API_URL=https://api.dify.ai/v1/chat-messages


# 服务
APP_NAME=dify-dingtalk-bot

```

---

# 四、配置服务

## app/config/settings.py

```python
import os
from dotenv import load_dotenv


load_dotenv()


class Settings:


    DING_CLIENT_ID = os.getenv(
        "DING_CLIENT_ID"
    )


    DING_CLIENT_SECRET = os.getenv(
        "DING_CLIENT_SECRET"
    )


    DIFY_API_KEY=os.getenv(
        "DIFY_API_KEY"
    )


    DIFY_API_URL=os.getenv(
        "DIFY_API_URL"
    )


settings=Settings()

```

---

# 五、Dify Service

负责：

- 调用 Dify
- 消费 SSE
- 返回完整答案

## app/services/dify\_service.py

```python
import requests
import json

from app.config.settings import settings



class DifyService:


    def __init__(self):

        self.url = (
            settings.DIFY_API_URL
        )

        self.key = (
            settings.DIFY_API_KEY
        )



    def chat(
        self,
        question:str,
        user:str
    ):


        headers={

            "Authorization":
            f"Bearer {self.key}",

            "Content-Type":
            "application/json"
        }


        payload={

            "inputs":{},

            "query":
            question,


            "response_mode":
            "streaming",


            "user":
            user

        }



        response=requests.post(

            self.url,

            headers=headers,

            json=payload,

            stream=True,

            timeout=120

        )


        answer=""


        for line in response.iter_lines():


            if not line:
                continue



            line=line.decode(
                "utf-8"
            )



            if not line.startswith(
                "data:"
            ):
                continue



            data=json.loads(
                line[5:]
            )


            event=data.get(
                "event"
            )


            if event=="message":

                answer += data.get(
                    "answer",
                    ""
                )


            if event=="message_end":

                break



        return answer

```

---

# 六、聊天业务 Service

以后加：

- 用户权限
- Redis
- 会话ID
- 日志

都放这里。

## app/services/chat\_service.py

```python
from app.services.dify_service import DifyService



class ChatService:


    def __init__(self):

        self.dify=DifyService()



    def ask(
        self,
        message,
        user
    ):


        return self.dify.chat(

            question=message,

            user=user

        )

```

---

# 七、钉钉发送 Service

## app/services/dingtalk\_service.py

```python
import dingtalk_stream



class DingTalkService:



    def reply(
        self,
        handler,
        text,
        message
    ):


        handler.reply_text(

            text,

            message

        )

```

---

# 八、机器人 Handler

这是核心。

## app/handlers/robot\_handler.py

```python
import logging

import dingtalk_stream

from dingtalk_stream import AckMessage


from app.services.chat_service import ChatService
from app.services.dingtalk_service import DingTalkService



class RobotHandler(
    dingtalk_stream.ChatbotHandler
):


    def __init__(self):

        super().__init__()

        self.chat_service=(
            ChatService()
        )


        self.ding_service=(
            DingTalkService()
        )



    async def process(
        self,
        callback:
        dingtalk_stream.CallbackMessage
    ):


        incoming = (
            dingtalk_stream
            .ChatbotMessage
            .from_dict(
                callback.data
            )
        )


        question=(

            incoming
            .text
            .content
            .strip()

        )


        user=(

            incoming
            .sender_staff_id

        )


        logging.info(
            f"user={user}, msg={question}"
        )



        try:


            answer=(

                self.chat_service.ask(

                    question,

                    user

                )

            )


            self.ding_service.reply(

                self,

                answer,

                incoming

            )


        except Exception as e:


            self.reply_text(

                "服务异常："+str(e),

                incoming

            )



        return (
            AckMessage.STATUS_OK,
            "OK"
        )

```

---

# 九、启动 Stream Client

## app/main.py

```python
import logging

import dingtalk_stream


from app.config.settings import settings

from app.handlers.robot_handler import RobotHandler



def start():


    logging.basicConfig(

        level=logging.INFO

    )



    credential=(

        dingtalk_stream
        .Credential(

            settings.DING_CLIENT_ID,

            settings.DING_CLIENT_SECRET

        )

    )



    client=(

        dingtalk_stream
        .DingTalkStreamClient(

            credential

        )

    )



    client.register_callback_handler(

        dingtalk_stream
        .chatbot
        .ChatbotMessage
        .TOPIC,


        RobotHandler()

    )



    client.start_forever()



if __name__=="__main__":

    start()

```

---

# 十、启动

```bash
python -m app.main

```

正常日志：

```text
INFO endpoint is wss://xxxx
INFO websocket connected

```

钉钉开发者后台机器人上线后：

群里：

```
@机器人 公司的年假政策是什么？

```

流程：

```
ChatbotMessage
       |
       ↓
RobotHandler
       |
       ↓
ChatService
       |
       ↓
DifyService
       |
       ↓
Dify SSE
       |
       ↓
reply_text()
       |
       ↓
钉钉群

```

---

# 十一、下一步建议改造（生产版）

你这个架构建议继续升级：

## 1. 增加 Redis 会话

现在：

```
用户
 |
Dify
 |
新会话

```

升级：

```
staff_id
   |
Redis
   |
conversation_id
   |
Dify上下文

```

---

## 2. 增加真正 Stream 卡片回复

当前：

```
Dify:
chunk1
chunk2
chunk3


钉钉:
一次回复

```

升级：

```
Dify chunk
    |
    |
钉钉AI卡片stream
    |
    |
逐字刷新

```

可以做到类似 ChatGPT 的效果。

---

## 3. 推荐生产目录

大型项目：

```text
services

├── dingtalk
│    ├── stream_client.py
│    ├── message.py
│    └── card.py
│
├── dify
│    ├── client.py
│    ├── stream.py
│    └── workflow.py
│
├── memory
│    └── redis.py
│
└── security
     └── permission.py

```

这个结构可以直接扩展成企业级 **钉钉 AI 助手 + Dify RAG 知识库平台**。

现在信息完整了，可以确定有 **两个独立问题**：

1. **`.env` 没有生效（最关键）**
2. **websockets 版本和 dingtalk-stream 0.24.3 不兼容**

我们逐个修。

---

# 一、你的 `.env` 当前全部被注释了

你贴出来：

```env
# DING_CLIENT_ID=ding09cjpitrovdwlax0
# DING_CLIENT_SECRET=xxxxx

```

注意前面的：

```text
#

```

意味着 Python 根本读不到。

所以：

```python
settings.DING_CLIENT_ID

```

实际应该是：

```text
None

```

SDK 发起：

```
POST https://api.dingtalk.com/v1.0/gateway/connections/open

```

时，没有合法 credential，钉钉返回：

```json
{
 "code":"systemError"
}

```

---

## 修改 .env

去掉所有 `#`：

```bash
vim /opt/dify-dingtalk-bot/.env

```

改成：

```env
# 钉钉Stream
DING_CLIENT_ID=xxxxxxxxxxxxx

DING_CLIENT_SECRET=你的secret


# Dify
DIFY_API_KEY=app-xxxxxxxxxxxxxxxxxxxxx

DIFY_API_URL=http://192.168.4.20/v1/chat-messages


APP_NAME=dify-dingtalk-bot

```

注意：

你的 Dify 地址之前：

```env
DIFY_API_URL=http://192.168.4.20/v1

```

少了：

```
/chat-messages

```

应该：

```
http://192.168.4.20/v1/chat-messages

```

---

# 二、验证环境变量

不要启动机器人，先测试：

```bash
python

```

执行：

```python
from app.config.settings import settings

print("client:", settings.DING_CLIENT_ID)

print("secret:",
      bool(settings.DING_CLIENT_SECRET))

print("dify:",
      settings.DIFY_API_URL)

```

正确应该：

```text
client: xxxxxxxxxxxx

secret: True

dify: http://192.168.4.20/v1/chat-messages

```

如果还是：

```text
client: None

```

说明 dotenv 路径问题。

---

# 三、修复 websockets 兼容问题

你的错误：

```
AttributeError:
module 'websockets' has no attribute 'exceptions'

```

原因：

你现在：

```text
dingtalk-stream 0.24.3

```

依赖：

```text
websockets

```

但是装到了新版：

大概率：

```
websockets 15.x

```

新版删除了一些旧接口。

---

查看：

```bash
pip show websockets

```

应该类似：

```text
Version: 15.x

```

---

降级：

```bash
pip uninstall websockets -y

pip install websockets==10.4

```

然后确认：

```bash
pip show websockets

```

应该：

```
Version: 10.4

```

---

# 四、修改 requirements.txt

否则以后重新部署还会坏。

你的：

`app/requirements.txt`

改：

```txt
fastapi
uvicorn
python-dotenv
requests
dingtalk-stream==0.24.3
websockets==10.4

```

---

# 五、重新测试

执行：

```bash
cd /opt/dify-dingtalk-bot

source /opt/ding_dify/bin/activate

python -m app.main

```

正常应该看到：

类似：

```
INFO:dingtalk_stream.client:
open connection

INFO:dingtalk_stream.client:
connection established

INFO:dingtalk_stream.client:
websocket connected

```

而不是循环：

```
400 systemError

```

---

# 六、如果仍然 400

那就只剩钉钉后台配置。

重点检查：

## 1. Client ID

必须来自：

钉钉开放平台：

```
应用开发
 ↓
企业内部应用
 ↓
凭证与基础信息
 ↓
Client ID

```

不是：

- AppKey
- AgentId
- RobotCode

---

## 2. Stream模式开启

后台：

```
机器人管理
 ↓
消息接收模式

```

必须：

```
Stream模式

```

---

## 3. 发布应用

必须：

```
版本管理与发布
 ↓
上线

```

测试应用也需要发布。

---

## 4. 机器人权限

至少：

```
机器人消息接收
机器人发送消息

```

---

你现在先做两个动作：

### ① 取消 `.env` 注释

### ② 降级 websocket

执行：

```bash
pip uninstall websockets -y
pip install websockets==10.4

```

然后重新跑。

如果还有错误，把新的启动日志贴出来。你现在距离通已经很近了。

不对。你现在加日志的位置有问题，会导致程序启动时直接报错。

你写在文件顶部：

```python
logger.info(
    "Dify request question=%s user=%s",
    question,
    user
)

logger.info(
    "Dify response=%s",
    answer
)

```

但是此时：

```python
question
user
answer

```

三个变量都还不存在。

Python 加载 `dify_service.py` 时就会执行这里，所以会报：

```text
NameError: name 'question' is not defined

```

---

正确方式：**日志应该放到 `chat()` 方法内部。**

修改后的 `dify_service.py`：

```python
import requests
import json
import logging

from app.config.settings import settings


logger = logging.getLogger(__name__)


class DifyService:


    def __init__(self):

        self.url = settings.DIFY_API_URL

        self.key = settings.DIFY_API_KEY



    def chat(
        self,
        question: str,
        user: str
    ):


        logger.info(
            "Dify request question=%s user=%s",
            question,
            user
        )


        headers = {

            "Authorization":
            f"Bearer {self.key}",

            "Content-Type":
            "application/json"
        }


        payload = {

            "inputs": {},

            "query": question,

            "response_mode":
            "streaming",

            "conversation_id":"",

            "user": user
        }


        logger.info(
            "Dify url=%s",
            self.url
        )


        response = requests.post(

            self.url,

            headers=headers,

            json=payload,

            stream=True,

            timeout=120

        )


        logger.info(
            "Dify http status=%s",
            response.status_code
        )


        answer = ""


        for line in response.iter_lines():


            if not line:
                continue


            line = line.decode(
                "utf-8"
            )


            logger.debug(
                "Dify stream=%s",
                line
            )


            if not line.startswith(
                "data:"
            ):
                continue



            data=json.loads(
                line[5:]
            )


            event=data.get(
                "event"
            )


            if event=="message":

                chunk=data.get(
                    "answer",
                    ""
                )

                answer += chunk


                logger.info(
                    "Dify chunk=%s",
                    chunk
                )


            elif event=="message_end":

                break


            elif event=="error":

                logger.error(
                    "Dify error=%s",
                    data
                )


        logger.info(
            "Dify response=%s",
            answer
        )


        return answer

```

---

## 另外，你现在排查钉钉无回答，建议再加一个关键日志

在：

```python
response=requests.post(...)

```

后面增加：

```python
logger.info(
    "Dify headers=%s",
    response.headers
)

```

以及：

```python
if response.status_code != 200:
    logger.error(
        "Dify error body=%s",
        response.text
    )

```

否则如果 API Key 错误，你只看到：

```text
answer=""

```

不知道原因。

---

## 重启服务

如果你用 systemd：

```bash
systemctl restart dify-dingtalk

```

查看：

```bash
journalctl -u dify-dingtalk -f

```

然后钉钉发送问题。

你应该看到类似：

```text
Dify request question=公司报销流程是什么 user=xxx

Dify url=http://192.168.4.20/v1/chat-messages

Dify http status=200

Dify chunk=根据公司制度...

Dify response=根据公司制度...

```

---

如果日志显示：

```text
Dify http status=200
Dify response=

```

那就是 **Dify 应用配置问题**。

如果显示：

```text
401

```

就是 API Key。

如果显示：

```text
404

```

就是 API URL。

如果显示：

```text
200 有answer

```

但是钉钉没回复，就是 `dingtalk_service.py / handler` 的问题。你下一步把日志贴出来即可。

# Dify Webdav上传文件不能分段分析处理过程记录

现在基本可以确定问题位置了。

你的数据库信息非常关键：

```text
doc_type        | 
doc_metadata    | null
doc_form        | text_model
word_count      | 12

```

尤其：

```text
doc_type = 空
doc_metadata = null
word_count = 12

```

这说明：

**Dify 从 WebDAV 下载后，没有识别成 docx 文件。**

正常 docx 应该至少有：

```text
doc_type = docx
doc_metadata = {...}
word_count = 几百/几千

```

---

## 更关键的是 pipeline 日志

你的：

```json
datasource_type:
online_drive

```

输入：

```json
{
 "id": "/Rulr运维/研-儒来平台国产化部署项目说明文档.docx",
 "name": "研-儒来平台国产化部署项目说明文档.docx",
 "bucket": "webdav"
}

```

说明：

WebDAV 插件只告诉 Dify：

> 文件在哪里

但是没有告诉 Dify：

> 这是一个 docx 文件，并提供可解析的文件对象

所以 pipeline 直接进入：

```
online_drive
    ↓
download
    ↓
text_model
    ↓
general_chunker
    ↓
1 chunk

```

---

# 现在重点查 file\_id

你的 documents 表还有：

```text
file_id | text

```

但是刚才查询没有显示。

执行：

```sql
select
id,
file_id,
name
from documents
where id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

我预计：

### 情况1（最可能）

结果：

```
file_id | NULL

```

那么说明：

WebDAV插件没有把文件保存到 Dify storage。

---

### 情况2

有 file\_id：

例如：

```
file_id
--------
xxxx-xxxx

```

那么继续查：

```sql
select *
from upload_files
where id='file_id';

```

---

# 另外查 segments

现在已经知道它只有12字符，再确认一下：

```sql
select
id,
position,
content
from document_segments
where document_id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

我预计：

类似：

```
position | content
---------+-------
1        | 研-儒来平台国产化部署项目说明文档.docx

```

如果是这个，就100%确认。

---

# 根因定位

你的环境：

```
Dify 1.15.0
plugin_daemon 0.6.3
shaba/webdav

```

问题不在 Dify 分段参数。

因为：

第一次：

```
max_chunk_length=800

```

第二次：

```
max_chunk_length=1024

```

第三次：

```
max_chunk_length=1024

```

结果一直：

```
1 paragraph

```

说明：

chunker工作正常，只是输入文本只有12字符。

---

# 修复方向

## 方案A（推荐）：修改 shaba/webdav 插件

需要检查：

插件：

```
shaba/webdav

```

里的：

```
online_drive_download_file

```

这个接口。

它现在应该类似返回：

```json
{
 "type":"file",
 "url":"..."
}

```

但是 Dify datasource plugin 标准应该返回：

文件二进制流 + 文件名 + mime。

需要保证：

```python
filename:
研-儒来平台国产化部署项目说明文档.docx

mime:
application/vnd.openxmlformats-officedocument.wordprocessingml.document

```

---

## 方案B：不用 datasource，改同步上传

如果只是想把 WebDAV 当文件仓库：

可以：

```
WebDAV
 ↓
rclone sync
 ↓
本地目录
 ↓
Dify API上传

```

这样一定走：

```
upload_file
docx parser
chunk

```

---

## 方案C：检查插件版本

进入 plugin 容器：

```bash
docker exec -it docker-plugin_daemon-1 bash

```

查看安装插件：

```bash
ls /app/plugins

```

确认：

```
shaba/webdav

```

版本。

可能需要升级。

---

现在请再执行两个命令：

### 1.

```sql
select
id,
file_id,
name
from documents
where id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

### 2.

```sql
select
position,
content
from document_segments
where document_id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

这两个结果出来后，可以确定是 **插件返回文件问题** 还是 **下载文件内容问题**。目前已经非常接近根因。

这个结果非常关键，前面的判断需要修正一下：

**不是 WebDAV 没有上传文件。**

因为 `upload_files` 里已经有：

```text
研-儒来平台国产化部署项目说明文档.docx
extension = docx
mime_type = application/vnd.openxmlformats-officedocument.wordprocessingml.document

```

说明：

✅ WebDAV 下载文件成功  
✅ 文件类型识别正常  
✅ upload\_files 已生成文件记录

但是：

```text
documents.file_id = NULL

```

说明：

**文件已经上传到 storage，但知识库 document 没有关联这个 file\_id。**

这就是导致：

```text
doc_type = NULL
doc_metadata = NULL
word_count = 12
1 paragraph

```

的直接原因。

---

## 现在需要查关联关系

Dify 1.15 这里通常通过：

```
documents.file_id
        ↓
upload_files.id

```

关联。

你的异常：

```
documents
 id:
4e9e360a-5ab3-4957-8de9-75b76e173bdb

file_id:
空

```

但是 upload\_files 有：

```
9dc4b86e-7f4c-4804-a5a8-f81742148ddc

```

这两个没有连起来。

---

## 找对应的 upload\_file

执行：

```sql
select
id,
name,
extension,
created_at
from upload_files
where name='研-儒来平台国产化部署项目说明文档.docx'
order by created_at desc;

```

你会看到多个。

注意时间：

你的 document：

```
created_at:
2026-07-09 07:31:48

```

但是 upload\_files：

例如：

```
2026-07-09 02:40:27

```

这里有时区差：

PostgreSQL显示 UTC，本地显示 +8。

大概率对应：

```text
9b2f7c06-e091-4332-a3e9-83c84af21bb8

```

或者：

```text
b69aa5e5-f81d-447f-a13f-8b106c03f5f4

```

---

## 验证一下

执行：

```sql
select
d.id as document_id,
d.name,
d.file_id,
u.id as upload_id,
u.name as upload_name
from documents d
left join upload_files u
on d.file_id=u.id
where d.name='研-儒来平台国产化部署项目说明文档.docx';

```

现在应该显示：

```
document_id                         file_id upload_id
----------------------------------------------------
4e9e360a...                         NULL    NULL

```

---

# 根因已经变成：

不是：

❌ WebDAV插件不能下载文件

而是：

❌ WebDAV datasource pipeline 创建 document 时，没有把 upload\_file\_id 写入 documents.file\_id

---

## 为什么本地上传正常？

本地：

```
upload_files
    |
    |
documents.file_id
    |
docx parser

```

WebDAV：

```
upload_files
    |
    X
documents.file_id=NULL
    |
text_model

```

---

# 修复方案

## 方案1：修 shaba/webdav 插件（推荐）

检查插件代码：

```
online_drive_download_file

```

它应该返回：

类似：

```json
{
 "file_id":"9dc4b86e-7f4c-4804-a5a8-f81742148ddc"
}

```

现在返回可能只有：

```json
{
 "id":"/Rulr运维/xxx.docx",
 "name":"xxx.docx",
 "bucket":"webdav"
}

```

---

## 方案2：手工验证（不要长期用）

可以直接更新：

```sql
update documents
set file_id='对应upload_files.id'
where id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

然后重新分段。

如果马上恢复：

说明100%就是关联问题。

⚠️ 建议先备份数据库。

---

## 还有一个需要查的表

Dify 1.15 datasource 可能还记录文件绑定：

执行：

```sql
select *
from segment_attachment_bindings
where document_id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

不过目前不是重点。

---

现在请执行：

```sql
select
id,
name,
created_at
from upload_files
where name='研-儒来平台国产化部署项目说明文档.docx'
order by created_at desc;

```

然后把结果贴一下。

我们找出和这个 document 对应的 upload\_file\_id，做一次手工关联测试，就能最终确认。

这个错误也很有价值：

```text
ERROR: operator does not exist: text = uuid
LINE 9: on d.file_id=u.id

```

说明：

```sql
documents.file_id  类型 = text
upload_files.id    类型 = uuid

```

所以 PostgreSQL 不会自动比较，需要转换类型。

执行：

```sql
select
d.id as document_id,
d.name,
d.file_id,
u.id as upload_id,
u.name as upload_name
from documents d
left join upload_files u
on d.file_id = u.id::text
where d.name='研-儒来平台国产化部署项目说明文档.docx';

```

不过根据你前面的结果：

```text
documents.file_id = 空

```

大概率结果还是：

```
document_id                         file_id   upload_id
-------------------------------------------------------
4e9e360a-5ab3-4957-8de9-75b76e173bdb NULL      NULL

```

---

## 下一步我们需要找对应的 upload\_file

你的 WebDAV 重试产生了 5 个同名文件：

```
2026-07-09 01:40:07
2026-07-09 02:20:31
2026-07-09 02:27:43
2026-07-09 02:40:27
2026-07-09 02:49:38

```

对应你的 document：

```
documents.created_at
2026-07-09 07:31:48

```

这里有时区 +8：

Postgres:

```
2026-07-09 07:31:48

```

实际北京时间：

```
2026-07-09 15:31:48

```

而 upload\_files：

```
2026-07-09 02:49:38 UTC

```

北京时间：

```
2026-07-09 10:49:38

```

不完全对应。

所以还需要查 pipeline 日志里的创建时间：

```
document_pipeline_execution_logs
created_at
2026-07-09 07:31:48

```

对应 upload\_file 可能是：

```text
f20a94e5-19b2-4219-b991-5abbc3ea0627

```

但不要直接改，先验证。

---

## 验证 upload\_file 内容

查：

```sql
select
id,
name,
key,
size,
extension,
mime_type
from upload_files
where id='f20a94e5-19b2-4219-b991-5abbc3ea0627';

```

如果有：

```
key
bucket
size

```

说明是真文件。

---

## 然后做一个临时修复测试

先备份：

```sql
create table documents_backup as
select * from documents
where id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

然后：

```sql
update documents
set file_id='f20a94e5-19b2-4219-b991-5abbc3ea0627'
where id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

重新执行知识库：

- 删除当前分段
- 重新分段

如果：

```
word_count
从 12
变成几千

paragraphs
从 1
变几十/几百

```

那么根因完全确认。

---

不过还有一个可能性：

你的日志里：

```
POST plugin_daemon dispatch/tool/invoke
Tool: general_chunker

Outputs:
{
 "variable_value":["online_drive"]
}

```

这里很异常。

正常应该：

```
docx parser
    ↓
text
    ↓
general_chunker

```

现在像是：

```
online_drive
    ↓
general_chunker

```

也就是说 **WebDAV datasource 没有触发文件解析节点**。

所以最终修复点大概率还是：

`shaba/webdav` 插件的数据源返回结构。

---

你先跑上面的：

```sql
select
id,
name,
key,
size,
extension,
mime_type
from upload_files
where id='f20a94e5-19b2-4219-b991-5abbc3ea0627';

```

以及：

```sql
\d upload_files

```

我需要确认 Dify 1.15 的 upload\_files 字段结构，然后给你准确的关联修复方案。

现在可以下最终结论了。

你的数据链路如下：

```
upload_files
        |
        |  正常
        ↓
f20a94e5-19b2-4219-b991-5abbc3ea0627
研-儒来平台国产化部署项目说明文档.docx
size=2847874
mime_type=docx
key=upload_files/...docx


documents
        |
        | 断了
        ↓
4e9e360a-5ab3-4957-8de9-75b76e173bdb
file_id=NULL

```

所以：

**文件已经存在，但 document 没有关联文件。**

这就是为什么：

```
word_count = 12
paragraph = 1
doc_type = NULL

```

因为 Dify 没走 docx parser，而是把 datasource metadata 当文本处理了。

---

## 先做一次手工修复验证

建议先不要改插件，验证关联是否能解决。

### 1. 备份当前 document

```sql
create table documents_backup_20260710 as
select *
from documents
where id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

---

### 2. 写入 file\_id

执行：

```sql
update documents
set file_id='f20a94e5-19b2-4219-b991-5abbc3ea0627'
where id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

确认：

```sql
select
id,
name,
file_id
from documents
where id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

应该：

```
id                                   file_id
---------------------------------------------------
4e9e360a...                          f20a94e5...

```

---

## 但是注意

仅修改 `file_id` **可能还不够**。

因为你的 document 已经生成过错误 segment：

检查：

```sql
select
count(*)
from document_segments
where document_id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

如果 &gt;0：

需要删除旧分段：

```sql
delete from document_segments
where document_id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

然后重新触发分段。

---

## 为什么 WebDAV 会出现这个问题？

从你的日志：

```
POST /dispatch/datasource/online_drive_download_file
HTTP 200

```

说明插件下载成功。

但是后续：

```
general_chunker
Outputs:
["online_drive"]

```

这里说明 pipeline 收到的是：

```
online_drive文本

```

不是：

```
docx文件

```

正常流程应该：

```
WebDAV
 |
download_file
 |
upload_files
 |
file_id
 |
document.file_id
 |
docx parser
 |
chunk
 |
embedding

```

你的实际：

```
WebDAV
 |
download_file
 |
upload_files     ✅
 |
document        ❌ file_id丢失
 |
general_chunker
 |
1段

```

---

# 长期修复点

应该改：

```
shaba/webdav

```

插件。

重点看：

```
online_drive_download_file

```

返回结构。

它现在应该没有返回：

```json
{
  "file_id": "f20a94e5-19b2-4219-b991-5abbc3ea0627"
}

```

或者没有触发 document 创建时绑定。

---

## 建议下一步

先执行手工：

```sql
update documents
set file_id='f20a94e5-19b2-4219-b991-5abbc3ea0627'
where id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

然后在 Dify 界面点：

```
知识库
→ 文档
→ 重新索引

```

看：

```
文档信息

```

是否变成：

```
doc_type: docx
word_count: xxxx
段落数量: xx

```

如果成功，就可以确定 100% 是 WebDAV 插件的 file\_id 绑定 bug。

下一步再改插件，不需要继续排查 Dify 核心。

很好，现在验证环境已经准备好了。

当前状态：

✅ `documents.file_id` 已补上：

```text
4e9e360a-5ab3-4957-8de9-75b76e173bdb
        |
        |
        v
f20a94e5-19b2-4219-b991-5abbc3ea0627

```

✅ 错误生成的 segment 已删除：

```text
document_segments = 0

```

下一步不要直接重新创建 segment，建议先检查 document 状态字段，否则 Dify 可能认为已经处理完成。

---

## 1. 查看当前 document 状态

执行：

```sql
select
id,
word_count,
tokens,
doc_type,
indexing_status,
parsing_completed_at,
splitting_completed_at,
completed_at,
error
from documents
where id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

重点看：

```text
indexing_status
splitting_completed_at
completed_at

```

---

## 2. 重置处理状态

如果现在类似：

```text
indexing_status = completed
splitting_completed_at 有值
completed_at 有值

```

需要清掉：

执行：

```sql
update documents
set
word_count=null,
tokens=null,
parsing_completed_at=null,
cleaning_completed_at=null,
splitting_completed_at=null,
completed_at=null,
indexing_status='waiting',
error=null
where id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

---

## 3. 重新触发索引

推荐优先用 UI：

```
知识库
 → 文档
 → 研-儒来平台国产化部署项目说明文档.docx
 → 重新索引

```

观察 worker：

```bash
docker logs -f docker-worker-1

```

正常应该看到：

类似：

```
parse document
loader: docx
extract text
split document
generate segments
embedding xxx texts

```

而不是：

```
general_chunker
online_drive
1 texts

```

---

## 4. 验证结果

重新完成后：

### documents

```sql
select
name,
word_count,
doc_type,
tokens
from documents
where id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

期待：

类似：

```
name                                  word_count doc_type tokens
---------------------------------------------------------------
研-儒来平台国产化部署项目说明文档.docx  5000       docx     xxxx

```

---

### segments

```sql
select
count(*)
from document_segments
where document_id='4e9e360a-5ab3-4957-8de9-75b76e173bdb';

```

期待：

```
几十 / 上百

```

而不是：

```
1

```

---

如果重新索引后恢复，就可以最终确认：

**shaba/webdav 插件 bug：创建 document 时遗漏 `documents.file_id`。**

之后修插件只需要在 datasource pipeline 创建 document 时补：

```python
document.file_id = upload_file.id

```

即可。

你现在先执行第 1 步，把 document 状态贴出来，我确认是否需要 reset。

# xwiki-sync v1.0 功能说明书

根据目前日志和目录结构，你的 **xwiki-sync v1.0 稳定版** 已经具备一个完整的“共享目录 → XWiki 文档库”的同步闭环：

- 文件新增 ✅
- 文件修改 ✅
- 文件删除同步 ✅
- XWiki 页面创建/更新/删除 ✅
- 自动空间映射 ✅
- 文件 Hash 增量检测 ✅
- SQLite 状态记录 ✅
- Docker 运行 ✅
- Tika 文档解析 ✅

下面整理成正式归档文档，建议保存为：

```
/opt/xwiki/sync/docs/xwiki-sync-v1.0功能说明书.md

```

---

# xwiki-sync v1.0 功能说明书

## 1. 项目名称

**xwiki-sync**

版本：

```
v1.0 Stable

```

发布日期：

```
2026-07-18

```

用途：

> 将 SMB 共享目录中的文档自动同步到 XWiki，实现企业内部文档自动化管理。

---

# 2. 系统架构

整体架构：

```
                 SMB共享目录
                      |
                      |
                scanner/smb.py
                      |
                      |
              文件扫描模块
              core/scanner.py
                      |
                      |
             文件状态数据库
             SQLite Database
                      |
          +-----------+-----------+
          |                       |
      新文件                  已存在文件
          |                       |
          |                   Hash检测
          |                       |
          +-----------+-----------+
                      |
              sync/processor.py
                      |
          +-----------+-----------+
          |
      文档解析
      extractor/tika.py
          |
          |
      XWiki REST API
          |
          |
      XWiki页面



```

---

# 3. 目录结构说明

```
sync
│
├── app.py
│
├── clients
│   └── xwiki.py
│
├── core
│   ├── database.py
│   ├── hash.py
│   ├── hashdb.py
│   └── scanner.py
│
├── extractor
│   └── tika.py
│
├── scanner
│   └── smb.py
│
├── sync
│   └── processor.py
│
├── models
│   └── fileinfo.py
│
├── config.yaml
│
├── Dockerfile
│
└── upgrade_db.py


```

---

# 4. 核心功能说明

# 4.1 文件扫描功能

模块：

```
scanner/smb.py
core/scanner.py

```

功能：

定时扫描共享目录。

默认周期：

```
60秒

```

扫描结果：

例如：

```
/data/wiki_attach/test.txt


```

转换为同步任务：

```
space = wiki_attach

page = test


```

---

# 4.2 文件路径映射规则

## 根目录文件

例如：

```
/data/web.config

```

转换：

```
XWiki:

Main.web


```

说明：

```
默认进入 Main 空间

```

---

## 一级目录

例如：

```
/data/wiki_attach/docker安装.txt


```

转换：

```
Space:

wiki_attach


Page:

docker安装


```

XWiki：

```
wiki_attach.docker安装


```

---

## 多级目录

例如：

```
/data/a/b/c.txt


```

转换：

```
Space:

a


Page:

b_c


```

规则：

```
目录名称_Page名称


```

---

# 4.3 文件类型支持

当前通过：

```
Apache Tika

```

解析。

支持：

<table id="bkmrk-%E7%B1%BB%E5%9E%8B-%E7%8A%B6%E6%80%81-txt-%E6%94%AF%E6%8C%81-docx-%E6%94%AF%E6%8C%81"><thead><tr><th>类型</th><th>状态</th></tr></thead><tbody><tr><td>TXT</td><td>支持</td></tr><tr><td>DOCX</td><td>支持</td></tr><tr><td>DOC</td><td>支持</td></tr><tr><td>PDF</td><td>支持</td></tr><tr><td>XLSX</td><td>支持</td></tr><tr><td>PPTX</td><td>支持</td></tr></tbody></table>

---

# 4.4 增量同步

核心：

```
core/hash.py
core/database.py


```

机制：

文件计算 SHA Hash。

例如：

第一次：

```
test.txt

hash:

abc123


```

数据库保存：

```
文件路径
hash
space
page


```

下一次扫描：

如果：

```
hash相同


```

跳过：

日志：

```
跳过:
xxx 未变化


```

避免重复写入 XWiki。

---

# 4.5 新文件同步

流程：

```
发现文件

↓

计算Hash

↓

数据库不存在

↓

Tika解析

↓

创建XWiki页面

↓

保存数据库


```

日志：

例如：

```
新文件:
wiki_attach.docker镜像导出和导入


页面创建成功

同步完成


```

---

# 4.6 文件修改同步

检测：

```
旧hash != 新hash


```

流程：

```
重新解析

↓

更新XWiki页面

↓

更新数据库hash


```

日志：

```
文件变化:

xxx

页面更新成功


```

---

# 4.7 删除同步

这是 v1.0 新增稳定功能。

流程：

共享目录：

```
test.txt

删除



```

扫描发现：

```
数据库存在

实际文件不存在


```

执行：

```
XWiki REST DELETE


```

日志：

```
发现删除文件:

/data/test.txt


删除XWiki页面:

Main.test


XWiki删除成功

删除完成


```

---

# 5. XWiki REST接口

客户端：

```
clients/xwiki.py


```

功能：

## 测试连接

接口：

```
GET

/rest/wikis/{wiki}/spaces


```

返回：

```
200


```

---

## 创建页面

接口：

```
PUT

/rest/wikis/xwiki/spaces/{space}/pages/{page}


```

---

## 更新页面

同创建接口：

```
PUT


```

XWiki自动判断：

```
新增
或者
版本更新


```

---

## 删除页面

接口：

```
DELETE

/rest/wikis/xwiki/spaces/{space}/pages/{page}


```

成功：

```
200
202
204


```

不存在：

```
404


```

均视为同步成功。

---

# 6. 数据库设计

数据库：

SQLite

用途：

保存同步状态。

主要字段：

<table id="bkmrk-%E5%AD%97%E6%AE%B5-%E8%AF%B4%E6%98%8E-file_path-%E6%96%87%E4%BB%B6%E8%B7%AF%E5%BE%84"><thead><tr><th>字段</th><th>说明</th></tr></thead><tbody><tr><td>file\_path</td><td>文件路径</td></tr><tr><td>hash</td><td>文件SHA</td></tr><tr><td>space</td><td>XWiki空间</td></tr><tr><td>page</td><td>XWiki页面</td></tr><tr><td>deleted</td><td>删除状态</td></tr></tbody></table>

---

# 7. Docker部署

运行模式：

```
Docker Container


```

容器：

```
xwiki-sync


```

依赖：

```
xwiki-web

tika

smb共享


```

网络：

```
Docker bridge


```

---

# 8. 配置文件

文件：

```
config.yaml


```

包含：

## XWiki

例如：

```yaml
xwiki:
  url: http://xwiki-web:8080
  wiki: xwiki
  user: admin
  password: ****

```

---

## SMB

例如：

```yaml
smb:
  server:
  share:
  username:
  password:

```

---

## 同步周期

例如：

```yaml
interval: 60


```

单位：

秒

---

# 9. 日志说明

正常：

```
发现文件 3 个


```

新增：

```
新文件:

xxx


```

跳过：

```
跳过:

xxx 未变化


```

删除：

```
发现删除文件

删除XWiki页面

XWiki删除成功


```

异常：

```
同步失败


```

---

# 10. 已知设计特点

## 优点

### 1. 增量同步

不会重复处理大量文档。

### 2. 状态可恢复

数据库保存状态。

### 3. 支持中文名称

例如：

```
新建空间测试1

主从复制_2025030401


```

### 4. XWiki自动版本管理

更新不会覆盖历史。

---

# 11. 当前限制

## 11.1 空间创建

目前：

```
create_space()


```

XWiki REST 返回：

```
405 Method Not Allowed


```

原因：

XWiki默认不允许REST创建Space。

当前策略：

```
忽略Space创建失败

继续创建页面


```

实际运行正常。

---

## 11.2 删除空间

未实现。

删除：

```
页面


```

不删除：

```
Space


```

---

## 11.3 附件同步

当前：

```
文件内容同步


```

不是：

```
XWiki Attachment


```

---

# 12. 稳定性验证记录

## 新增测试

文件：

```
/data/wiki_attach/docker镜像导出和导入.txt


```

结果：

```
同步完成


```

---

## 删除测试

删除：

```
docker镜像导出和导入.txt

创建容器四代网关协议代理适配器rulr-v4gw-adapter.txt


```

结果：

```
XWiki删除成功


```

---

## 连续运行测试

周期：

```
60秒


```

结果：

```
无重复同步

无异常


```

---

# 13. 版本状态

当前版本：

```
xwiki-sync v1.0 Stable


```

状态：

```
生产可用


```

已验证：

<table id="bkmrk-%E5%8A%9F%E8%83%BD-%E7%8A%B6%E6%80%81-%E6%96%B0%E5%A2%9E%E5%90%8C%E6%AD%A5-%E2%9C%85-%E4%BF%AE%E6%94%B9%E5%90%8C%E6%AD%A5-%E2%9C%85-"><thead><tr><th>功能</th><th>状态</th></tr></thead><tbody><tr><td>新增同步</td><td>✅</td></tr><tr><td>修改同步</td><td>✅</td></tr><tr><td>删除同步</td><td>✅</td></tr><tr><td>中文路径</td><td>✅</td></tr><tr><td>中文页面</td><td>✅</td></tr><tr><td>DOCX解析</td><td>✅</td></tr><tr><td>TXT解析</td><td>✅</td></tr><tr><td>XWiki REST</td><td>✅</td></tr><tr><td>Docker运行</td><td>✅</td></tr><tr><td>断点恢复</td><td>✅</td></tr></tbody></table>

---

# 14. 后续规划建议

v1.1：

- 增加附件上传
- 增加XWiki标签
- 增加文档权限映射
- 增加同步失败重试队列

v1.2：

- Web管理界面
- 同步状态监控
- 操作审计日志

---

# 结论

**xwiki-sync v1.0 已完成共享目录到 XWiki 文档中心的自动化同步闭环。**

当前版本满足：

> 企业内部文档自动归档、同步、删除管理需求。

可作为生产环境基础版本长期运行。

---

建议归档：

```
/opt/xwiki/sync/docs/
        |
        └── xwiki-sync-v1.0功能说明书.md


```

同时建议备份：

```
config.yaml
database.db
Dockerfile

```

作为 v1.0 基线版本。

# Ubuntu 24.04 + Docker，部署 LiteLLM v1.87.0

你当前环境是 **Ubuntu 24.04 + Docker**，部署 LiteLLM v1.87.0 最推荐使用 **Docker Compose**，比官方单行 `docker run` 更适合生产环境（持久化、数据库、配置、密钥管理）。

下面给你一个完整部署方案。

---

# 一、环境准备

安装 Docker：

```
#Ubuntu24.04 安装Docker&Compose

sudo apt update && sudo apt install -y ca-certificates curl gnupg lsb-release git

# 重新下载密钥并生成统一签名环文件
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 赋予可读权限
sudo chmod 644 /usr/share/keyrings/docker-archive-keyring.gpg

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 开机自启
sudo systemctl enable --now docker
# 当前用户免sudo操作docker
sudo usermod -aG docker $USER
# 刷新用户组，不用重启服务器
newgrp docker

# 验证Docker安装

docker --version
docker compose version

```

配置国内docker加速器：

```
mkdir -p /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com"
  ]
}
EOF
systemctl daemon-reload
systemctl restart docke
```

确认 Docker：

```bash
docker --version
docker compose version

```

建议：

```text
Docker >= 24
Docker Compose >= 2.x

```

---

# 二、创建目录

例如：

```bash
mkdir -p /opt/litellm
cd /opt/litellm

```

目录：

```text
/opt/litellm
├── docker-compose.yml
├── .env
└── config.yaml

```

---

# 三、创建 LiteLLM 配置

## config.yaml

```bash
vi config.yaml

```

内容：

```yaml
model_list:

  # OpenAI 示例
  - model_name: gpt-5
    litellm_params:
      model: openai/gpt-5
      api_key: os.environ/OPENAI_API_KEY


  # Gemini 示例
  - model_name: gemini-3.5-flash
    litellm_params:
      model: vertex_ai/gemini-3.5-flash
      api_key: os.environ/GEMINI_API_KEY


general_settings:

  master_key: os.environ/LITELLM_MASTER_KEY

  # 开启数据库存储
  store_model_in_db: true

```

---

# 四、创建环境变量

## .env

```bash
vi .env

```

例如：

```env
LITELLM_MASTER_KEY=sk-litellm-admin-123456

OPENAI_API_KEY=sk-xxxx

GEMINI_API_KEY=xxxx

```

---

# 五、Docker Compose 部署（推荐）

创建：

```bash
vi docker-compose.yml

```

内容：

```yaml
services:

  litellm:
    image: ghcr.io/berriai/litellm:1.87.0

    container_name: litellm

    restart: always

    ports:
      - "4000:4000"

    environment:

      STORE_MODEL_IN_DB: "True"

      DATABASE_URL: postgresql://litellm:litellm@postgres:5432/litellm

      LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY}

      OPENAI_API_KEY: ${OPENAI_API_KEY}

      GEMINI_API_KEY: ${GEMINI_API_KEY}


    volumes:

      - ./config.yaml:/app/config.yaml


    command:
      --config /app/config.yaml


    depends_on:
      - postgres



  postgres:

    image: postgres:16

    container_name: litellm-postgres

    restart: always


    environment:

      POSTGRES_DB: litellm

      POSTGRES_USER: litellm

      POSTGRES_PASSWORD: litellm


    volumes:

      - ./postgres:/var/lib/postgresql/data

```

---

# 六、启动

执行：

```bash
# 通过南大ghcr代理拉取镜像
docker pull ghcr.nju.edu.cn/berriai/litellm:1.87.0
# 还原原始镜像标签，适配compose
docker tag ghcr.nju.edu.cn/berriai/litellm:1.87.0 ghcr.io/berriai/litellm:1.87.0
docker rmi ghcr.nju.edu.cn/berriai/litellm:1.87.0

docker compose up -d

```

查看：

```bash
docker ps

```

应该：

```text
litellm
litellm-postgres

```

---

查看日志：

```bash
docker logs -f litellm

```

正常：

```text
LiteLLM Proxy Server Started
Server running on port 4000

```

---

# 七、测试 API

LiteLLM 默认兼容 OpenAI API。

测试：

```bash
curl http://127.0.0.1:4000/v1/models \
-H "Authorization: Bearer sk-litellm-admin-123456"

```

返回：

```json
{
 "data":[
   {
    "id":"gpt-5"
   }
 ]
}

```

---

测试聊天：

```bash
curl http://127.0.0.1:4000/v1/chat/completions \
-H "Authorization: Bearer sk-litellm-admin-123456" \
-H "Content-Type: application/json" \
-d '
{
 "model":"gpt-5",
 "messages":[
   {
    "role":"user",
    "content":"hello"
   }
 ]
}'

```

---

# 八、访问管理后台

LiteLLM v1.87 有 Dashboard。

访问：

```
http://服务器IP:4000/ui

```

例如：

```
http://192.168.4.21:4000/ui

```

使用：

```
Master Key:
sk-litellm-admin-123456

```

登录。

---

# 九、如果只是测试（官方方式）

不需要 PostgreSQL：

```bash
docker run \
-d \
--name litellm \
-p 4000:4000 \
-e STORE_MODEL_IN_DB=True \
docker.litellm.ai/berriai/litellm:1.87.0

```

但是：

缺点：

- 配置丢失
- 无数据库
- 无用户管理
- 无 Key 管理

不建议生产。

---

# 十、结合你之前的环境（Dify / RAGFlow）

你的环境里已经有：

- Dify
- RAGFlow
- Keycloak
- PostgreSQL
- Docker Compose

LiteLLM 很适合作为统一 AI Gateway：

架构：

```
                 Dify
                   |
                   |
               OpenAI API
                   |
                   v
              LiteLLM 4000
                   |
     +-------------+-------------+
     |             |             |
  OpenAI       Gemini       Ollama
     |
  Azure OpenAI

```

Dify 中配置：

模型类型：

```
OpenAI Compatible

```

Base URL:

```
http://litellm:4000/v1

```

API Key:

```
sk-litellm-admin-123456

```

即可。

---

# 十一、生产建议

如果是你的服务器环境，我建议：

```
Ubuntu 24.04
        |
Docker
        |
Nginx HTTPS
        |
LiteLLM 1.87
        |
PostgreSQL 16
        |
Keycloak OAuth

```

再加：

- Redis（限流）
- Prometheus（监控）
- Grafana（Dashboard）

---

你这里的：

```env
LITELLM_MASTER_KEY=sk-litellm-admin-123456

```

就是 LiteLLM Dashboard 登录密码（Master Key）。

修改方法如下。

---

## 1. 修改 `.env`

编辑：

```bash
cd /opt/litellm
vi .env

```

例如改成：

```env
LITELLM_MASTER_KEY=sk-litellm-admin-9f83a7d2c1e54b6a

OPENAI_API_KEY=sk-xxxx

GEMINI_API_KEY=xxxx

```

建议生成随机值：

```bash
openssl rand -hex 32

```

例如：

```
a9d7f3e8b4c1d2e6f7a8b9c0d1e2f3456789abcd

```

然后：

```env
LITELLM_MASTER_KEY=sk-a9d7f3e8b4c1d2e6f7a8b9c0d1e2f3456789abcd

```

---

## 2. 重启 LiteLLM

因为环境变量是在容器启动时读取：

```bash
docker compose down

docker compose up -d

```

或者：

```bash
docker compose restart litellm

```

如果 `.env` 被 compose 读取，推荐：

```bash
docker compose up -d --force-recreate litellm

```

确保新环境变量进入容器。

---

## 3. 验证新 Key

查看容器：

```bash
docker exec litellm env | grep LITELLM_MASTER_KEY

```

应该看到：

```text
LITELLM_MASTER_KEY=sk-litellm-admin-9f83a7d2c1e54b6a

```

---

## 4. Dashboard重新登录

访问：

```
http://服务器IP:4000/ui

```

输入：

```
Master Key:
sk-litellm-admin-9f83a7d2c1e54b6a

```

即可。

---

## 注意：不要只改 `.env` 后 restart

很多人这里容易踩坑。

例如：

```bash
vi .env
docker compose restart litellm

```

有时不会重新加载环境变量，因为容器已经存在。

确认：

```bash
docker inspect litellm | grep LITELLM_MASTER_KEY

```

如果还是旧值，需要：

```bash
docker compose up -d --force-recreate litellm

```

---

## 生产环境建议

你当前：

```env
LITELLM_MASTER_KEY=sk-litellm-admin-123456

```

属于测试密码。

建议：

```env
LITELLM_MASTER_KEY=sk-prod-$(openssl rand -hex 32)

```

并且：

- Master Key 只用于管理 Dashboard
- Dify/RAGFlow 使用单独生成的 API Key
- 不要把 Master Key 放到应用配置里

后续如果接 Dify，可以在 LiteLLM Dashboard 创建：

```
Keys → Generate Key

```

例如：

```
sk-dify-prod-xxxx

```

然后 Dify 使用这个，而不是 Master Key。

你的 LiteLLM 已经部署好了，现在添加阿里百炼（DashScope / Model Studio）的 **qwen3.7-max** 很简单。

LiteLLM 对百炼支持 OpenAI Compatible 接口，配置方式和 OpenAI 类似，只需要指定：

- `model`
- `api_base`
- `api_key`

阿里云百炼 qwen3.7-max 提供 OpenAI 兼容接口，模型 ID 为：

```text
qwen3.7-max

```

对应接口地址可以使用百炼 OpenAI Compatible Endpoint。([AlibabaCloud](https://www.alibabacloud.com/help/en/model-studio/models?utm_source=chatgpt.com "Supported Models and Capabilities Overview - Model Studio - Alibaba Cloud - Alibaba Cloud Model Studio - Alibaba Cloud Documentation Center"))

---

## 1. 修改 .env

你现在：

```bash
cat /opt/litellm/.env

```

类似：

```env
LITELLM_MASTER_KEY=sk-litellm-admin-123456

OPENAI_API_KEY=sk-xxxx

GEMINI_API_KEY=xxxx

```

增加：

```env
DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxxxx

```

例如：

```env
LITELLM_MASTER_KEY=sk-litellm-admin-123456

OPENAI_API_KEY=sk-xxxx

GEMINI_API_KEY=xxxx

DASHSCOPE_API_KEY=sk-abcd123456789

```

这个 Key 在：

阿里云百炼控制台 → API Key 管理

创建。

---

## 2. 修改 LiteLLM config.yaml

假设你的配置：

```bash
/opt/litellm/config.yaml

```

增加：

```yaml
model_list:

  - model_name: gpt-5
    litellm_params:
      model: openai/gpt-5
      api_key: os.environ/OPENAI_API_KEY


  - model_name: gemini-3.5-flash
    litellm_params:
      model: gemini/gemini-3.5-flash
      api_key: os.environ/GEMINI_API_KEY


  # 阿里百炼 qwen3.7-max
  - model_name: qwen3.7-max
    litellm_params:
      model: openai/qwen3.7-max
      api_base: https://dashscope.aliyuncs.com/compatible-mode/v1
      api_key: os.environ/DASHSCOPE_API_KEY

```

LiteLLM 的 `model_name` 是暴露给 Dify/RAGFlow 的名字，`litellm_params.model` 是实际供应商模型。([docs.litellm.com.cn](https://docs.litellm.com.cn/docs/proxy/configs?utm_source=chatgpt.com "概览 | liteLLM 网关"))

---

## 3. 重启 LiteLLM

因为 `.env` 修改了：

不要只 restart。

执行：

```bash
cd /opt/litellm

docker compose up -d --force-recreate litellm

```

查看：

```bash
docker compose logs -f litellm

```

---

## 4. 检查模型是否出现

执行：

```bash
curl http://127.0.0.1:4000/v1/models \
-H "Authorization: Bearer sk-litellm-admin-123456"

```

应该看到：

```json
{
 "data":[
   {
     "id":"gpt-5"
   },
   {
     "id":"gemini-3.5-flash"
   },
   {
     "id":"qwen3.7-max"
   }
 ]
}

```

---

## 5. 测试 qwen3.7-max

```bash
curl http://127.0.0.1:4000/v1/chat/completions \
-H "Authorization: Bearer sk-litellm-admin-123456" \
-H "Content-Type: application/json" \
-d '
{
 "model":"qwen3.7-max",
 "messages":[
   {
    "role":"user",
    "content":"介绍一下阿里百炼"
   }
 ]
}'

```

成功返回：

```json
{
 "choices":[
   {
    "message":{
      "content":"..."
    }
   }
 ]
}

```

---

## 6. 给 Dify 使用

你现在 Dify 调 LiteLLM，建议暴露统一名字：

例如：

```yaml
- model_name: qwen-max
  litellm_params:
    model: openai/qwen3.7-max
    api_base: https://dashscope.aliyuncs.com/compatible-mode/v1
    api_key: os.environ/DASHSCOPE_API_KEY

```

以后 Dify 只配置：

```
qwen-max

```

以后换：

```
qwen3.7-max
↓
qwen4-max
↓
DeepSeek

```

Dify 不需要改。

---

## 7. 你的最终架构会变成

```
              Dify
                |
                |
          OpenAI API格式
                |
                |
          LiteLLM 1.87
                |
    +-----------+------------+
    |           |            |
 GPT-5     Gemini       Qwen3.7-Max
 OpenAI    Google       阿里百炼

```

这正适合你之前的 Dify + RAGFlow + 企业知识库架构。

另外注意：你之前日志里 `/v1/responses` 是 OpenAI Responses API，如果后续用 Codex/Agent 类客户端调用 qwen3.7-max，需要确认该模型端点对 Responses API 的兼容性；Dify 通常走 `/v1/chat/completions`，问题会少一些。

# win11本地部署Codex机器人

收到！"Codex 机器人"一般指 OpenAI 的 \*\*Codex CLI\*\* —— 一个跑在终端里的 AI 编程助手。Windows 11 原生支持，不用装 WSL。我先给你画个整体流程图，再上保姆级步骤。  
先看整体流程，一共 5 步，10 分钟内能搞定：  
下面是保姆级教程，全部在 \*\*PowerShell\*\*（开始菜单搜 "PowerShell"，建议以管理员身份打开）里操作。

\---

\## 一、先说清楚 Codex 是什么

Codex CLI 是 OpenAI 官方的\*\*终端 AI 编程助手\*\*，开源在 GitHub（`openai/codex`）。它能：  
\- 用自然语言写代码、改 Bug、重构  
\- 直接读写你本地的项目文件  
\- 在终端里自动执行命令（装依赖、跑测试）

\*\*Windows 11 原生支持，不需要装 WSL。\*\* 前提是你有 ChatGPT Plus/Pro/Business/Edu 订阅，或者 OpenAI API Key。

\## 二、安装 Node.js（必备）

```powershell  
\# 1. 先看装没装  
node -v  
npm -v  
```

如果没装，用 Windows 自带的 winget 一条命令搞定：

```powershell  
winget install --id OpenJS.NodeJS.LTS -e  
```

装完\*\*关掉 PowerShell 重新打开\*\*，再验证 `node -v` 能输出版本号（如 v22.x）。

\## 三、放行执行策略（90% 的人卡在这步）

不先做这步，npm 会报 `无法加载文件 ...npm.ps1，因为在此系统上禁止运行脚本`：

```powershell  
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned  
```

输入 `Y` 确认。只对当前用户生效，不影响系统其他人。

\## 四、安装 Codex CLI

```powershell  
\# 国内网络慢的话，用 npmmirror 镜像加速（推荐）  
npm install -g @openai/codex --registry=https://registry.npmmirror.com

\# 验证版本  
codex --version  
```

&gt; 如果提示 `codex` 找不到命令：执行 `npm config get prefix` 拿到全局安装路径，把它加到系统环境变量 PATH 里，然后重开终端。

\## 五、登录认证

输入 `codex` 启动，首次运行会让你选择登录方式：

| 方式 | 适用人群 | 说明 |  
|------|---------|------|  
| \*\*ChatGPT 账号登录\*\* | 有 Plus/Pro 订阅 | 会弹浏览器完成授权，最省事 |  
| \*\*API Key\*\* | 有 OpenAI API 账号 | 在 platform.openai.com 生成 `sk-...` 密钥 |

也可以写配置文件永久生效，路径为 `%USERPROFILE%\\.codex\\config.toml`：

```toml  
model = "gpt-5.4-codex"  
model\_provider = "openai"  
```

\## 六、国内网络怎么解决

\- \*\*npm 下载慢\*\* → 已经用镜像解决了（上面命令里的 `--registry`）。  
\- \*\*登录/调用 OpenAI 慢或失败\*\* → 需要能访问 OpenAI 的网络环境，或使用\*\*合法合规\*\*的 API 中转服务。若走中转，在 `config.toml` 里加：

```toml  
model\_provider = "openai"  
base\_url = "https://你的中转服务地址/v1"  
api\_key = "sk-你的中转key"  
model = "gpt-5.4-codex"  
```

⚠️ 提醒：请务必使用合法合规的服务渠道，遵守相关法律法规和 OpenAI 使用条款。

\## 七、开始使用

```powershell  
codex  
```

进入交互界面后直接说需求，比如：  
\- `帮我创建一个 Express 项目的基本结构`  
\- `把项目里所有 console.log 改成 logger.info`  
\- `给这个函数写 10 个单元测试`

会话内常用命令：`/model` 切换模型、`/approval-mode` 控制自动执行还是逐步确认。

\## 八、常见问题速查

| 症状 | 原因 | 解决 |  
|------|------|------|  
| npm 报执行策略错误 | 没放行脚本 | 执行第三步的命令 |  
| `npm install` 报 EPERM | 权限不足 | 用管理员 PowerShell，或把全局目录切到 `$env:APPDATA\\npm` |  
| `codex` 找不到命令 | PATH 没配 | `npm config get prefix` 查路径后加入系统 PATH |  
| 启动报缺 api-ms-win-crt | 缺 VC++ 运行库 | 安装 Visual C++ Redistributable |  
| 版本装完启动失败 | 个别版本有兼容 bug | 降级：`npm install -g @openai/codex@0.119.0` |

升级到最新版：`npm install -g @openai/codex@latest`

\---

需要的话，我可以直接帮你把环境变量配置写成一个一键脚本，或者帮你写一个 `config.toml` 模板文件，要不要？

# WorkBuddy 500个神级用法， 看完你还用不好算我输

<div class="rich_media_meta_list" id="bkmrk-" style="margin:0px 0px 22px;padding:0px;line-height:20px;font-size:0px;color:rgba(0,0,0,0.9);font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><span class="rich_media_meta rich_media_meta_nickname" id="bkmrk--1" style="margin:0px 10px 10px 0px;padding:0px;display:inline-block;vertical-align:middle;font-size:15px;"></span><span id="bkmrk--2" style="margin:0px;padding:0px;"></span></div><div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-%E5%88%AB%E8%A2%AB%E6%95%B0%E5%AD%97%E5%90%93%E5%88%B0%EF%BC%9A%E8%BF%99%E6%98%AF%E4%B8%80%E5%BC%A0%E5%8F%AF%E4%BB%A5%E6%90%9C%E7%B4%A2%E7%9A%84%E5%B7%A5%E4%BD%9C%E5%9C%B0%E5%9B%BE" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><section style="margin:0px 0px 24px;padding:27px 2px 6px;max-width:100%;color:rgb(36,38,41);font-family:'-apple-system', BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;font-size:medium;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;visibility:visible;"><span style="margin:0px;padding:0px;max-width:100%;color:rgb(232,229,223);font-family:'-apple-system', BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;font-size:16px;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;background-color:rgb(36,38,41);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline;visibility:visible;"><span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">别被数字吓到：这是一张可以搜索的工作地图。找到一个动作，套上任务单，就能开始。</span></span>

<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;visibility:visible;">AI 工具最容易让人产生一种错觉：功能越多，自己越应该会用。结果打开输入框，还是不知道该交代什么。</span></span>

<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;visibility:visible;">500 个用法的意义，不是让你收藏 500 条咒语，而是把“我想提高效率”拆成 500 个具体动作：整理一份文件、解释一张报表、准备一场会议、追踪一个指标。</span></span>

<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;visibility:visible;">先从一个真实任务开始。能交付，才算用上。</span></span>

</section><section style="margin:23px 0px 9px;padding:18px;max-width:100%;color:rgb(36,38,41);font-family:'-apple-system', BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;font-size:medium;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(230,240,237);border-top:4px solid rgb(40,125,112);border-bottom:1px solid rgb(184,204,198);visibility:visible;"><span style="margin:0px;padding:0px;max-width:100%;visibility:visible;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;visibility:visible;">万能任务单：把地图里的短动作变成可执行指令</span></span>

<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;visibility:visible;">你是【角色】。请读取【材料位置】，完成【具体任务】。输出【文件/表格/摘要/草稿】；质量标准是【口径、长度、字段、格式】。不要【删除/覆盖/发送/猜测】；先给【计划/样本/预览】，我确认后再执行。完成后报告【成功、失败、异常、日志位置】。</span></span>

</section><section style="margin:0px 0px 24px;padding:25px 0px 5px;max-width:100%;color:rgb(36,38,41);font-family:'-apple-system', BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;font-size:medium;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;visibility:visible;">**<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;visibility:visible;">01—10</span></span>**<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;visibility:visible;"> 文件与办公</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">11—20</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 内容与传播</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">21—30</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 业务与组织</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">31—40</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 数据与技术</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">41—50</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 自动化与个人</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">每个领域 10 个动作，共 500 个索引</span></span>

</section><section style="margin:0px 0px 24px;padding:26px 0px 4px;max-width:100%;color:rgb(36,38,41);font-family:'-apple-system', BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;font-size:medium;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">MAP 01 / 01—10</span></span>

## <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">文件与办公：把杂事变成清单</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">01 文件整理</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 批量分类 · 重复查找 · 目录树 · 归档方案 · 批量改名 · 文件检索 · 版本对照 · 权限清单 · 交接目录 · 清理预览</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">02 PDF 与文档</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> PDF 摘要 · PDF 转 Word · 表格提取 · OCR 检查 · 文档合并 · 章节重排 · 页码核对 · 引用提取 · 文档比对 · 问题清单</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">03 表格办公</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 表格合并 · 字段统一 · 数据透视 · 重复筛查 · 缺失统计 · 格式统一 · 公式解释 · 条件标记 · 汇总表 · 处理日志</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">04 邮件沟通</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 主题拟定 · 正文起草 · 语气改写 · 附件检查 · 回复摘要 · 催办邮件 · 婉拒邮件 · 感谢邮件 · 跨部门邮件 · 发送预览</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">05 日程会议</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 周计划 · 冲突检测 · 时间块 · 会议邀请 · 会议议程 · 会议纪要 · 决策树 · 待办表 · 会后跟进 · 提醒草案</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">06 个人效率</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 今日排序 · 番茄钟计划 · 截止日拆解 · 专注清单 · 任务估时 · 精力分配 · 复盘模板 · 习惯追踪 · 代办合并 · 下班总结</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">07 工作报告</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 日报 · 周报 · 月报 · 季度总结 · 述职稿 · 一页摘要 · 进展同步 · 风险报告 · 项目复盘 · 管理层摘要</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">08 翻译校对</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 中英翻译 · 术语表 · 双语对照 · 错别字 · 标点检查 · 语法检查 · 风格统一 · 数字核对 · 引用核查 · 歧义标记</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">09 差旅行政</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 行程方案 · 预算估算 · 会议室安排 · 访客清单 · 物资清单 · 通知公告 · 值班表 · 出差总结 · 报销材料 · 备用方案</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">10 简历求职</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> JD 提取 · 简历匹配 · 经历改写 · 关键词检查 · 项目量化 · 自我介绍 · 面试题库 · 反问清单 · 求职邮件 · 面试复盘</span></span>

</section><section style="margin:0px 0px 24px;padding:28px 0px 4px;max-width:100%;color:rgb(36,38,41);font-family:'-apple-system', BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;font-size:medium;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">MAP 02 / 11—20</span></span>

## <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">内容与传播：从一个想法到一套内容</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">11 文章写作</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 主题拆解 · 核心观点 · 文章大纲 · 开头冲突 · 案例补充 · 论据检查 · 结尾提问 · 长文初稿 · 文章摘要 · 事实清单</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">12 短内容</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 小红书笔记 · 朋友圈文案 · 微博短帖 · 评论回复 · 置顶文案 · 金句提取 · 长文拆条 · 问答回答 · 社群通知 · 互动问题</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">13 视频脚本</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 3秒钩子 · 口播稿 · 分镜表 · 字幕稿 · 直播提纲 · 产品演示 · 培训视频 · 访谈提问 · 结尾行动 · 拍摄清单</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">14 PPT 表达</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 逐页大纲 · 目录页 · 数据页 · 对比页 · 时间线 · 结尾页 · 演讲备注 · 过渡话术 · Q&amp;A · 页面核对</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">15 公众号运营</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 选题池 · 标题测试 · 摘要 · 排版稿 · 配图位置 · 发布检查 · 读者提问 · 内容复盘 · 栏目规划 · 月度日历</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">16 设计创意</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 海报 brief · 配色方案 · 字体搭配 · 页面线框 · 设计说明 · 灵感搜集 · 视觉关键词 · 组件清单 · 作品集文案 · 评审意见</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">17 内容增长</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 用户画像 · 选题评分 · 热点筛选 · 内容漏斗 · 转化路径 · A/B 标题 · 评论分析 · 复购引导 · 渠道适配 · 周期复盘</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">18 品牌传播</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 品牌定位 · Slogan · 语气指南 · 关键词库 · 新闻稿 · FAQ · 媒体问答 · 案例故事 · 活动文案 · 危机回应</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">19 内容质检</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 事实核验 · 版权检查 · 夸张识别 · 敏感词 · 隐私检查 · 逻辑检查 · 引用格式 · 链接检查 · 版本记录 · 发布审批</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">20 多平台分发</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 公众号版 · 小红书版 · 视频号版 · 知乎版 · 邮件版 · 社群版 · 口播版 · 海报版 · 摘要版 · 统一事实底稿</span></span>

</section><section style="margin:0px 0px 24px;padding:28px 0px 4px;max-width:100%;color:rgb(36,38,41);font-family:'-apple-system', BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;font-size:medium;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">MAP 03 / 21—30</span></span>

## <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">业务与组织：让协作少开几次会</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">21 销售</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 客户画像 · 需求挖掘 · 跟进话术 · 异议处理 · 卖点提炼 · 报价说明 · 方案摘要 · 客户复盘 · 销售周报 · 预测清单</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">22 客服电商</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 商品标题 · 详情页 · 活动方案 · 客服话术 · 催付回复 · 差评回应 · 直播脚本 · 评价归类 · 退换货说明 · FAQ</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">23 客户成功</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 交付计划 · 客户培训 · 使用报告 · 健康度 · 风险预警 · 续约提醒 · 需求归档 · 回访提纲 · 案例采集 · 服务复盘</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">24 市场调研</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 行业扫描 · 竞品矩阵 · 定价对比 · 用户访谈 · 问卷设计 · 反馈主题 · 渠道分析 · 趋势摘要 · 证据清单 · 未知项</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">25 产品经理</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> PRD 框架 · 用户故事 · 验收标准 · 原型说明 · 需求排序 · 竞品分析 · 版本公告 · 需求评审 · 变更评估 · 发布清单</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">26 项目管理</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 项目章程 · WBS · 里程碑 · 风险矩阵 · 资源分配 · 周报 · 变更请求 · 干系人 · 复盘 · 收尾</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">27 团队协作</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> RACI · 站会模板 · 异步同步 · 决策记录 · 任务分派 · 跨部门邮件 · 协作规则 · 会议纠偏 · 共识整理 · 经验沉淀</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">28 HR 招聘</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> JD · 简历筛选 · 面试题 · 评分表 · 入职计划 · 培训大纲 · 绩效反馈 · 离职面谈 · 人才盘点 · HR FAQ</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">29 财务采购</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 发票初筛 · 报销检查 · 预算差异 · 现金流 · 供应商评估 · 付款清单 · 成本拆解 · 合规提示 · 盈亏平衡 · 管理摘要</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">30 管理沟通</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 向上汇报 · 延期说明 · 请示话术 · 反馈表达 · 婉拒 · 催办 · 感谢 · 冲突回应 · 通知 · 领导摘要</span></span>

</section><section style="margin:0px 0px 24px;padding:28px 0px 4px;max-width:100%;color:rgb(36,38,41);font-family:'-apple-system', BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;font-size:medium;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">MAP 04 / 31—40</span></span>

## <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">数据与技术：把原始信息变成判断</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">31 数据清洗</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 去重 · 缺失诊断 · 日期统一 · 金额统一 · 异常标记 · 字段映射 · 数据字典 · 质量报告 · 清洗日志 · 原始备份</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">32 数据统计</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 均值 · 中位数 · 分位数 · 方差 · 分组汇总 · 交叉表 · 同比 · 环比 · 占比 · 指标口径</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">33 可视化</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 趋势图 · 柱状图 · 散点图 · 漏斗图 · 雷达图 · 热力图 · KPI 卡 · 仪表盘 · 配色 · 误读检查</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">34 业务分析</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 销售拆解 · 用户分层 · 复购分析 · 转化漏斗 · ROI · 渠道贡献 · 价格分析 · 资源效率 · 机会点 · 行动建议</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">35 调研分析</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 样本概况 · 无效样本 · 频数 · 交叉分析 · 开放题 · 主题提取 · 情感分类 · 偏差说明 · 原话匿名 · 结论限制</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">36 时间序列</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 移动平均 · 季节分解 · 趋势识别 · 峰值 · 谷值 · 预测草案 · 区间说明 · 突破点 · 变化原因 · 验证计划</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">37 SQL 数据库</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 单表查询 · 多表关联 · 分组统计 · 去重 · 窗口函数 · 安全更新 · 事务保护 · 索引建议 · 执行计划 · 字段注释</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">38 代码开发</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 函数生成 · 代码解释 · 重构 · 单元测试 · Bug 定位 · 日志补充 · API 文档 · 参数校验 · 错误处理 · 发布说明</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">39 运维安全</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 故障 SOP · 监控指标 · 告警规则 · 备份策略 · 恢复演练 · 权限审计 · 威胁建模 · 安全加固 · 回滚方案 · 事件复盘</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">40 技术文档</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 技术方案 · ADR · 数据模型 · 接口文档 · 用户手册 · 变更日志 · 部署说明 · FAQ · 测试报告 · 验收标准</span></span>

</section><section style="margin:0px 0px 24px;padding:28px 0px 4px;max-width:100%;color:rgb(36,38,41);font-family:'-apple-system', BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;font-size:medium;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">MAP 05 / 41—50</span></span>

## <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">自动化与个人：让好方法重复出现</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">41 自动化触发</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 定时任务 · 文件触发 · 状态触发 · 日报生成 · 周报汇总 · 异常提醒 · 失败重试 · 日志记录 · 权限检查 · 停止开关</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">42 信息监控</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 网站更新 · 竞品变化 · 行业早报 · 价格变动 · 招聘动态 · 政策公告 · 内容关键词 · 页面差异 · 去重提醒 · 来源留存</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">43 文件自动化</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 备份 · 批量归档 · 格式转换 · 重命名 · 压缩 · 文件清单 · 版本保留 · 空间检查 · 恢复测试 · 变更报告</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">44 知识库</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 资料摘要 · 标签 · FAQ · 知识图谱 · 版本差异 · 过期识别 · 冲突识别 · 搜索索引 · 学习卡片 · 更新日志</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">45 学习研究</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 课程大纲 · 概念解释 · 费曼讲解 · 问答卡 · 错题分析 · 阅读摘要 · 论文拆解 · 研究计划 · 复习提醒 · 模拟面试</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">46 语言跨境</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 邮件翻译 · 会议口译稿 · 术语对照 · 双语摘要 · 文化差异 · 表达润色 · 简历翻译 · 合同初译 · 字幕草稿 · 语气转换</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">47 合规审查</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 隐私扫描 · 版权提示 · 广告用语 · 合同风险点 · 数据脱敏 · 权限清单 · 发布检查 · 记录留痕 · 人工复核项 · 风险分级</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">48 个人财务</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 消费归类 · 月度预算 · 账单摘要 · 订阅检查 · 目标拆解 · 旅行预算 · 报销清单 · 保险资料 · 现金流草案 · 风险提醒</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">49 生活计划</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 旅行路线 · 购物清单 · 菜谱规划 · 搬家清单 · 家庭日程 · 运动计划 · 阅读计划 · 礼物建议 · 物品整理 · 周末安排</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">50 个性化助手</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;"> 风格切换 · 角色设定 · 偏好记录 · 回复模板 · 语音摘要 · 快速查询 · 离线待办 · 本地搜索 · 每周复盘 · 个人工作手册</span></span>

</section><section style="margin:0px 0px 24px;padding:31px 0px 6px;max-width:100%;color:rgb(36,38,41);font-family:'-apple-system', BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;font-size:medium;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">12 COPY-READY TASK SHEETS</span></span>

## <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">地图只是索引，下面 12 张任务单可以直接改</span></span>

### <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">任务单 A：月度报告</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">你是数据分析师。读取【月份】【业务类型】的【数据文件】，先输出字段、口径和缺失项，再生成月度报告：数据概览、趋势变化、异常预警、原因假设、3 条行动建议和 5 张图表建议。每个结论附数据位置；不要把推测写成事实。先给大纲和样例，我确认后再生成完整报告。</span></span>

### <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">任务单 B：批量整理文件</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">扫描【文件夹】，按【命名规则】提出归档方案。先输出目录树、重复文件、冲突文件和前 10 个新旧文件名预览；不要移动、删除或覆盖。得到确认后执行，输出成功、失败、跳过、原路径、新路径和变更日志。</span></span>

### <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">任务单 C：把长文拆成内容包</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">读取【长文/录音稿】，先提炼事实底稿和核心观点，再生成公众号文章、小红书笔记、短视频脚本和 5 条封面金句。四种版本保持事实一致，分别适配平台；不编造经历和数据。输出素材缺口、各版本草稿和发布前核对项。</span></span>

### <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">任务单 D：准备一场高效会议</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">根据【会议目标、参与人、背景材料】设计【时长】分钟议程，每段包含目标、主持问题、预计产出和负责人。补充会前材料清单、决策项、风险项和会后行动表。先给议程草案，不创建邀请、不发送消息。</span></span>

### <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">任务单 E：客户反馈变产品建议</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">分析【评论/工单】，先去除个人身份信息，再按主题、情绪、频率、影响范围和紧急程度归类。保留匿名代表原话，输出问题清单、证据、优先级、建议动作和未知项；无法判断的内容标待人工复核。</span></span>

### <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">任务单 F：竞品变化周报</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">每周检查【竞品公开页面清单】，只记录过去 7 天新增或修改的产品、价格、活动和案例。每条保留原链接、页面日期、抓取时间和前后差异；事实与推测分开。无变化时输出“无明确更新”，访问失败要列原因。</span></span>

### <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">任务单 G：做一份可编辑 PPT</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">根据【材料目录】为【听众】制作【页数】页 PPT。先给一句话结论和逐页大纲，我确认后生成。每页一个观点，数据标来源，图表说明口径；输出可编辑文件和检查清单，检查文字溢出、字体替换、单位、页码和空白页。</span></span>

### <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">任务单 H：从数据找异常</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">检查【数据集】中的重复、缺失、逻辑冲突、突增突降和预算偏差。先说明期间、币种、正常范围和检测规则，再输出异常记录、实际值、参考区间、影响和核查建议。不要修改原始数据，不把异常直接判定为业务问题。</span></span>

### <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">任务单 I：把需求拆成项目计划</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">根据【目标、范围、截止日期、团队成员】拆解 WBS，列任务、负责人、工期、依赖、里程碑、风险和验收标准。先给关键路径和资源冲突，再给完整计划；不要替我决定范围变更，变更项单独列出。</span></span>

### <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">任务单 J：建立可恢复的备份</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">为【源目录】设计定时备份到【目标位置】的方案，写明版本命名、加密、保留周期、空间阈值、失败提醒、完整性验证和恢复演练。先输出方案，不删除旧备份；删除前必须展示将被删除的版本并等待确认。</span></span>

### <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">任务单 K：把一封冲突邮件改成建设性沟通</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">读取【邮件/聊天记录】，先提取对方诉求、事实、情绪和待决问题，再提供温和、中性、坚定三版回复。保留我的立场，不承认未经确认的责任，不攻击个人；每版列出风险和建议使用场景，未经确认不要发送。</span></span>

### <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">任务单 L：把一次流程固化成 Skill</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">根据我完成【任务】的 3 次记录，提炼固定输入、执行步骤、异常分支、输出格式、权限要求和验收标准。先给流程图与风险点，我确认后再整理成可复用模板。任何删除、发布、发送和付款动作必须保留人工审批节点。</span></span>

</section><section style="margin:28px 0px 0px;padding:22px 18px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;font-size:medium;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(36,38,41);color:rgb(255,255,255);">## <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">500 个用法，先记住 4 条底线</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">材料底线：</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">没有提供的文件、数据和权限，不能假装已经读取。</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">事实底线：</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">分析、翻译、润色和报告都不能擅自增加事实。</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">动作底线：</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">删除、覆盖、发送、发布、付款和改账，先预览再确认。</span></span>

**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">隐私底线：</span></span>**<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">客户、人事、财务和账号材料先脱敏，专业结论交给专业人员复核。</span></span>

</section><section style="margin:0px 0px 24px;padding:29px 2px 6px;max-width:100%;color:rgb(36,38,41);font-family:'-apple-system', BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;font-size:medium;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;">## <span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">不要收藏 500 个答案，建立你的 5 个常用入口</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">从地图中挑 5 个你每周都会遇到的动作：一个文件类、一个沟通类、一个内容类、一个数据类、一个周期任务。把材料位置和交付格式写成固定变量，每次只替换当周内容。</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">跑过几轮后，把你人工修正的地方补回任务单。你会得到的不是一堆收藏，而是一套真正属于自己的工作台。</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">看完还用不好，通常不是因为缺少第 501 个用法，而是还没把第 1 个任务交代清楚。</span></span>

</section><footer style="margin:24px 0px 0px;padding:23px 2px 3px;max-width:100%;color:rgb(36,38,41);font-family:'-apple-system', BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;font-size:medium;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;border-top:5px solid rgb(40,125,112);"><span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">今天先从一个低风险任务开始。</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">当 WorkBuddy 能稳定收到材料、按步骤执行、交回文件，并清楚告诉你哪里失败，它才真正从聊天工具变成了工作助手。</span></span>

<span style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;font-size:14px;">定时任务、外部平台、浏览器操作和本地文件能力依赖当前版本、连接器和账号权限。权限不足时应明确报告，不能假装执行完成。</span></span>

</footer></div>

# computer-use 插件的API 和使用方法

现在我已经完整了解了 computer-use 插件的全部 API 和使用方法。以下是详细的使用示例说明：

---

## Computer Use 插件使用指南

Computer Use 插件可以通过 `@oai/sky` 库自动化控制 Windows 应用程序的 UI，支持截图、点击、输入、滚动、拖拽等操作，即使窗口被遮挡也能工作。

---

### 初始化

每次使用前需要先初始化 sky 对象：

```
if (!globalThis.sky) {
  const { sky } = await import("@oai/sky");
  globalThis.sky = sky;
}
```

---

### 示例 1：列出所有已打开的应用和窗口

```
globalThis.apps = await sky.list_apps();
nodeRepl.write(JSON.stringify(apps, null, 2));
```

---

### 示例 2：选择目标窗口并激活

```
// 假设从 list_apps 结果中找到记事本
globalThis.targetApp = apps.find((app) => app.id === "notepad.exe");
globalThis.targetWindow = await sky.get_window({
  id: targetApp.windows[0].id,
  app: targetApp.windows[0].app,
});
await sky.activate_window({ window: targetWindow });
```

---

### 示例 3：获取窗口状态（截图 + 无障碍树）

```
globalThis.state = await sky.get_window_state({
  window: targetWindow,
  include_screenshot: true,
  include_text: true,
});
globalThis.targetWindow = state.window;
// 查看无障碍树中的元素索引
nodeRepl.write(String(state.accessibility?.tree || ""));
```

---

### 示例 4：点击元素（通过无障碍树索引）

```
// element_index 来自上一步无障碍树中看到的索引号
await sky.click({ window: targetWindow, element_index: 12 });
```

### 示例 4b：点击坐标

```
// 基于窗口相对坐标点击
await sky.click({ window: targetWindow, x: 200, y: 150 });
```

---

### 示例 5：输入文本

```
await sky.type_text({ window: targetWindow, text: "Hello, World!" });
```

---

### 示例 6：按键 / 快捷键

```
// 按回车
await sky.press_key({ window: targetWindow, key: "Return" });

// Ctrl+A 全选
await sky.press_key({ window: targetWindow, key: "Control_L+a" });

// Ctrl+C 复制
await sky.press_key({ window: targetWindow, key: "Control_L+c" });

// Ctrl+V 粘贴
await sky.press_key({ window: targetWindow, key: "Control_L+v" });
```

---

### 示例 7：滚动

```
// 在窗口内 (x:400, y:300) 位置向下滚动 600 像素
await sky.scroll({
  window: targetWindow,
  x: 400,
  y: 300,
  scrollX: 0,
  scrollY: 600,
});
```

---

### 示例 8：拖拽

```
// 从 (100, 200) 拖拽到 (300, 400)
await sky.drag({
  window: targetWindow,
  from_x: 100,
  from_y: 200,
  to_x: 300,
  to_y: 400,
});
```

---

### 示例 9：设置输入框的值

```
// 替换某个可编辑元素的值（element_index 来自无障碍树）
await sky.set_value({ window: targetWindow, element_index: 5, value: "新内容" });
```

---

### 示例 10：执行辅助操作（如展开/折叠）

```
await sky.perform_secondary_action({
  window: targetWindow,
  element_index: 8,
  action: "Expand",  // 可选: Raise, Scroll Up, Scroll Down, Expand, Collapse 等
});
```

---

### 示例 11：启动一个应用

```
// 通过 app id 启动
await sky.launch_app({ app: "notepad.exe" });

// 或通过完整 exe 路径启动
await sky.launch_app({ app: "C:\\Program Files\\MyApp\\app.exe" });
```

---

### 核心工作流模式（观察 → 操作 → 刷新）

这是最推荐的使用模式，每次操作后都要重新获取窗口状态：

```
// 第 1 步：观察
globalThis.state = await sky.get_window_state({
  window: targetWindow,
  include_screenshot: true,
  include_text: true,
});
nodeRepl.write(String(state.accessibility?.tree));

// 第 2 步：执行一个操作
await sky.click({ window: targetWindow, element_index: 12 });

// 第 3 步：刷新状态（必须！索引和坐标在状态变化后失效）
globalThis.state = await sky.get_window_state({
  window: targetWindow,
  include_screenshot: true,
  include_text: true,
});
nodeRepl.write(String(state.accessibility?.tree));
```

---

### 重要注意事项

- **每次操作后必须刷新状态**：元素索引、截图 ID、坐标在窗口状态变化后都会失效
- **不要自动化终端应用**（CMD、PowerShell、Windows Terminal）
- **不要使用 Windows 键**或涉及 Windows 键的快捷键
- **不要自动化密码输入或安全对话框**
- 对于浏览器自动化，推荐使用 Browser Use 插件而非 Computer Use
- 涉及删除数据、发送消息、财务操作等高风险动作需要用户确认

# 换电脑后， WorkBuddy 如何迁移？

<div class="rich_media_meta_list" id="bkmrk-" style="margin:0px 0px 22px;padding:0px;line-height:20px;font-size:0px;color:rgba(0,0,0,0.9);font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><span class="rich_media_meta rich_media_meta_nickname" id="bkmrk--1" style="margin:0px 10px 10px 0px;padding:0px;display:inline-block;vertical-align:middle;font-size:15px;"></span><span id="bkmrk--2" style="margin:0px;padding:0px;"></span></div><div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-%E4%B8%80%E5%8F%A5%E8%AF%9D%E5%89%8D%E6%8F%90%EF%BC%9Aworkbuddy-%E6%98%AF%E8%B4%A6%E5%8F%B7%E5%88%B6" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><section style="margin:20px 0px;padding:16px 20px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(232,243,255);border-left:4px solid rgb(0,82,217);font-size:15px;line-height:1.8;color:rgb(51,51,51);visibility:visible;">**<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">一句话前提：</span>**<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">WorkBuddy 是账号制的，登录同一账号，对话记录和个人画像会自动同步。但你在旧电脑上装的技能、配的自动化任务、MCP 连接器、记忆文件——这些全存在本地硬盘里，</span>**<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">不会跟着账号走</span>**<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">。换电脑后，这部分需要手动迁移。</span></section></div><span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">本文目录</span>

<div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-%E4%B8%80%E3%80%81%E5%85%88%E6%90%9E%E6%B8%85%E6%A5%9A%EF%BC%9A%E4%BB%80%E4%B9%88%E4%BC%9A%E5%90%8C%E6%AD%A5%EF%BC%8C%E4%BB%80%E4%B9%88%E4%B8%8D%E4%BC%9A-%E4%BA%8C%E3%80%81" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><section style="margin:20px 0px;padding:16px 20px;max-width:100%;color:rgb(63,63,63);font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;font-size:16px;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(248,249,250);border:1px solid rgb(224,224,224);visibility:visible;"><span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">一、先搞清楚：什么会同步，什么不会</span>

<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">二、需要迁移的完整清单</span>

<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">三、三种迁移方案（按推荐排序）</span>

<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">四、迁移后的验证清单</span>

<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">五、避坑指南</span>

<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">六、一劳永逸：长期同步方案</span>

</section></div><span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">一、先搞清楚：什么会同步，什么不会</span>

<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">这是迁移的第一步——你得知道哪些东西需要搬，哪些不用管。</span>

<div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-%E2%98%81%EF%B8%8F-%E4%BA%91%E7%AB%AF%E8%87%AA%E5%8A%A8%E5%90%8C%E6%AD%A5-%E6%8D%A2%E7%94%B5%E8%84%91%E7%99%BB%E5%BD%95%E5%90%8C%E4%B8%80%E8%B4%A6%E5%8F%B7%EF%BC%8C" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><table style="margin:20px 0px;padding:0px;border-collapse:collapse;display:table;width:677px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;letter-spacing:normal;text-transform:none;word-spacing:0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;font-size:14px;visibility:visible;"><tbody style="margin:0px;padding:0px;max-width:100%;visibility:visible;"><tr style="margin:0px;padding:0px;max-width:100%;visibility:visible;"><td style="margin:0px;padding:14px;border:1px solid rgb(198,246,213);max-width:100%;background:rgb(240,255,244);vertical-align:top;visibility:visible;"><span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">☁️ 云端自动同步</span>

<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">换电脑登录同一账号，自动出现</span>

<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">• 对话 / 任务记录</span>

<span style="margin:0px;padding:0px;max-width:100%;visibility:visible;">• 个人画像（服务端生成）</span>

<span style="margin:0px;padding:0px;max-width:100%;">• 历史对话检索功能</span>

<span style="margin:0px;padding:0px;max-width:100%;">• 基础账号设置</span>

</td><td style="margin:0px;padding:14px;border:1px solid rgb(254,178,178);max-width:100%;background:rgb(255,245,245);vertical-align:top;"><span style="margin:0px;padding:0px;max-width:100%;">💻 本地存储（需迁移）</span>

<span style="margin:0px;padding:0px;max-width:100%;">换电脑后全部空白，需手动搬</span>

<span style="margin:0px;padding:0px;max-width:100%;">• Skills 技能库</span>

<span style="margin:0px;padding:0px;max-width:100%;">• 自动化任务</span>

<span style="margin:0px;padding:0px;max-width:100%;">• MCP 连接器配置</span>

<span style="margin:0px;padding:0px;max-width:100%;">• 身份文件（SOUL/IDENTITY/USER）</span>

<span style="margin:0px;padding:0px;max-width:100%;">• 记忆文件（MEMORY.md + 日志）</span>

<span style="margin:0px;padding:0px;max-width:100%;">• 团队配置</span>

</td></tr></tbody></table>

<section style="margin:20px 0px;padding:16px 20px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(255,247,230);border-left:4px solid rgb(237,137,54);font-size:15px;line-height:1.8;color:rgb(51,51,51);">**<span style="margin:0px;padding:0px;max-width:100%;">关键认知：</span>**<span style="margin:0px;padding:0px;max-width:100%;">WorkBuddy 的设计理念是「这台机器的设定」而非「这个账号的云资产」。本地配置存在 </span>`<span style="margin:0px;padding:0px;max-width:100%;">~/.workbuddy/</span>`<span style="margin:0px;padding:0px;max-width:100%;"> 目录里（Windows 路径：</span>`<span style="margin:0px;padding:0px;max-width:100%;">C:\Users\你的用户名\.workbuddy\</span>`<span style="margin:0px;padding:0px;max-width:100%;">），它不跟账号走。</span></section></div><span style="margin:0px;padding:0px;max-width:100%;">二、需要迁移的完整清单</span>

<span style="margin:0px;padding:0px;max-width:100%;">以下文件和目录都在 </span>`<span style="margin:0px;padding:0px;max-width:100%;">~/.workbuddy/</span>`<span style="margin:0px;padding:0px;max-width:100%;"> 下（即 </span>`<span style="margin:0px;padding:0px;max-width:100%;">C:\Users\你的用户名\.workbuddy\</span>`<span style="margin:0px;padding:0px;max-width:100%;">）：</span>

<div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-%E6%96%87%E4%BB%B6-%2F-%E7%9B%AE%E5%BD%95-%E5%86%85%E5%AE%B9-%E9%87%8D%E8%A6%81%E6%80%A7-skill" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><table style="margin:20px 0px;padding:0px;border-collapse:collapse;display:table;width:676.989px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;letter-spacing:normal;text-transform:none;word-spacing:0px;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;font-size:14px;min-width:441px;"><thead style="margin:0px;padding:0px;max-width:100%;"><tr style="margin:0px;padding:0px;max-width:100%;"><th style="margin:0px;padding:11px 14px;border-width:2px 1px 1px;border-style:solid;border-color:rgb(187,187,187) rgb(221,221,221) rgb(221,221,221);background:rgb(0,82,217);max-width:100%;color:rgb(255,255,255);text-align:left;font-weight:600;"><section style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;">文件 / 目录</span></section></th><th style="margin:0px;padding:11px 14px;border-width:2px 1px 1px;border-style:solid;border-color:rgb(187,187,187) rgb(221,221,221) rgb(221,221,221);background:rgb(0,82,217);max-width:100%;color:rgb(255,255,255);text-align:left;font-weight:600;"><section style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;">内容</span></section></th><th style="margin:0px;padding:11px 14px;border-width:2px 1px 1px;border-style:solid;border-color:rgb(187,187,187) rgb(221,221,221) rgb(221,221,221);background:rgb(0,82,217);max-width:100%;color:rgb(255,255,255);text-align:left;font-weight:600;"><section style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;">重要性</span></section></th></tr></thead><tbody style="margin:0px;padding:0px;max-width:100%;"><tr style="margin:0px;padding:0px;max-width:100%;"><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);">`<span style="margin:0px;padding:0px;max-width:100%;">skills/</span>`</td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><section style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;">已安装的所有技能（Skill）</span></section></td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><span style="margin:0px;padding:2px 8px;max-width:100%;background:rgb(255,240,240);color:rgb(197,48,48);font-size:12px;font-weight:600;"><span style="margin:0px;padding:0px;max-width:100%;">必须迁移</span></span></td></tr><tr style="margin:0px;padding:0px;max-width:100%;background:rgb(249,250,251);"><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);">`<span style="margin:0px;padding:0px;max-width:100%;">workbuddy.db</span>`</td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><section style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;">SQLite 数据库：自动化任务、运行状态、执行历史</span></section></td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><span style="margin:0px;padding:2px 8px;max-width:100%;background:rgb(255,240,240);color:rgb(197,48,48);font-size:12px;font-weight:600;"><span style="margin:0px;padding:0px;max-width:100%;">必须迁移</span></span></td></tr><tr style="margin:0px;padding:0px;max-width:100%;"><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);">`<span style="margin:0px;padding:0px;max-width:100%;">mcp.json</span>`</td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><section style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;">MCP 服务器 / 连接器配置</span></section></td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><span style="margin:0px;padding:2px 8px;max-width:100%;background:rgb(255,240,240);color:rgb(197,48,48);font-size:12px;font-weight:600;"><span style="margin:0px;padding:0px;max-width:100%;">必须迁移</span></span></td></tr><tr style="margin:0px;padding:0px;max-width:100%;background:rgb(249,250,251);"><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);">`<span style="margin:0px;padding:0px;max-width:100%;">SOUL.md</span>`</td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><section style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;">AI 人格、行为准则、语气风格</span></section></td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><span style="margin:0px;padding:2px 8px;max-width:100%;background:rgb(255,240,240);color:rgb(197,48,48);font-size:12px;font-weight:600;"><span style="margin:0px;padding:0px;max-width:100%;">必须迁移</span></span></td></tr><tr style="margin:0px;padding:0px;max-width:100%;"><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);">`<span style="margin:0px;padding:0px;max-width:100%;">IDENTITY.md</span>`</td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><section style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;">AI 名字、角色定位</span></section></td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><span style="margin:0px;padding:2px 8px;max-width:100%;background:rgb(255,240,240);color:rgb(197,48,48);font-size:12px;font-weight:600;"><span style="margin:0px;padding:0px;max-width:100%;">必须迁移</span></span></td></tr><tr style="margin:0px;padding:0px;max-width:100%;background:rgb(249,250,251);"><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);">`<span style="margin:0px;padding:0px;max-width:100%;">USER.md</span>`</td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><section style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;">用户信息、偏好、项目背景</span></section></td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><span style="margin:0px;padding:2px 8px;max-width:100%;background:rgb(255,240,240);color:rgb(197,48,48);font-size:12px;font-weight:600;"><span style="margin:0px;padding:0px;max-width:100%;">必须迁移</span></span></td></tr><tr style="margin:0px;padding:0px;max-width:100%;"><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);">`<span style="margin:0px;padding:0px;max-width:100%;">MEMORY.md</span>`</td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><section style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;">用户级长期记忆（跨项目）</span></section></td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><span style="margin:0px;padding:2px 8px;max-width:100%;background:rgb(255,240,240);color:rgb(197,48,48);font-size:12px;font-weight:600;"><span style="margin:0px;padding:0px;max-width:100%;">必须迁移</span></span></td></tr><tr style="margin:0px;padding:0px;max-width:100%;background:rgb(249,250,251);"><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);">`<span style="margin:0px;padding:0px;max-width:100%;">experts/</span>`</td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><section style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;">已安装的专家包</span></section></td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><span style="margin:0px;padding:2px 8px;max-width:100%;background:rgb(255,247,230);color:rgb(183,121,31);font-size:12px;font-weight:600;"><span style="margin:0px;padding:0px;max-width:100%;">建议迁移</span></span></td></tr><tr style="margin:0px;padding:0px;max-width:100%;"><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);">`<span style="margin:0px;padding:0px;max-width:100%;">teams/</span>`</td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><section style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;">团队协作配置</span></section></td><td style="margin:0px;padding:10px 14px;max-width:100%;border:1px solid rgb(221,221,221);"><span style="margin:0px;padding:2px 8px;max-width:100%;background:rgb(255,247,230);color:rgb(183,121,31);font-size:12px;font-weight:600;"><span style="margin:0px;padding:0px;max-width:100%;">建议迁移</span></span></td></tr><tr style="margin:0px;padding:0px;max-width:100%;background:rgb(249,250,251);"><td style="margin:0px;padding:10px 14px;border:1px solid rgb(221,221,221);max-width:100%;">`<span style="margin:0px;padding:0px;max-width:100%;">argv.json</span>`</td><td style="margin:0px;padding:10px 14px;border:1px solid rgb(221,221,221);max-width:100%;"><section style="margin:0px;padding:0px;max-width:100%;"><span style="margin:0px;padding:0px;max-width:100%;">启动参数配置</span></section></td><td style="margin:0px;padding:10px 14px;border:1px solid rgb(221,221,221);max-width:100%;"><span style="margin:0px;padding:2px 8px;max-width:100%;background:rgb(255,247,230);color:rgb(183,121,31);font-size:12px;font-weight:600;"><span style="margin:0px;padding:0px;max-width:100%;">建议迁移</span></span></td></tr></tbody></table>

<section style="margin:20px 0px;padding:16px 20px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(255,247,230);border-left:4px solid rgb(237,137,54);font-size:15px;line-height:1.8;color:rgb(51,51,51);">**<span style="margin:0px;padding:0px;max-width:100%;">注意：</span>**<span style="margin:0px;padding:0px;max-width:100%;">项目级记忆文件 </span>`<span style="margin:0px;padding:0px;max-width:100%;">{项目目录}/.workbuddy/memory/</span>`<span style="margin:0px;padding:0px;max-width:100%;">（每日日志 + 项目记忆）不在 </span>`<span style="margin:0px;padding:0px;max-width:100%;">~/.workbuddy/</span>`<span style="margin:0px;padding:0px;max-width:100%;"> 下，而是跟着各自的项目走。如果你的项目在 Git 管理下，这些文件会跟着代码仓库一起迁移。</span></section></div><span style="margin:0px;padding:0px;max-width:100%;">三、三种迁移方案（按推荐排序）</span>

<span style="margin:0px;padding:0px;max-width:100%;">方案一：云盘同步（推荐，一劳永逸）</span>

<span style="margin:0px;padding:0px;max-width:100%;">把 </span>`<span style="margin:0px;padding:0px;max-width:100%;">~/.workbuddy/</span>`<span style="margin:0px;padding:0px;max-width:100%;"> 目录放到云盘的同步文件夹中，通过软链接让 WorkBuddy 仍然从原始路径读取。设置一次，以后两台电脑自动保持一致。</span>

**<span style="margin:0px;padding:0px;max-width:100%;">第 1 步 · 在旧电脑上操作：</span>**<span style="margin:0px;padding:0px;max-width:100%;">把整个 </span>`<span style="margin:0px;padding:0px;max-width:100%;">.workbuddy</span>`<span style="margin:0px;padding:0px;max-width:100%;"> 目录移动到云盘同步文件夹中。例如 OneDrive：</span>

<div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-c%3A%5Cusers%5C%E4%BD%A0%E7%9A%84%E7%94%A8%E6%88%B7%E5%90%8D%5C.work" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><section style="margin:12px 0px 16px;padding:16px 18px;max-width:100%;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(30,30,30);color:rgb(212,212,212);font-family:Consolas, monospace;font-size:13px;line-height:1.7;"><span style="margin:0px;padding:0px;max-width:100%;">C:\\Users\\你的用户名\\.workbuddy\\ → C:\\Users\\你的用户名\\OneDrive\\WorkBuddy备份\\.workbuddy\\</span></section></div>**<span style="margin:0px;padding:0px;max-width:100%;">第 2 步 · 创建软链接</span>**<span style="margin:0px;padding:0px;max-width:100%;">（以管理员身份打开 PowerShell）：在原位置创建一个指向云盘的符号链接：</span>

<div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-mklink-%2Fd-%22c%3A%5Cusers%5C" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><section style="margin:12px 0px 16px;padding:16px 18px;max-width:100%;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(30,30,30);color:rgb(212,212,212);font-family:Consolas, monospace;font-size:13px;line-height:1.7;"><span style="margin:0px;padding:0px;max-width:100%;">mklink /D "C:\\Users\\你的用户名\\.workbuddy" "C:\\Users\\你的用户名\\OneDrive\\WorkBuddy备份\\.workbuddy"</span></section></div>**<span style="margin:0px;padding:0px;max-width:100%;">第 3 步 · 在新电脑上操作：</span>**<span style="margin:0px;padding:0px;max-width:100%;">确保云盘已同步完成，然后在相同位置创建同样的软链接。WorkBuddy 会自动从软链接指向的云盘路径读取所有配置。</span>

<div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-%E4%BC%98%E7%82%B9%EF%BC%9A%E8%AE%BE%E7%BD%AE%E4%B8%80%E6%AC%A1%E5%90%8E%E5%85%A8%E8%87%AA%E5%8A%A8%EF%BC%8C%E6%97%A0%E9%9C%80%E9%87%8D%E5%A4%8D%E6%93%8D%E4%BD%9C%E3%80%82%E4%B8%A4" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><section style="margin:20px 0px;padding:16px 20px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(232,243,255);border-left:4px solid rgb(0,82,217);font-size:15px;line-height:1.8;color:rgb(51,51,51);">**<span style="margin:0px;padding:0px;max-width:100%;">优点：</span>**<span style="margin:0px;padding:0px;max-width:100%;">设置一次后全自动，无需重复操作。两台电脑的配置永远一致。</span><span style="margin:0px;padding:0px;max-width:100%;">  
</span>**<span style="margin:0px;padding:0px;max-width:100%;">适用场景：</span>**<span style="margin:0px;padding:0px;max-width:100%;">有固定两台以上电脑（公司 + 家里），且都安装了同一云盘客户端。</span></section></div><span style="margin:0px;padding:0px;max-width:100%;">方案二：GitHub 私有仓库（适合有版本管理需求）</span>

<span style="margin:0px;padding:0px;max-width:100%;">把 </span>`<span style="margin:0px;padding:0px;max-width:100%;">~/.workbuddy/</span>`<span style="margin:0px;padding:0px;max-width:100%;"> 初始化为 Git 仓库，推送到 GitHub 私有仓库。天然有版本记录，传错了能回滚，比普通网盘更稳。</span>

**<span style="margin:0px;padding:0px;max-width:100%;">第 1 步 · 在旧电脑初始化仓库：</span>**

<div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-cd-%7E%2F.workbuddygit-i" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><section style="margin:12px 0px 16px;padding:16px 18px;max-width:100%;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(30,30,30);color:rgb(212,212,212);font-family:Consolas, monospace;font-size:13px;line-height:1.7;"><span style="margin:0px;padding:0px;max-width:100%;">cd ~/.workbuddy</span><span style="margin:0px;padding:0px;max-width:100%;">  
</span><span style="margin:0px;padding:0px;max-width:100%;">git init</span><span style="margin:0px;padding:0px;max-width:100%;">  
</span><span style="margin:0px;padding:0px;max-width:100%;">git add .</span><span style="margin:0px;padding:0px;max-width:100%;">  
</span><span style="margin:0px;padding:0px;max-width:100%;">git commit -m "备份 WorkBuddy 配置"</span><span style="margin:0px;padding:0px;max-width:100%;">  
</span><span style="margin:0px;padding:0px;max-width:100%;">git remote add origin https://github.com/你的用户名/workbuddy-backup.git</span><span style="margin:0px;padding:0px;max-width:100%;">  
</span><span style="margin:0px;padding:0px;max-width:100%;">git push -u origin main</span></section></div>**<span style="margin:0px;padding:0px;max-width:100%;">第 2 步 · 在新电脑上拉取：</span>**

<div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-cd-%7Egit-clone-https%3A" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><section style="margin:12px 0px 16px;padding:16px 18px;max-width:100%;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(30,30,30);color:rgb(212,212,212);font-family:Consolas, monospace;font-size:13px;line-height:1.7;"><span style="margin:0px;padding:0px;max-width:100%;">cd ~</span><span style="margin:0px;padding:0px;max-width:100%;">  
</span><span style="margin:0px;padding:0px;max-width:100%;">git clone https://github.com/你的用户名/workbuddy-backup.git .workbuddy</span></section></div>**<span style="margin:0px;padding:0px;max-width:100%;">第 3 步 · 后续更新：</span>**<span style="margin:0px;padding:0px;max-width:100%;">每次在任一电脑上修改配置后，</span>`<span style="margin:0px;padding:0px;max-width:100%;">git add . && git commit && git push</span>`<span style="margin:0px;padding:0px;max-width:100%;"> 推送；在另一台电脑上 </span>`<span style="margin:0px;padding:0px;max-width:100%;">git pull</span>`<span style="margin:0px;padding:0px;max-width:100%;"> 拉取。</span>

<div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-%E4%BC%98%E7%82%B9%EF%BC%9A%E6%9C%89%E5%AE%8C%E6%95%B4%E7%89%88%E6%9C%AC%E5%8E%86%E5%8F%B2%EF%BC%8C%E8%AF%AF%E6%93%8D%E4%BD%9C%E5%8F%AF%E5%9B%9E%E6%BB%9A%EF%BC%8C%E9%80%82%E5%90%88" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><section style="margin:20px 0px;padding:16px 20px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(232,243,255);border-left:4px solid rgb(0,82,217);font-size:15px;line-height:1.8;color:rgb(51,51,51);">**<span style="margin:0px;padding:0px;max-width:100%;">优点：</span>**<span style="margin:0px;padding:0px;max-width:100%;">有完整版本历史，误操作可回滚，适合配置经常变动的场景。</span><span style="margin:0px;padding:0px;max-width:100%;">  
</span>**<span style="margin:0px;padding:0px;max-width:100%;">注意：</span>**`<span style="margin:0px;padding:0px;max-width:100%;">workbuddy.db</span>`<span style="margin:0px;padding:0px;max-width:100%;"> 是二进制文件，Git 对二进制文件的版本管理效果一般（无法做行级 diff），但作为备份和同步仍然可用。</span></section></div><span style="margin:0px;padding:0px;max-width:100%;">方案三：U盘 / 网盘手动拷贝（最简单，适合一次性迁移）</span>

<span style="margin:0px;padding:0px;max-width:100%;">如果你只需要做一次性迁移，不想搞云盘或 Git，直接拷贝整个目录就行。</span>

**<span style="margin:0px;padding:0px;max-width:100%;">第 1 步：</span>**<span style="margin:0px;padding:0px;max-width:100%;">关闭旧电脑上的 WorkBuddy（确保数据库写入完成）。</span>

**<span style="margin:0px;padding:0px;max-width:100%;">第 2 步：</span>**<span style="margin:0px;padding:0px;max-width:100%;">复制整个 </span>`<span style="margin:0px;padding:0px;max-width:100%;">.workbuddy</span>`<span style="margin:0px;padding:0px;max-width:100%;"> 目录到 U盘或网盘。</span>

**<span style="margin:0px;padding:0px;max-width:100%;">第 3 步：</span>**<span style="margin:0px;padding:0px;max-width:100%;">在新电脑上，把目录覆盖到相同位置。</span>

**<span style="margin:0px;padding:0px;max-width:100%;">第 4 步：</span>**<span style="margin:0px;padding:0px;max-width:100%;">打开新电脑上的 WorkBuddy，检查配置是否生效。</span>

<div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-%E4%BC%98%E7%82%B9%EF%BC%9A%E9%9B%B6%E9%97%A8%E6%A7%9B%EF%BC%8C%E4%BA%BA%E4%BA%BA%E4%BC%9A%E6%93%8D%E4%BD%9C%E3%80%82%E7%BC%BA%E7%82%B9%EF%BC%9A%E6%AF%8F%E6%AC%A1%E6%8D%A2%E7%94%B5" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><section style="margin:20px 0px;padding:16px 20px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(232,243,255);border-left:4px solid rgb(0,82,217);font-size:15px;line-height:1.8;color:rgb(51,51,51);">**<span style="margin:0px;padding:0px;max-width:100%;">优点：</span>**<span style="margin:0px;padding:0px;max-width:100%;">零门槛，人人会操作。</span><span style="margin:0px;padding:0px;max-width:100%;">  
</span>**<span style="margin:0px;padding:0px;max-width:100%;">缺点：</span>**<span style="margin:0px;padding:0px;max-width:100%;">每次换电脑都要手动操作一次，无法自动保持同步。</span></section></div><span style="margin:0px;padding:0px;max-width:100%;">四、迁移后的验证清单</span>

<span style="margin:0px;padding:0px;max-width:100%;">迁移完成后，按这个清单逐项检查，确认所有配置都生效了：</span>

<div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-%E2%98%90-skills-%E6%8A%80%E8%83%BD%E5%88%97%E8%A1%A8%EF%BC%9A%E6%89%93%E5%BC%80%E3%80%8C%E4%B8%93%E5%AE%B6-" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><section style="margin:20px 0px;padding:16px 20px;max-width:100%;color:rgb(63,63,63);font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;font-size:16px;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(240,255,244);border:1px solid rgb(198,246,213);"><span style="margin:0px;padding:0px;max-width:100%;">☐ Skills 技能列表：打开「专家 · 技能 · 连接器」→ 技能，确认所有技能都在</span>

<span style="margin:0px;padding:0px;max-width:100%;">☐ 自动化任务：打开自动化列表，确认所有定时任务都在</span>

<span style="margin:0px;padding:0px;max-width:100%;">☐ MCP 连接器：打开连接器列表，确认已连接的服务还在（注意：部分连接器可能需要重新授权）</span>

<span style="margin:0px;padding:0px;max-width:100%;">☐ 身份文件：开一个新对话，问 AI「你是谁？我是谁？」，确认 AI 能正确回答</span>

<span style="margin:0px;padding:0px;max-width:100%;">☐ 记忆文件：问 AI「你还记得我之前跟你说过什么吗」，确认长期记忆存在</span>

<span style="margin:0px;padding:0px;max-width:100%;">☐ 专家包：打开专家中心，确认已安装的专家都在</span>

<span style="margin:0px;padding:0px;max-width:100%;">☐ 对话历史：确认云端同步的历史对话能看到（这个不需要迁移，自动同步）</span>

</section></div><span style="margin:0px;padding:0px;max-width:100%;">五、避坑指南</span>

<div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-%E5%9D%91-1%EF%BC%9A%E7%9B%B4%E6%8E%A5%E6%8B%B7%E8%B4%9D-workbuddy.d" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><section style="margin:20px 0px;padding:16px 20px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(255,240,240);border-left:4px solid rgb(229,62,62);font-size:15px;line-height:1.8;color:rgb(51,51,51);">**<span style="margin:0px;padding:0px;max-width:100%;">坑 1：直接拷贝 workbuddy.db 导致数据库报错</span>**<span style="margin:0px;padding:0px;max-width:100%;">  
</span><span style="margin:0px;padding:0px;max-width:100%;">workbuddy.db 包含本地路径记录，如果两台电脑的 Windows 用户名不同（如一台是 </span>`<span style="margin:0px;padding:0px;max-width:100%;">Administrator</span>`<span style="margin:0px;padding:0px;max-width:100%;">，另一台是 </span>`<span style="margin:0px;padding:0px;max-width:100%;">zhangsan</span>`<span style="margin:0px;padding:0px;max-width:100%;">），数据库中的路径记录会不匹配。解决方案：迁移后如果自动化任务无法执行，删除 workbuddy.db 中的 automation\_runtime\_state 表数据，让运行状态重新初始化。或者更保险的做法——用 automation\_update 工具逐条导出 JSON 再导入，而不是搬数据库文件。</span></section><section style="margin:20px 0px;padding:16px 20px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(255,247,230);border-left:4px solid rgb(237,137,54);font-size:15px;line-height:1.8;color:rgb(51,51,51);">**<span style="margin:0px;padding:0px;max-width:100%;">坑 2：MCP 连接器需要重新授权</span>**<span style="margin:0px;padding:0px;max-width:100%;">  
</span><span style="margin:0px;padding:0px;max-width:100%;">即使迁移了 </span>`<span style="margin:0px;padding:0px;max-width:100%;">mcp.json</span>`<span style="margin:0px;padding:0px;max-width:100%;">，部分连接器（如飞书、企业微信、GitHub 等）的授权 token 可能已过期或绑定到了旧机器的会话。迁移后需要到「连接器管理」页面重新点击「Trust / 授权」。</span></section><section style="margin:20px 0px;padding:16px 20px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(255,247,230);border-left:4px solid rgb(237,137,54);font-size:15px;line-height:1.8;color:rgb(51,51,51);">**<span style="margin:0px;padding:0px;max-width:100%;">坑 3：项目级记忆不会跟着走</span>**<span style="margin:0px;padding:0px;max-width:100%;">  
</span>`<span style="margin:0px;padding:0px;max-width:100%;">~/.workbuddy/</span>`<span style="margin:0px;padding:0px;max-width:100%;"> 只包含用户级配置。每个项目自己的记忆文件（</span>`<span style="margin:0px;padding:0px;max-width:100%;">{项目目录}/.workbuddy/memory/</span>`<span style="margin:0px;padding:0px;max-width:100%;">）是独立存储的。如果项目目录不在 Git 管理下，这些记忆也不会自动迁移。解决方案：把项目目录也纳入 Git 管理或单独拷贝。</span></section><section style="margin:20px 0px;padding:16px 20px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(255,247,230);border-left:4px solid rgb(237,137,54);font-size:15px;line-height:1.8;color:rgb(51,51,51);">**<span style="margin:0px;padding:0px;max-width:100%;">坑 4：云盘同步时的文件冲突</span>**<span style="margin:0px;padding:0px;max-width:100%;">  
</span><span style="margin:0px;padding:0px;max-width:100%;">如果两台电脑同时打开 WorkBuddy 且都在写入记忆文件（如每日日志），云盘同步可能出现冲突副本（如 </span>`<span style="margin:0px;padding:0px;max-width:100%;">2026-07-28 (1).md</span>`<span style="margin:0px;padding:0px;max-width:100%;">）。解决方案：避免两台电脑同时使用同一项目；或采用 Git 方案（二选一），Git 有冲突解决机制。</span></section><section style="margin:20px 0px;padding:16px 20px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;background:rgb(255,247,230);border-left:4px solid rgb(237,137,54);font-size:15px;line-height:1.8;color:rgb(51,51,51);">**<span style="margin:0px;padding:0px;max-width:100%;">坑 5：第三方登录导致账号不一致</span>**<span style="margin:0px;padding:0px;max-width:100%;">  
</span><span style="margin:0px;padding:0px;max-width:100%;">如果一台电脑用微信扫码登录，另一台用邮箱密码登录，可能产生两个独立账号，导致云端对话记录都无法同步。解决方案：所有设备统一使用同一种登录方式（推荐邮箱 + 密码）。</span></section></div><span style="margin:0px;padding:0px;max-width:100%;">六、一劳永逸：长期同步方案</span>

<span style="margin:0px;padding:0px;max-width:100%;">如果你经常在两台以上电脑之间切换，建议设置一个长期的自动同步机制，而不是每次换电脑都手动搬一次。</span>

**<span style="margin:0px;padding:0px;max-width:100%;">第 1 步 · 用户级配置</span>**<span style="margin:0px;padding:0px;max-width:100%;">（</span>`<span style="margin:0px;padding:0px;max-width:100%;">~/.workbuddy/</span>`<span style="margin:0px;padding:0px;max-width:100%;">）→ 用云盘 + 软链接方案（方案一），设置一次后全自动同步。</span>

**<span style="margin:0px;padding:0px;max-width:100%;">第 2 步 · 项目级记忆</span>**<span style="margin:0px;padding:0px;max-width:100%;">（</span>`<span style="margin:0px;padding:0px;max-width:100%;">{项目}/.workbuddy/memory/</span>`<span style="margin:0px;padding:0px;max-width:100%;">）→ 把项目纳入 Git 管理，记忆文件跟着代码仓库走。</span>

**<span style="margin:0px;padding:0px;max-width:100%;">第 3 步 · 自动化任务</span>**<span style="margin:0px;padding:0px;max-width:100%;"> → 如果两台电脑用户名不同，不要搬 </span>`<span style="margin:0px;padding:0px;max-width:100%;">workbuddy.db</span>`<span style="margin:0px;padding:0px;max-width:100%;">，而是用 </span>`<span style="margin:0px;padding:0px;max-width:100%;">automation_update</span>`<span style="margin:0px;padding:0px;max-width:100%;"> 工具逐条导出为 JSON，在新电脑上逐条导入。安全且不会损坏数据库。</span>

<div class="rich_media_content js_underline_content autoTypeSetting24psection" id="bkmrk-%E6%80%BB%E7%BB%93-workbuddy-%E7%9A%84%E8%BF%81%E7%A7%BB%E6%9C%AC%E8%B4%A8%E4%B8%8A%E5%B0%B1" style="margin:0px;padding:0px;color:rgba(0,0,0,0.9);font-size:17px;overflow:hidden;text-align:justify;font-family:'PingFang SC NEW', 'system-ui', '-apple-system', BlinkMacSystemFont, 'Helvetica Neue', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;font-style:normal;font-weight:400;letter-spacing:0.544px;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;background-color:rgb(255,255,255);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;"><section style="margin:25px 0px;padding:24px 28px;max-width:100%;font-family:'-apple-system', BlinkMacSystemFont, 'PingFang SC', 'Microsoft YaHei', sans-serif;font-size:16px;font-style:normal;font-weight:400;letter-spacing:normal;text-indent:0px;text-transform:none;word-spacing:0px;white-space:normal;text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;color:rgb(255,255,255);"><span style="margin:0px;padding:0px;max-width:100%;">总结</span>

<span style="margin:0px;padding:0px;max-width:100%;">WorkBuddy 的迁移本质上就是搬一个目录：</span>`<span style="margin:0px;padding:0px;max-width:100%;">~/.workbuddy/</span>`<span style="margin:0px;padding:0px;max-width:100%;">。关键记住三件事：</span>

<span style="margin:0px;padding:0px;max-width:100%;">• </span>**<span style="margin:0px;padding:0px;max-width:100%;">云端同步的</span>**<span style="margin:0px;padding:0px;max-width:100%;">：对话记录 + 个人画像 → 不用管，自动跟账号走</span>

<span style="margin:0px;padding:0px;max-width:100%;">• </span>**<span style="margin:0px;padding:0px;max-width:100%;">本地存储的</span>**<span style="margin:0px;padding:0px;max-width:100%;">：技能 + 自动化 + MCP + 身份 + 记忆 → 需要手动迁移 </span>`<span style="margin:0px;padding:0px;max-width:100%;">~/.workbuddy/</span>`

<span style="margin:0px;padding:0px;max-width:100%;">• </span>**<span style="margin:0px;padding:0px;max-width:100%;">项目级记忆</span>**<span style="margin:0px;padding:0px;max-width:100%;">：跟着各自项目目录走，不在 </span>`<span style="margin:0px;padding:0px;max-width:100%;">~/.workbuddy/</span>`<span style="margin:0px;padding:0px;max-width:100%;"> 里</span>

<span style="margin:0px;padding:0px;max-width:100%;">最佳实践：云盘 + 软链接搞定用户级配置，Git 管理搞定项目级记忆，自动化任务用 JSON 导出导入。一次设置，终身受用。</span>

</section></div>

# Codex++（Codex‑plus‑plus‑manager）微信连接功能

> 注意：**这不是OpenAI官方Codex功能，是Codex++第三方增强工具的扩展**。 原理：扫码登录个人微信，做消息桥接：**手机微信作为远程输入入口，指令交给本地电脑上运行的Codex‑CLI/Codex App执行，结果再回传到微信**，AI的全部算力、文件读写都还是跑在你Windows本机上。

## ✨主要作用

1. **手机微信远程操控本地Codex（核心）** 手机微信发文字指令，电脑上的Codex执行：写代码、查日志、生成脚本、命令行操作、文件读写，执行完成把结果、代码片段直接回复到微信聊天窗口。
    
    > 例如：手机发：`帮我看D:\log下的报错日志，整理问题点`，电脑Codex读取本地文件，整理完把结果回微信发给你。
2. **每个微信联系人独立隔离会话** 不同微信私聊/好友自动映射独立Codex会话，上下文互不干扰；每个微信对话对应电脑上一套独立会话、工作目录，不会混上下文。 支持指令：`/new` 在微信里开启全新会话。
3. **消息透传，支持文本、文件** 微信发送文本、粘贴代码片段、上传文本文件，直接喂给Codex；Codex生成的长代码、输出日志可以直接在微信返回，大内容会做分片。
4. **可控制模型、切换工作目录（微信内发指令）** 在微信聊天框发斜杠指令远程控制本地Codex实例：

- `/model qwen3.7‑max`：远程切换模型（对接LiteLLM的模型也生效）
- `/dir D:\project`：切换电脑上的工作目录
- `/reset`：重置当前会话上下文

5. **后台常驻运行** 开启微信连接之后，电脑Codex++在后台挂着，不需要你一直开着Codex CLI窗口；只要电脑开机、服务在线，手机微信随时下发任务。

## 🧩整体数据流

```
手机微信消息 → Codex++微信桥接模块 → 转发给本机Codex‑CLI（可以是对接LiteLLM代理）
Codex在电脑执行读写文件/命令 → 返回结果 → Codex++推送回微信

```

## ⚠️重要限制与风险（一定要看）

1. **是基于个人微信协议桥接，不是企业微信机器人API**，存在账号风控风险，不建议大号长期挂；优先用小号测试。
2. **权限很大**：微信下发的指令可以直接操作电脑本地磁盘、运行命令，**不要把这个微信会话开放给其他人，仅限自己使用**，否则别人微信发指令可以读写、修改你电脑文件。
3. 依赖Codex‑CLI本身的稳定性，如果你LiteLLM代理不稳定、模型不支持工具调用，微信端就会收到会话中断，和你截图`Conversation interrupted`是同源问题。
4. 微信连接 ≠ 把模型部署到微信；**所有运算、文件访问全部发生在你的Windows本机**，微信只是遥控器。

## 📌常见踩坑

1. 启动微信连接前，要保证Codex++已经正常连通你的Codex‑CLI（能正常调用模型，例如LiteLLM代理已经调通）。
2. 扫码登录微信之后，**保持codex‑plus‑plus‑manager程序不要关闭**，关闭就断开微信桥接。
3. 如果对接LiteLLM国产模型，模型必须支持工具调用，否则微信发指令经常直接会话中断。

## 区分两个容易混淆概念

- **Codex++微信连接**：manager内置自带的wechat桥接（你现在问的），开箱在manager面板一键开启扫码。
- **cx2wechat / Codex‑Bridge**：外部独立第三方桥接工具，需要额外npm安装，不属于Codex++内置功能。

# Codex‑plus‑plus‑manager 微信连接完整使用教程

> 前置条件：
> 
> 1. 已经正常运行 **codex‑cli**，`config.toml`配置正常（可以直连OpenAI或对接LiteLLM网关），本地控制台可以正常对话，无会话中断报错。
> 2. Codex++版本 ≥ **v1.2.48**，旧版本没有微信连接功能。
> 3. Windows已装好VC++运行库，程序可以正常启动。

## 一、开启微信连接步骤

1. 打开 `codex‑plus‑plus‑manager.exe` 主界面
2. 在侧边栏找到 **微信连接** 标签页，点击 **启动微信桥接**
3. 程序窗口内会出现微信登录二维码。 > ⚠️ 使用**手机微信扫码登录（PC微信不要登录同一个账号，协议冲突）**，推荐小号测试，不建议日常大号长期挂。
4. 手机微信确认登录，管理器页面提示：`微信桥接已运行`。
5. **关键：给自己这条微信发一条消息**，完成会话初始化，此时桥接链路正式打通。

> 运行后：`codex‑plus‑plus‑manager.exe`**不能关闭、不能最小化到托盘退出**，窗口最小化可以，关闭程序微信桥接直接断开。

## 二、微信端可用斜杠指令（直接微信聊天框发送）

<table id="bkmrk-%E5%BE%AE%E4%BF%A1%E5%8F%91%E9%80%81%E6%8C%87%E4%BB%A4-%E5%8A%9F%E8%83%BD%E8%AF%B4%E6%98%8E-%2Fhelp-%E8%BE%93%E5%87%BA"><thead><tr><th>微信发送指令</th><th>功能说明</th></tr></thead><tbody><tr><td>`/help`</td><td>输出全部可用指令帮助</td></tr><tr><td>`/new`</td><td>开启全新Codex会话，清空上下文记忆</td></tr><tr><td>`/status`</td><td>查询桥接状态：当前模型、工作目录</td></tr><tr><td>`/model qwen3.7‑max`</td><td>远程切换模型（名字和codex config / litellm model\_list必须完全一致）</td></tr><tr><td>`/dir D:\MyProject`</td><td>切换电脑本地工作目录，后续读写文件都在这个路径</td></tr><tr><td>`/retry`</td><td>上一条会话中断（你截图的`Conversation interrupted`），重试上一次任务</td></tr><tr><td>`/reset`</td><td>重置当前会话，重置工具状态</td></tr></tbody></table>

### 普通用法示例（不需要斜杠，直接发自然语言）

```
读取D:\logs\app.log，找出报错，整理成要点
写一个powershell脚本，批量重命名该目录jpg文件
查看当前目录所有docker‑compose.yml，检查语法

```

手机发送后，**电脑本地Codex执行文件读写、命令调用**，结果会回传到微信。长输出会自动做消息分片返回。

> 每个微信私聊好友，自动分配**独立会话上下文**，互相隔离互不干扰。

## 三、对接LiteLLM的特别注意点（你现在的环境）

1. Codex‑CLI 的`config.toml`必须配置好`openai_base_url`指向`http://127.0.0.1:4000/v1`，`wire_api = "responses"`，litellm开启`enable_responses_api: true`。
2. **下游模型必须支持工具调用（function‑call）**。国产模型工具调用能力弱，微信端会频繁报 `Conversation interrupted`会话中断。
3. `/model`后面写的模型名必须和litellm配置`model_list`的`model_name`**完全一模一样，大小写不能错**，否则返回400模型不存在错误。

## 四、安全配置（非常重要）

1. 默认状态下，**扫码登录的这个微信号才有执行权限，其它微信消息全部会被拒绝，不会执行指令**。不要修改配置开放给其他人，微信下发指令可以读写本地磁盘、运行命令，风险极高。
2. **不要登录微信PC版和桥接为同一个账号，会冲突掉线。**
3. 电脑睡眠、关机、断网，微信不会收到回复。如果要24小时运行，需要关闭Windows自动睡眠。

## 五、常见故障排查

1. **扫码成功，微信发消息没有任何回复**
    - 确认codex‑cli本身在本机控制台可以正常对话。
    - 检查manager窗口日志，看是否有报错；
    - 重启微信桥接，重新发一条消息初始化会话。
2. **频繁会话中断 `Conversation interrupted`**
    - 绝大多数是模型工具调用兼容问题。LiteLLM代理开启responses，但底层模型不支持工具调用。优先换OpenAI官方模型测试确认链路是否正常。
3. **微信桥接频繁掉线**
    - 不要同时登录PC微信；网络波动会掉线，重新扫码登录即可。
4. **更换模型不生效**
    - 微信发送`/status`确认当前模型；名字严格匹配Litellm model\_list。

## 六、停止微信桥接

两种方式：

1. 在Codex++管理器微信连接页面，点击**停止微信桥接**
2. 直接关闭整个`codex‑plus‑plus‑manager.exe`程序，桥接立刻终止。

> 桥接配置保存在codex++的配置目录，重启程序需要手动重新点启动桥接、重新扫码。

如果你需要，我可以给你一份最小可直接复制的codex config.toml + litellm\_config.yaml适配微信桥接。

# LiteLLM 升级操作手册：1.87.0 -> 1.98.0

<div id="bkmrk---%E7%9B%AE%E6%A0%87%E6%9C%8D%E5%8A%A1%E5%99%A8%EF%BC%9A%60192.168.4.1" style="color:#ffffff;background-color:#002451;font-family:Consolas, 'Courier New', monospace;font-weight:normal;font-size:14px;line-height:19px;white-space:pre;">  
<div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 目标服务器：</span><span style="color:#ff9da4;">`192.168.4.19`</span><span style="color:#bbdaff;">（容器 </span><span style="color:#ff9da4;">`litellm`</span><span style="color:#bbdaff;">，安装目录 </span><span style="color:#ff9da4;">`/opt/litellm`</span><span style="color:#bbdaff;">）</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 计划时间：中午业务低峰执行，预计停机 20-40 秒</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 手册生成：2026-09-01</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 状态：</span><span style="color:#ffc58f;font-weight:bold;">\*\*预检已通过，尚未执行升级\*\*</span><span style="color:#bbdaff;">（生产仍运行 1.87.0）</span></div>  
<div><span style="color:#ffffff;">---</span></div>  
<div><span style="color:#d1f1a9;font-weight:bold;">\## 一、现状与版本核实</span></div>  
<div><span style="color:#ffffff;">| 项目 | 值 |</span></div><div><span style="color:#ffffff;">|---|---|</span></div><div><span style="color:#ffffff;">| 当前镜像 | </span><span style="color:#ff9da4;">`ghcr.io/berriai/litellm:1.87.0`</span><span style="color:#ffffff;">（2026-05-23 发布） |</span></div><div><span style="color:#ffffff;">| 目标版本 | </span><span style="color:#ff9da4;">`v1.98.0`</span><span style="color:#ffffff;">（2026-08-22，官方 Latest Release） |</span></div><div><span style="color:#ffffff;">| 更新版本情况 | </span><span style="color:#ff9da4;">`1.99.0-rc.2`</span><span style="color:#ffffff;">、</span><span style="color:#ff9da4;">`1.100.0-rc.1`</span><span style="color:#ffffff;"> 均为 RC，生产不使用 |</span></div><div><span style="color:#ffffff;">| 部署方式 | docker-compose v5.3.1，</span><span style="color:#ff9da4;">`/opt/litellm/docker-compose.yml`</span><span style="color:#ffffff;"> |</span></div><div><span style="color:#ffffff;">| 数据库 | </span><span style="color:#ff9da4;">`postgres:16`</span><span style="color:#ffffff;">，bind mount </span><span style="color:#ff9da4;">`/opt/litellm/postgres`</span><span style="color:#ffffff;">，库名 </span><span style="color:#ff9da4;">`litellm`</span><span style="color:#ffffff;"> |</span></div><div><span style="color:#ffffff;">| 配置挂载 | </span><span style="color:#ff9da4;">`./config.yaml`</span><span style="color:#ffffff;"> -&gt; </span><span style="color:#ff9da4;">`/app/config.yaml`</span><span style="color:#ffffff;"> |</span></div><div><span style="color:#ffffff;">| 关键开关 | </span><span style="color:#ff9da4;">`STORE\_MODEL\_IN\_DB=True`</span><span style="color:#ffffff;">、</span><span style="color:#ff9da4;">`restart: always`</span><span style="color:#ffffff;"> |</span></div><div><span style="color:#ffffff;">| 模型数 | 11 个 |</span></div><div><span style="color:#ffffff;">| 资源 | 磁盘剩 1.8T，内存 15G，DB 体积 386MB |</span></div>  
<div><span style="color:#ffc58f;font-weight:bold;">\*\*为什么该升\*\*</span><span style="color:#ffffff;">：官方只维护最近 4 个稳定小版本（当前 1.95-1.98），1.87.0 已停止接收修复。</span></div>  
<div><span style="color:#ffffff;">---</span></div>  
<div><span style="color:#d1f1a9;font-weight:bold;">\## 二、预检结论（2026-09-01 已实测，生产未受影响）</span></div>  
<div><span style="color:#bbdaff;">1.</span><span style="color:#bbdaff;"> 镜像可用性</span></div><div><span style="color:#bbdaff;"> </span><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> </span><span style="color:#ff9da4;">`ghcr.io`</span><span style="color:#bbdaff;"> 直连会卡死（11/21 层后无进展），</span><span style="color:#ffc58f;font-weight:bold;">\*\*必须用镜像源\*\*</span></div><div><span style="color:#bbdaff;"> </span><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> </span><span style="color:#ff9da4;">`ghcr.nju.edu.cn/berriai/litellm:1.98.0`</span><span style="color:#bbdaff;"> 约 30 秒拉取完成，已在本地</span></div><div><span style="color:#bbdaff;"> </span><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> </span><span style="color:#ff9da4;">`docker.litellm.ai/berriai/litellm:1.98.0`</span><span style="color:#bbdaff;"> 亦验证可拉</span></div><div><span style="color:#bbdaff;">2.</span><span style="color:#bbdaff;"> 备份可用性</span></div><div><span style="color:#bbdaff;"> </span><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 已生成 </span><span style="color:#ff9da4;">`/opt/litellm/backup\_litellm\_db\_20260901-020955.dump`</span><span style="color:#bbdaff;">（20MB，</span><span style="color:#ff9da4;">`pg\_dump -Fc`</span><span style="color:#bbdaff;">）</span></div><div><span style="color:#bbdaff;"> </span><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 已成功 restore 到临时库，备份有效</span></div><div><span style="color:#bbdaff;">3.</span><span style="color:#bbdaff;"> 数据库迁移</span></div><div><span style="color:#bbdaff;"> </span><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 用克隆库实跑 1.98.0：</span><span style="color:#ffc58f;font-weight:bold;">\*\*28 个迁移自动应用成功\*\*</span></div><div><span style="color:#bbdaff;"> </span><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 日志链路：</span><span style="color:#ff9da4;">`prisma migrate deploy`</span><span style="color:#bbdaff;"> -&gt; </span><span style="color:#ff9da4;">`Migration diff applied`</span><span style="color:#bbdaff;"> -&gt; </span><span style="color:#ff9da4;">`Post-migration sanity check completed`</span><span style="color:#bbdaff;">，无报错</span></div><div><span style="color:#bbdaff;">4.</span><span style="color:#bbdaff;"> 功能一致性</span></div><div><span style="color:#bbdaff;"> </span><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 11 个模型全部注册，</span><span style="color:#ff9da4;">`/model/info`</span><span style="color:#bbdaff;"> 入/出/缓存单价与 1.87 </span><span style="color:#ffc58f;font-weight:bold;">\*\*逐项一致，0 差异\*\*</span></div><div><span style="color:#bbdaff;"> </span><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 真实调用通过：</span><span style="color:#ff9da4;">`qwen3.7-plus`</span><span style="color:#bbdaff;">、</span><span style="color:#ff9da4;">`deepseek-v4-flash-vision-exp`</span><span style="color:#bbdaff;"> 均正常返回</span></div><div><span style="color:#bbdaff;">5.</span><span style="color:#bbdaff;"> 兼容性风险</span></div><div><span style="color:#bbdaff;"> </span><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 1.88-1.98 release notes </span><span style="color:#ffc58f;font-weight:bold;">\*\*无 Breaking Changes 段落\*\*</span></div><div><span style="color:#bbdaff;"> </span><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 已知高危 issue #33650（1.90.0 起全新库迁移静默失败）已在 </span><span style="color:#ffc58f;font-weight:bold;">\*\*v1.90.6 修复\*\*</span><span style="color:#bbdaff;">，且只影响全新库；本次是增量升级，不受影响</span></div><div><span style="color:#bbdaff;"> </span><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 预检日志中无 unknown / invalid / deprecated 配置项告警</span></div>  
<div><span style="color:#ffffff;">---</span></div>  
<div><span style="color:#d1f1a9;font-weight:bold;">\## 三、升级步骤</span></div>  
<div><span style="color:#d1f1a9;font-weight:bold;">\### 步骤 0：升级前再备份一次（务必，捕获当天用量数据）</span></div>  
<div><span style="color:#ffffff;">```bash</span></div><div><span style="color:#bbdaff;">cd</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">/opt/litellm</span></div><div><span style="color:#bbdaff;">cp</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">config.yaml</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">config.yaml.bak.</span><span style="color:#ffffff;">$(</span><span style="color:#bbdaff;">date</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">+%Y%m%d-%H%M</span><span style="color:#ffffff;">)</span></div><div><span style="color:#bbdaff;">cp</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">docker-compose.yml</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">docker-compose.yml.bak.</span><span style="color:#ffffff;">$(</span><span style="color:#bbdaff;">date</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">+%Y%m%d-%H%M</span><span style="color:#ffffff;">)</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">exec</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm-postgres</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">pg\_dump</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-U</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-d</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-Fc</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-f</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">/tmp/pre.dump</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">cp</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm-postgres:/tmp/pre.dump</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">/opt/litellm/backup\_before\_1.98\_</span><span style="color:#ffffff;">$(</span><span style="color:#bbdaff;">date</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">+%Y%m%d-%H%M</span><span style="color:#ffffff;">)</span><span style="color:#d1f1a9;">.dump</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">exec</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm-postgres</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">rm</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-f</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">/tmp/pre.dump</span></div><div><span style="color:#bbdaff;">ls</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-lh</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">/opt/litellm/backup\_before\_1.98\_</span><span style="color:#ff9da4;">\*</span><span style="color:#d1f1a9;">.dump</span></div><div><span style="color:#ffffff;">```</span></div>  
<div><span style="color:#d1f1a9;font-weight:bold;">\### 步骤 1：改镜像 tag</span></div>  
<div><span style="color:#ffffff;">```bash</span></div><div><span style="color:#bbdaff;">cd</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">/opt/litellm</span></div><div><span style="color:#bbdaff;">sed</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-i</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">'s#image: ghcr.io/berriai/litellm:1.87.0#image: ghcr.nju.edu.cn/berriai/litellm:1.98.0#'</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">docker-compose.yml</span></div><div><span style="color:#bbdaff;">grep</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-n</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">"image:"</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">docker-compose.yml</span></div><div><span style="color:#ffffff;">```</span></div>  
<div><span style="color:#d1f1a9;font-weight:bold;">\### 步骤 2：重建容器（只动 litellm，postgres 不重启）</span></div>  
<div><span style="color:#ffffff;">```bash</span></div><div><span style="color:#bbdaff;">cd</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">/opt/litellm</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">compose</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">up</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-d</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span></div><div><span style="color:#ffffff;">```</span></div>  
<div><span style="color:#d1f1a9;font-weight:bold;">\### 步骤 3：盯日志确认迁移与模型加载</span></div>  
<div><span style="color:#ffffff;">```bash</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">logs</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-f</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span></div><div><span style="color:#ffffff;">```</span></div>  
<div><span style="color:#ffffff;">成功标志（顺序出现）：</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> </span><span style="color:#ff9da4;">`Applying migration ...`</span><span style="color:#bbdaff;">（28 条）</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> </span><span style="color:#ff9da4;">`Migration diff applied successfully`</span><span style="color:#bbdaff;"> + </span><span style="color:#ff9da4;">`Post-migration sanity check completed`</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> </span><span style="color:#ff9da4;">`LiteLLM: Proxy initialized with Config, Set models:`</span><span style="color:#bbdaff;"> 后列出 11 个模型</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 无 </span><span style="color:#ff9da4;">`Traceback`</span><span style="color:#bbdaff;"> / </span><span style="color:#ff9da4;">`ERROR`</span></div>  
<div><span style="color:#ff9da4;">`Ctrl+C`</span><span style="color:#ffffff;"> 退出日志跟踪。</span></div>  
<div><span style="color:#d1f1a9;font-weight:bold;">\### 步骤 4：验证</span></div>  
<div><span style="color:#ffffff;">```bash</span></div><div><span style="color:#7285b7;">\# 健康检查</span></div><div><span style="color:#bbdaff;">curl</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-s</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">http://127.0.0.1:4000/health/readiness</span></div><div><span style="color:#7285b7;">\# 期望 {"status":"healthy","db":"connected"}</span></div>  
<div><span style="color:#7285b7;">\# 模型数量应为 11</span></div><div><span style="color:#bbdaff;">curl</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-s</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">http://127.0.0.1:4000/v1/models</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-H</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">"Authorization: Bearer sk-xxxxxxxxxxxx"</span><span style="color:#ffffff;"> </span><span style="color:#99ffff;">|</span><span style="color:#ffffff;"> </span><span style="color:#bbdaff;">python3</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-c</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">"import json,sys; d=json.load(sys.stdin); print(len(d\['data'\])); \[print(' -',m\['id'\]) for m in d\['data'\]\]"</span></div>  
<div><span style="color:#7285b7;">\# 实际调用一次最便宜的模型</span></div><div><span style="color:#bbdaff;">curl</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-s</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">http://127.0.0.1:4000/v1/chat/completions</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-H</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">"Authorization: Bearer sk-xxxxxxxxxxxx"</span><span style="color:#ffffff;"> </span><span style="color:#ffc58f;">\\</span></div><div><span style="color:#ffffff;"> -H "Content-Type: application/json" \\</span></div><div><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-d</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">'{"model":"qwen3.7-plus","messages":\[{"role":"user","content":"hi"}\],"max\_tokens":5}'</span></div>  
<div><span style="color:#7285b7;">\# 确认版本</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">exec</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">--version</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">inspect</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">--format</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">"{{.Config.Image}}"</span></div><div><span style="color:#ffffff;">```</span></div>  
<div><span style="color:#ffffff;">界面侧还要确认：</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> Costs 页面 11 个模型金额正常（单位仍显示 </span><span style="color:#ff9da4;">`$`</span><span style="color:#bbdaff;">，数值为人民币口径不变）</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> Usage / 预算 / Key 列表能正常打开</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> Admin UI 这版从 antd/Tremor 改为 shadcn，</span><span style="color:#ffc58f;font-weight:bold;">\*\*外观会变\*\*</span><span style="color:#bbdaff;">，属预期</span></div>  
<div><span style="color:#ffffff;">---</span></div>  
<div><span style="color:#d1f1a9;font-weight:bold;">\## 四、回滚方案</span></div>  
<div><span style="color:#d1f1a9;font-weight:bold;">\### 方案 A（首选，轻量）：改回旧镜像</span></div>  
<div><span style="color:#ffffff;">1.98 新增的都是新表/新列，1.87 的 Prisma 只查询已知列，通常可直接回退：</span></div>  
<div><span style="color:#ffffff;">```bash</span></div><div><span style="color:#bbdaff;">cd</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">/opt/litellm</span></div><div><span style="color:#bbdaff;">sed</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-i</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">'s#image: ghcr.nju.edu.cn/berriai/litellm:1.98.0#image: ghcr.io/berriai/litellm:1.87.0#'</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">docker-compose.yml</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">compose</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">up</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-d</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">logs</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-f</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span></div><div><span style="color:#ffffff;">```</span></div>  
<div><span style="color:#ffffff;">若 1.87 启动报迁移相关错误（</span><span style="color:#ff9da4;">`relation does not exist`</span><span style="color:#ffffff;"> / </span><span style="color:#ff9da4;">`migration state mismatch`</span><span style="color:#ffffff;">），删除 1.98 新增的迁移记录后重启：</span></div>  
<div><span style="color:#ffffff;">```bash</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">exec</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm-postgres</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">psql</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-U</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-d</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-c</span><span style="color:#ffffff;"> </span><span style="color:#ffc58f;">\\</span></div><div><span style="color:#ffffff;"> "DELETE FROM \\"\_prisma\_migrations\\" WHERE migration\_name &gt; '20260514120000\_add\_blocked\_to\_proxy\_model\_table';"</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">compose</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">restart</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span></div><div><span style="color:#ffffff;">```</span></div>  
<div><span style="color:#d1f1a9;font-weight:bold;">\### 方案 B（彻底）：用备份重建库</span></div>  
<div><span style="color:#ffffff;">```bash</span></div><div><span style="color:#bbdaff;">cd</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">/opt/litellm</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">compose</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">stop</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">exec</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm-postgres</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">psql</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-U</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-d</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">postgres</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-c</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">"DROP DATABASE litellm;"</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">exec</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm-postgres</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">psql</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-U</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-d</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">postgres</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-c</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">"CREATE DATABASE litellm OWNER litellm;"</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">cp</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">backup\_before\_1.98\_</span><span style="color:#99ffff;">&lt;</span><span style="color:#d1f1a9;">时间</span><span style="color:#ffffff;">戳</span><span style="color:#99ffff;">&gt;</span><span style="color:#d1f1a9;">.dump</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm-postgres:/tmp/r.dump</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">exec</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm-postgres</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">pg\_restore</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-U</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-d</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">/tmp/r.dump</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">--no-owner</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">exec</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">litellm-postgres</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">rm</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-f</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">/tmp/r.dump</span></div><div><span style="color:#7285b7;">\# 同时把 docker-compose.yml 的 image 改回 1.87.0</span></div><div><span style="color:#bbdaff;">docker</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">compose</span><span style="color:#ffffff;"> </span><span style="color:#d1f1a9;">up</span><span style="color:#ffffff;"> </span><span style="color:#ffffff;">-d</span></div><div><span style="color:#ffffff;">```</span></div>  
<div><span style="color:#ffc58f;">&gt; 注意：方案 B 会丢弃备份点之后的所有用量与 Key 数据，属最后手段。</span></div>  
<div><span style="color:#ffffff;">---</span></div>  
<div><span style="color:#d1f1a9;font-weight:bold;">\## 五、1.98.0 相对 1.87.0 新增的 28 个迁移（回滚清理时对照用）</span></div>  
<div><span style="color:#ffffff;">```</span></div><div><span style="color:#ffffff;">20260520120000\_add\_mcp\_env\_vars</span></div><div><span style="color:#ffffff;">20260526120000\_add\_oauth\_passthrough\_to\_mcp\_servers</span></div><div><span style="color:#ffffff;">20260604120000\_add\_oauth2\_flow\_to\_mcp\_servers</span></div><div><span style="color:#ffffff;">20260605182307\_add\_timeout\_to\_mcp\_server\_table</span></div><div><span style="color:#ffffff;">20260626120000\_add\_mcp\_tool\_search\_enabled</span></div><div><span style="color:#ffffff;">20260629000000\_add\_max\_concurrent\_requests\_to\_mcp\_server\_table</span></div><div><span style="color:#ffffff;">20260630120000\_add\_token\_exchange\_to\_mcp\_servers</span></div><div><span style="color:#ffffff;">20260630190000\_add\_budget\_fallbacks\_to\_litellm\_verification\_token</span></div><div><span style="color:#ffffff;">20260703120000\_add\_token\_exchange\_profile\_to\_mcp\_servers</span></div><div><span style="color:#ffffff;">20260710000000\_add\_dcr\_bridge\_to\_mcp\_server\_table</span></div><div><span style="color:#ffffff;">20260713010000\_add\_ptu\_columns\_to\_daily\_team\_spend</span></div><div><span style="color:#ffffff;">20260713230852\_add\_key\_type\_to\_litellm\_verification\_token</span></div><div><span style="color:#ffffff;">20260715000000\_add\_issuer\_to\_mcp\_server\_table</span></div><div><span style="color:#ffffff;">20260717000000\_add\_compression\_saved\_tokens</span></div><div><span style="color:#ffffff;">20260717000000\_add\_mcp\_server\_oauth\_client\_table</span></div><div><span style="color:#ffffff;">20260718000000\_add\_savings\_spend</span></div><div><span style="color:#ffffff;">20260721000000\_add\_sso\_identity\_assertion</span></div><div><span style="color:#ffffff;">20260724000000\_add\_spend\_log\_tool\_index\_start\_time\_idx</span></div><div><span style="color:#ffffff;">20260725000000\_add\_daily\_tool\_spend</span></div><div><span style="color:#ffffff;">20260729000000\_add\_reload\_tracking\_to\_litellm\_config</span></div><div><span style="color:#ffffff;">20260730000000\_add\_api\_key\_and\_request\_tags\_to\_managed\_object\_table</span></div><div><span style="color:#ffffff;">20260731000000\_add\_autorouter\_savings\_spend</span></div><div><span style="color:#ffffff;">20260803000000\_add\_daily\_gateway\_requests</span></div><div><span style="color:#ffffff;">20260805000000\_add\_autorouter\_session\_rollup</span></div><div><span style="color:#ffffff;">20260807000000\_add\_autorouter\_session\_tier\_turns</span></div><div><span style="color:#ffffff;">20260810000000\_add\_verificationtoken\_settings\_updated\_at</span></div><div><span style="color:#ffffff;">20260811172448\_add\_shadow\_eval</span></div><div><span style="color:#ffffff;">20260813180408\_add\_shadow\_eval\_direction</span></div><div><span style="color:#ffffff;">```</span></div>  
<div><span style="color:#ffffff;">升级前库内迁移头（回滚判定基线）：</span><span style="color:#ff9da4;">`20260514120000\_add\_blocked\_to\_proxy\_model\_table`</span></div>  
<div><span style="color:#ffffff;">---</span></div>  
<div><span style="color:#d1f1a9;font-weight:bold;">\## 六、注意事项</span></div>  
<div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> </span><span style="color:#ffc58f;font-weight:bold;">\*\*迁移只前进不后退\*\*</span><span style="color:#bbdaff;">：不要只改回 tag 就认为万事大吉，报迁移错时按方案 A 清理 </span><span style="color:#ff9da4;">`\_prisma\_migrations`</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> </span><span style="color:#ffc58f;font-weight:bold;">\*\*不要改 </span><span style="color:#ff9da4;">`LITELLM\_MASTER\_KEY`</span><span style="color:#ffc58f;font-weight:bold;">\*\*</span><span style="color:#bbdaff;">：当前未在 compose 显式设置 </span><span style="color:#ff9da4;">`LITELLM\_SALT\_KEY`</span><span style="color:#bbdaff;">，LiteLLM 用 master key 派生加密盐，改 master key 会导致库内已存的 LLM API Key 无法解密</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> </span><span style="color:#ffc58f;font-weight:bold;">\*\*保留 1.87.0 镜像\*\*</span><span style="color:#bbdaff;">：升级后近期不要 </span><span style="color:#ff9da4;">`docker image prune`</span><span style="color:#bbdaff;">，它是快速回滚的保险</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> </span><span style="color:#ffc58f;font-weight:bold;">\*\*1.98 会多一条启动 warning\*\*</span><span style="color:#bbdaff;">：</span><span style="color:#ff9da4;">`register\_model: model=... not in built-in cost map ... cache cost fields will default to 0`</span><span style="color:#bbdaff;">。只影响“缓存写入（cache creation）”成本统计，现有 </span><span style="color:#ff9da4;">`cache\_read\_input\_token\_cost`</span><span style="color:#bbdaff;"> 照常生效（已实测单价一致）。如要消除，可在各 </span><span style="color:#ff9da4;">`model\_info`</span><span style="color:#bbdaff;"> 补 </span><span style="color:#ff9da4;">`cache\_creation\_input\_token\_cost`</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> </span><span style="color:#ffc58f;font-weight:bold;">\*\*1.98.0 主要新特性\*\*</span><span style="color:#bbdaff;">（与本项目相关）：PTU 按部署计费、可调用的 routing groups、6 个 </span><span style="color:#ff9da4;">`x-litellm-response-cost-\*`</span><span style="color:#bbdaff;"> 响应头拆分成本、Admin UI 大改版</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> 升级当天留意 SMTP 告警邮件是否正常发出（</span><span style="color:#ff9da4;">`alerting: \["email"\]`</span><span style="color:#bbdaff;"> 依赖 compose 中的 SMTP 变量）</span></div>  
<div><span style="color:#ffffff;">---</span></div>  
<div><span style="color:#d1f1a9;font-weight:bold;">\## 七、执行确认清单</span></div>  
<div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> \[ \] 步骤 0 当天新备份已生成并确认文件大小</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> \[ \] 步骤 1 image 行已改为 </span><span style="color:#ff9da4;">`ghcr.nju.edu.cn/berriai/litellm:1.98.0`</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> \[ \] 步骤 3 日志出现 28 条 Applying migration 且无 ERROR</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> \[ \] 步骤 4 健康检查 healthy + db connected</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> \[ \] 步骤 4 </span><span style="color:#ff9da4;">`/v1/models`</span><span style="color:#bbdaff;"> 返回 11 个模型</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> \[ \] 步骤 4 实际调用返回 200</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> \[ \] Costs 页面金额与升级前一致</span></div><div><span style="color:#bbdaff;">-</span><span style="color:#bbdaff;"> \[ \] 业务侧同事确认网关可用</span></div>  
</div>

# DeepSeek Harness 部署方案

已确认项目身份与全部部署参数（官方仓库、npm 版本、Node 要求、启动参数、凭据解析）。以下是 Ubuntu 24.04 的部署方案：

---

## 项目与最新版本

- **DeepSeek Harness（`dsh`）**：DeepSeek 官方开源 agent 框架，采用“一切皆插件”架构（基于 Cordis）。仓库：[deepseek-ai/deepseek-harness](https://github.com/deepseek-ai/deepseek-harness)，文档：[官方文档站](https://deepseek-harness.github.io/deepseek-harness/)。
- **最新版本**：npm `latest` = `0.1.5-rc.1`（2026-09-10 发布）；`next` 通道 = `0.1.5-rc.2`（最新）。处于开发者预览阶段，**会有破坏兼容性的变更**，部署时建议钉住版本号。
- **运行要求**：Node.js `^22.19.0 || >=24.0.0`（package.json `engines`），Ubuntu 24.04 上推荐 **Node 24 LTS**。
- **默认端口**：`http://127.0.0.1:3080`。

## 推荐部署形态

- **npm 全局安装 + systemd 守护**：`dsh web` 本身只监听本机，适合再套一层 nginx 反代 + HTTPS。
- **不建议用 Docker**：官方维护者指出容器路线有已知坑（pnpm 符号链接、`node-pty` 等原生模块与 musl/glibc、profile patch 被卷挂载覆盖），npm 直装最稳。
- 生产建议：`127.0.0.1` 回环绑定（webserver 无内置 TLS/鉴权），远程访问走 SSH 隧道或 nginx+HTTPS。

## 部署步骤

**1. 前置准备（Ubuntu 24.04）**

```
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl ca-certificates git ufw
# 全程用非 root 的 sudo 用户执行
```

**2. 安装 Node.js 24 LTS（NodeSource）**

```
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt install -y nodejs
node -v   # 必须 >= v22.19，推荐 v24.x
npm -v
```

**3. 创建运行用户与工作区目录**

```
sudo useradd --system --create-home --shell /usr/sbin/nologin dsh
sudo mkdir -p /srv/dsh/workspace
sudo chown -R dsh:dsh /srv/dsh
# 启动时所在目录 = 默认 workspace 根目录（Web UI 里还需手动“选择工作区”）
```

**4. 全局安装 DeepSeek Harness（钉住版本）**

```
sudo npm install -g @deepseek-ai/dsh@0.1.5-rc.1
dsh --version        # 预期 0.1.5-rc.1
dsh --help
```

> 想用最新 `rc.2` 就装 `@deepseek-ai/dsh@0.1.5-rc.2`。CLI 参数：`dsh --profile web`（`web` 是别名），web 应用参数需放在其后：`--host`（仅 `127.0.0.1`/`0.0.0.0`）、`--port`、可重复的 `--trusted-host`、`--no-open`。

**5. 配置 DeepSeek API Key（无交互方式）**

凭据解析顺序：进程环境变量 → `$DSH_HOME/.credentials.yaml` → 调用目录 `.env` → `$DSH_HOME/.env`（$DSH\_HOME 默认 `~/.dsh`）。Web 搜索使用 `DEEPSEEK_API_KEY`。推荐直接在 systemd 里注入环境变量（第 6 步会用）。

手动方式也可以：启动后浏览器打开 `http://127.0.0.1:3080` → **设置 → 模型** → DeepSeek 卡片填 Key（密钥只写，存于 `$DSH_HOME/.credentials.yaml`）。模型变更立即生效，无需重启。

**6. systemd 服务**

```
# /etc/systemd/system/dsh.service
[Unit]
Description=DeepSeek Harness Web UI
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=dsh
Group=dsh
WorkingDirectory=/srv/dsh/workspace
Environment=DSH_HOME=/home/dsh/.dsh
Environment=DEEPSEEK_API_KEY=sk-你的密钥
ExecStart=/usr/bin/dsh web --no-open --host 127.0.0.1 --port 3080
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
```

```
sudo systemctl daemon-reload
sudo systemctl enable --now dsh
journalctl -u dsh -f          # 观察 "dsh web:" URL 行（内含进程 token，属敏感信息）
curl -sI http://127.0.0.1:3080/ | head -1   # 预期 HTTP/1.1 200
```

> 若 `dsh` 不在 `/usr/bin`，用 `which dsh` 修正 `ExecStart`。

**7.（可选）nginx 反代 + HTTPS（远程访问必做）**

```
# /etc/nginx/sites-available/dsh
server {
    listen 80;
    server_name dsh.example.com;
    location / {
        proxy_pass http://127.0.0.1:3080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;      # WebSocket 必需
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
```

```
sudo ln -s /etc/nginx/sites-available/dsh /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d dsh.example.com
```

浏览器同源策略要求：反代后需把域名加入可信主机，否则 WebSocket 连不上 → 在服务参数追加 `--trusted-host dsh.example.com`（重启生效）。需要登录密码可选装社区插件 `dsh-webui-auth`；自己只想内网用的也可以不加反代，直接 `ssh -L 3080:127.0.0.1:3080 user@server` 隧道访问。

**8. 防火墙与验收**

```
sudo ufw allow OpenSSH && sudo ufw allow 80/tcp && sudo ufw allow 443/tcp && sudo ufw enable
```

验收：浏览器打开 `https://dsh.example.com` → 设置→模型配 Key → 选择工作区 → 发一条任务（例如“Summarize this repository”）→ 确认能读文件、跑命令、委派子任务。

## 运维与注意事项

- **升级**：开发者预览迭代快，升级前备份整个 $DSH\_HOME（`settings.yaml`、`.credentials.yaml`、`profiles/`、会话库），再 `sudo npm install -g @deepseek-ai/dsh@<新版本>`；先看 npm 发布说明和 [SAFETY.md](https://github.com/deepseek-ai/deepseek-harness/blob/master/SAFETY.md)。
- **安全**：保持回环绑定；启动 URL 里的进程 token 是 API/WebSocket 的认证凭据，注意别把完整 URL 打进日志/截图；密钥只写入 `$DSH_HOME/.credentials.yaml`，建议 `chmod 600`；`0.0.0.0` 直绑无 TLS 无鉴权，谨慎。
- **扩展**：一次性任务用 `dsh --profile headless "任务文本"`；插件管理 `dsh plugin --profile web add <包>`（需 pnpm，`sudo corepack enable && corepack prepare pnpm@latest --activate`）；国内网络需代理时见文档 [network-proxy](https://github.com/deepseek-ai/deepseek-harness/blob/master/docs/user/guide/network-proxy.zh.md)。

现状确认：服务器没有 pnpm（需要用 corepack/npm 启用），`dsh plugin` 必须带 `--profile`。给你一套可直接照抄的完整示例——以官方插件 **Codex 子代理（`@deepseek-ai/dsh-subagent-codex`）** 为例：

## 第一步：装 pnpm（dsh 插件管理依赖它）

```
sudo npm install -g pnpm@11.7.0     # 项目本身用的 pnpm 11.7.0
pnpm --version                       # 验证
```

## 第二步：安装插件到 web 配置

```
sudo -u dsh /usr/bin/dsh plugin --profile web add @deepseek-ai/dsh-subagent-codex
```

要点：

- 必须用 `sudo -u dsh` 跑（profile 在 `/home/dsh/.dsh/profiles/web` 下，以 dsh 用户运行才能读到正确的 `DSH_HOME`）
- `--profile web` 指定装到哪个配置（还有 `headless`、`sdk`、`acp` 或自定义 profile）
- 该命令等价于在该 profile 目录里执行 `pnpm add`，装完会自动把包写进 `dsh.profile.bundles`（因为包的 `package.json` 声明了 `"dsh": {"bundle": {"patch": "./cordis.patch.yml"}}`）

## 第三步：重启服务让新 bundle 挂载

```
sudo systemctl restart dsh
dsh-url        # 重启后 token 变了，取新访问地址
```

## 第四步：验证

```
sudo -u dsh /usr/bin/dsh plugin --profile web list        # 已安装列表
sudo -u dsh env DSH_HOME=/home/dsh/.dsh /usr/bin/dsh --profile web --dump-config | grep -i subagent
```

Web UI 里新建会话后，Agent 面板会出现 Codex 子代理提供方（实际可用还要求服务器上装了 Codex CLI 并完成登录）。

## 其他“装插件”的形态（顺带说明）

- **移除**：`sudo -u dsh /usr/bin/dsh plugin --profile web remove @deepseek-ai/dsh-subagent-codex`，然后重启
- **本地/社区插件**：`... plugin --profile web add <npm包名>`，或本地目录 `... add /path/to/plugin`（GitHub 上带 `dsh-plugin` topic 的都是生态插件）
- **可选覆盖层（非 npm 包）**：官方 `config/examples/` 里的 github-review、schedule、mcp-memory 是 cordis patch 文件，用 `dsh --profile web --patch ./xx.yml` 或写入 `cordis.patch.yml`，不需要 pnpm

需要我直接在服务器上把 pnpm 和这个 Codex 子代理插件装上吗？装完我会重启并给你新的访问地址。

核实完毕，关键事实已确认：**会话库在 `$DSH_HOME/sessions/<工作区>/` 下，一个进程只有一个 token、一份会话库、一份设置**——这就是"所有人会话互相可见"的根本原因（当前版本 Web 版是单用户设计，没有内置账号体系）。

## 隔离方案：每人一个独立实例（推荐）

核心思路：**每用户 = 独立 DSH\_HOME + 独立端口 + 独立 token + 独立工作区**，互不共享任何状态。以给 `alice` 开一个为例：

**1. 建独立系统用户与工作区（文件系统这一层也隔离）**

```
sudo useradd -m -s /usr/sbin/nologin alice
sudo mkdir -p /srv/dsh-alice/workspace
sudo chown -R alice:alice /srv/dsh-alice
```

**2. 新建 systemd 实例（独立 DSH\_HOME、独立端口 3081、独立密钥）**

```
# /etc/systemd/system/dsh-alice.service
[Unit]
Description=DeepSeek Harness Web UI (alice)
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=alice
Group=alice
WorkingDirectory=/srv/dsh-alice/workspace
Environment=DSH_HOME=/home/alice/.dsh
Environment=DEEPSEEK_API_KEY=sk-alice自己的密钥
ExecStart=/usr/bin/dsh --profile web --no-open --host 127.0.0.1 --port 3081
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target
```

```
sudo systemctl daemon-reload && sudo systemctl enable --now dsh-alice
```

**3. nginx 给它单独开一个端口（dsh 不让直接绑 0.0.0.0）**

```
# /etc/nginx/sites-available/dsh-alice
server {
    listen 8081;                 # alice 专属入口
    location / {
        proxy_pass http://127.0.0.1:3081;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
    }
}
```

启用后 `sudo nginx -t && sudo systemctl reload nginx`。

**4. 给 alice 发登录地址（每个实例 token 独立）**

```
sudo -u alice env DSH_HOME=/home/alice/.dsh /usr/bin/dsh-url   # 或从 journalctl 取
```

Alice 打开 `http://192.168.4.17:8081/?token=<她的token>`，她只会看到自己的会话、设置、密钥；Bob 用 8082/3082 同理。各自实例记得加 `--trusted-host 192.168.4.17`（如果和共享实例一样用 IP 访问）。

## 为什么不建议其他做法

- **单实例 + 密码插件（`dsh-webui-auth`）**：只能挡陌生人，登录后仍是同一个 token/同一份会话库，**做不到会话隔离**
- **单实例内分工作区**：会话虽按工作区目录存放（`$DSH_HOME/sessions/...`），但任何人拿到 token 都能切到任意工作区查看/操作，代理也能读其他目录，隔离形同虚设
- **共享 `DSH_HOME` 跑多个 profile**：`sessions`、设置、凭据都在同一个 $DSH\_HOME 下，仍互相可见

## 安全边界提醒

这个方案保证的是**会话/设置/入口隔离**。如果用户之间不完全互信，还需要：

- 各自独立工作区目录 + 独立 OS 用户（agent 以该 OS 用户执行命令，读不到别人的目录）
- 每个实例的 token 只发给对应的人；局域网里 token 即权限

需要我直接在服务器上把 `alice` 这个实例（用户、目录、unit、nginx 端口、token）完整建好吗？建好后把她的访问地址单独给你。