个人站点:www.loginext.cn/home.html

从通义到智谱、从裸跑 RAG 到企业级平台:RAG 平台 V2 升级全记录

前置阅读:本文是 [Claude Code + 通义千问,从零搭出生产级 RAG 要花多少钱?) 的续篇。V1 版本记录了「Claude Code 写规格 + 通义千问做推理」从零搭建生产级 RAG 的全过程(14 个 Bug、约 100 元 API 成本)。V2 在 V1 基础上完成了模型切换、安全加固、可观测性补全与前端企业级改造。
说明:当前升级全部使用claude code + 智普Coding plan来完成,当前文档也是claude cod + 智普GLM5.1来生成的。

升级背景与动机

V1 跑通后暴露了几个明确的短板:

  1. 无认证、无审计:任何能访问后端端口的人都能操作全部 API,无法满足企业部署合规要求
  2. 评测只有面板壳子:前端有评估面板 UI,但后端没有真正的评测管道,指标全靠手填
  3. 模型侧隐患:LangChain OpenAIEmbeddings 对通义 API 返回零向量的 Bug 虽然绕过了(用 configuration.baseURL),但长期来看 LangChain 对国内 API 的兼容性不可控
  4. 缺少监控:生产系统需要实时知道「请求延迟多少、错误率多少、缓存命中多少」,V1 全靠 console.log
  5. 没有用户反馈闭环:产品侧无法收集「这个回答有没有帮助」,无法量化模型表现

升级全景:从 V1 到 V2 的变更总览

V1(第一版)                              V2(升级版)
┌──────────────────────┐                ┌──────────────────────┐
│ 通义 qwen3.6-plus    │  ──切换──→     │ 智谱 GLM-4.5-Air     │
│ text-embedding-v3    │                │ embedding-3 (2048维)  │
│ (1024维)             │                │                      │
├──────────────────────┤                ├──────────────────────┤
│ 无认证               │  ──新增──→     │ JWT + 角色控制        │
│ 无审计               │                │ 完整审计日志          │
│ console.log          │                │ Prometheus 指标       │
│ 无用户反馈           │                │ 用户反馈系统          │
├──────────────────────┤                ├──────────────────────┤
│ 评测面板(空壳)      │  ──实现──→     │ 端到端评测管道        │
│                      │                │ HitRate/MRR/忠实度等  │
│                      │                │ A/B 测试能力          │
├──────────────────────┤                ├──────────────────────┤
│ LangChain Embeddings │  ──重写──→     │ 直接 fetch 调 API     │
│ (兼容性不可控)        │                │ (绕过 LangChain)      │
├──────────────────────┤                ├──────────────────────┤
│ 5 种文档解析器        │  ──新增──→     │ + GLM-OCR 图片解析    │
│                      │                │ (保留表格/公式/版式)   │
├──────────────────────┤                ├──────────────────────┤
│ 前端四面板            │  ──扩展──→     │ + 登录/注册           │
│                      │                │ + 管理员审计日志      │
│                      │                │ + 实时监控面板        │
│                      │                │ + 配置调参面板增强     │
└──────────────────────┘                └──────────────────────┘

一、模型切换:从通义到智谱

1.1 切换原因

V1 使用通义千问 qwen3.6-plus 作为对话模型,text-embedding-v3 作为向量模型(经阿里百炼 OpenAI 兼容接口调用)。升级时切换到智谱 AI 的原因:

买了智普的coding plan,想试试包月Pro的token量是否能满足日常的工作需求,同时开通了两个体验资源包,Embedding-3、GLM-OCR。

1.2 模型对应关系

功能 V1 V2
对话/生成 qwen3.6-plus(通义) GLM-4.5-Air(智谱)
向量嵌入 text-embedding-v3(1024维) embedding-3(2048维)
API 基地址 dashscope.aliyuncs.com/compatible-mode/v1 open.bigmodel.cn/api/paas/v4
OCR glm-ocr(智谱布局解析)
Rerank Cohere Cohere(未变)

1.3 Embedding 客户端重写

这是本次升级改动最核心、踩坑最深的一处。

V1 的 Embedding 客户端使用 LangChain 的 OpenAIEmbeddings

// V1 写法(已废弃)
new OpenAIEmbeddings({
  model: 'text-embedding-v3',
  apiKey: 'sk-...',
  configuration: { baseURL: 'https://dashscope.aliyuncs.com/compatible-mode/v1' },
  dimensions: 1024,
});

切换到智谱后,OpenAIEmbeddings 对智谱 API 返回零向量——不是报错,而是静默返回 [0, 0, 0, ...]。这个 Bug 比 V1 的 baseUrl 问题更隐蔽:V1 至少是超时或 0 条结果,这次是「向量全零但入库成功、检索永远不匹配」。

解决方案:完全绕过 LangChain,直接用 fetch 调用智谱 /v4/embeddings 端点:

// V2 写法 — 直接 fetch,不依赖 LangChain
export async function callEmbeddingAPI(
  input: string[],
  apiKey: string,
  baseURL: string,
  model: string,
): Promise<number[][]> {
  const res = await fetch(`${baseURL}/embeddings`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${apiKey}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ model, input }),
  });
  const data = await res.json();
  return data.data
    .sort((a, b) => a.index - b.index)
    .map(d => d.embedding);
}

新增的 OpenAIEmbeddingProvider 类支持:

  • embed(texts) — 单批嵌入
  • embedMany(texts) — 分批嵌入(每批 50 条,避免 API 限流)
  • embedQuery(text) — 单条查询嵌入(供 retrieve.node.ts 使用)

1.4 向量维度从 1024 升到 2048

智谱 embedding-3 默认输出 2048 维向量,Milvus 集合需要重建:

// vectorstore/schema.ts — V1 写死 1024,V2 从配置读取
export function getDenseVectorDim(): number {
  return getConfig().EMBEDDING_DIMENSION; // 从 .env 读取,当前为 2048
}

操作步骤

  1. 修改 .envEMBEDDING_DIMENSION=2048
  2. 删除旧 Milvus 集合(维度不可修改)
  3. 重启后端自动重建集合
  4. 重新上传文档入库

经验:维度变更意味着全量重建。生产环境应在设计时考虑「维度可变」策略,或在切换模型前评估重建成本。

1.5 LLM 客户端调整

LLM 侧改动较小,ChatOpenAI 对智谱 API 兼容性良好,只需调整 base URL:

// llm/openai.ts — 支持 OpenAI 兼容 API(阿里百炼、智谱等通过 LLM_BASE_URL 切换)
instance = new ChatOpenAI({
  model: resolvedModel,       // GLM-4.5-Air
  apiKey: config.LLM_API_KEY,
  configuration: { baseURL: config.LLM_BASE_URL }, // open.bigmodel.cn/api/paas/v4
  temperature: resolvedTemp,
  maxTokens: config.LLM_MAX_TOKENS,
  streaming: true,
});

增加了实例缓存(按 模型名:温度 做 key),避免重复创建连接。


二、认证与授权系统

2.1 JWT 认证流程

用户注册/登录 → 签发 Access Token (15min) + Refresh Token (7d)
     ↓
每次请求携带 Access Token → auth 中间件验证 → 设置 request.user
     ↓
Token 过期 → 前端自动用 Refresh Token 刷新 → 获取新 Access Token
     ↓
登出 → 服务端清除 Refresh Token

2.2 实现细节

新增文件

  • services/auth.service.ts — JWT 签发/验证、密码哈希、用户 CRUD
  • server/middleware/auth.ts — Fastify preHandler 钩子
  • server/routes/auth.ts — 注册/登录/刷新/登出/用户信息 5 个端点
  • db/migrations/002_auth.sqlusers 表 + refresh_tokens

角色控制

// 中间件用法
app.post('/api/v1/query', { preHandler: [requireAuth] }, handler);  // 需登录
app.get('/api/v1/admin/audit', { preHandler: [requireAuth, requireRole('admin')] }, handler);  // 需管理员

前端集成

  • stores/authStore.ts — Zustand 管理登录状态、自动刷新、localStorage 持久化
  • api/client.ts — Axios 拦截器自动注入 Token、401 时自动刷新
  • LoginPage.tsx — 登录/注册二合一界面

2.3 多租户数据隔离

002_auth.sqldocumentschunkseval_results 等表添加 user_id 字段:

  • 普通用户只能看到自己的文档和评估结果
  • 管理员可以查看所有数据
  • API 层通过 request.user.id 过滤查询

三、审计日志系统

3.1 自动记录

审计日志通过 Fastify 的 onResponse 钩子自动记录所有 API 请求:

// server/middleware/audit.ts — 自动记录,不影响业务逻辑
app.addHook('onResponse', async (request, reply) => {
  // 跳过健康检查和认证路由,避免自我审计
  if (request.url.startsWith('/health') || request.url.startsWith('/api/v1/auth')) return;

  await auditService.log({
    userId: request.user?.id,
    action: parseAction(request.method),     // create/read/update/delete/execute
    resource: parseResource(request.url),     // documents/query/eval/...
    resourceId: parseResourceId(request.url),
    ip: request.ip,
    userAgent: request.headers['user-agent'],
    statusCode: reply.statusCode,
    duration: reply.elapsedTime,
  });
});

3.2 存储与查询

  • db/migrations/003_audit.sqlaudit_logs 表,含 user_idactionresourceipduration 等字段
  • services/audit.service.ts — 异步写入(不阻塞请求)、管理端分页查询
  • components/admin/AuditLog.tsx — 前端审计日志查看界面,支持按操作类型过滤

四、端到端评测管道

4.1 V1 vs V2 评测对比

维度 V1 V2
指标展示 前端面板有 UI 但数据是假的 真实运行 RAG 管道并计算指标
检索指标 HitRate@K、MRR
生成指标 上下文精确度、上下文召回、忠实度、答案相关性
测试方法 提交评测数据集 + 配置,自动运行
A/B 测试 同一数据集分别用两组配置运行并对比

4.2 指标体系

检索指标(基于文档 ID 匹配,无需 LLM):

  • HitRate@K:检索结果中是否包含任一 ground truth 文档(0 或 1)
  • MRR:第一个匹配 ground truth 的排名倒数

生成指标(LLM 评估,调用 GLM-4.5-Air 打分):

  • Context Precision:检索到的上下文是否包含回答所需的关键信息
  • Faithfulness:答案中的论断是否都有上下文支持
  • Answer Relevance:答案是否直接、完整地回答了用户的问题
  • Context Recall:上下文是否覆盖了标准答案中的所有关键信息

每个指标通过 LLM 评估返回 0.0–1.0 的分数和评估理由。

4.3 LLM 评估实现

// 通用 LLM 评估 — 调用 LLM 获取 0-1 分数
private async llmEval(systemPrompt: string, userMessage: string): Promise<number> {
  const llm = getLLM(undefined, 0);
  const response = await llm.invoke([
    new SystemMessage(systemPrompt),
    new HumanMessage(userMessage),
  ]);
  const jsonMatch = response.content.match(/\{[^}]+\}/s);
  if (jsonMatch) {
    const parsed = JSON.parse(jsonMatch[0]);
    return Math.max(0, Math.min(1, parsed.score));
  }
  return 0;
}

4.4 A/B 测试

// 同一数据集,两组不同配置并行评测
const { metricsA, metricsB } = await evaluationService.abTest(
  dataset,                    // 评测数据集
  { topK: 5, chunkSize: 512 },   // 配置 A
  { topK: 10, chunkSize: 1000 }, // 配置 B
  userId,
);

五、Prometheus 监控指标

5.1 新增依赖

  • metrics.service.ts — 内存中的指标注册中心
  • server/middleware/metrics.ts — 自动采集 HTTP 请求指标
  • server/routes/metrics.tsGET /metrics 返回 Prometheus 文本格式

5.2 采集的指标

指标 类型 说明
http_requests_total Counter HTTP 请求总数
http_request_duration_seconds Histogram 请求延迟分布
http_errors_total Counter 错误请求数
cache_hits_total / cache_misses_total Counter 缓存命中/未命中
process_uptime_seconds Gauge 进程运行时间

5.3 前端监控面板

components/admin/MetricsDashboard.tsx 每 10 秒自动刷新,展示:

  • 总请求数、错误率(颜色编码)
  • 缓存命中率
  • 系统运行时间
  • 请求路径分布

六、GLM-OCR 图片与扫描件解析

6.1 新增能力

V1 支持的文档格式:PDF、DOCX、Excel、HTML、Markdown(5 种文本格式解析器)

V2 新增:图片解析器image.parser.ts)+ GLM-OCR 客户端glm-ocr.ts),支持:

  • JPEG、PNG、BMP、TIFF、WebP(单图 ≤ 10MB)
  • 扫描件 PDF(≤ 50MB,最大 100 页)
  • 输出保留表格、公式、版式的 Markdown 文本

6.2 实现要点

// parsers/glm-ocr.ts — 调用智谱 GLM-OCR 布局解析 API
async parseFile(buffer: Buffer, mimeType: string) {
  const base64 = buffer.toString('base64');
  const dataUri = `data:${mimeType};base64,${base64}`;

  const response = await fetch(`${this.baseUrl}/layout_parsing`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${this.apiKey}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ model: 'glm-ocr', file: dataUri }),
  });
  // 返回 Markdown 格式文本
}

多页 PDF 处理:逐页渲染为 PNG → 逐页调用 GLM-OCR → 合并为带页码标记的 Markdown。


七、用户反馈系统

7.1 反馈收集

  • services/feedback.service.ts — 记录用户对每个回答的反馈(赞/踩 + 文字评论)
  • server/routes/feedback.tsPOST /api/v1/feedback 提交反馈
  • 存储当时的 RAG 配置快照(config_snapshot),便于分析「哪种配置得分高」

7.2 前端反馈组件

ChatWindow.tsx 中每条 AI 回复附带:

  • 赞/踩按钮
  • 置信度徽章
  • 引用来源展开面板
  • 复制按钮

八、前端企业级改造

8.1 新增页面与组件

组件 V1 V2 说明
LoginPage.tsx 登录/注册,密码可见切换
AuditLog.tsx 管理员审计日志,操作类型过滤
MetricsDashboard.tsx 实时监控面板,10 秒刷新
EvalDashboard.tsx 壳子 完整 真实指标 + 7 天趋势 + 运行评测按钮
ConfigPanel.tsx 基础 增强 三 Tab(检索/模型与分块/高级),4 种检索策略 + 4 种分块策略

8.2 App.tsx 路由与权限

┌─ 侧边栏 ──────────────────────────────────┐
│  [对话]   → ChatWindow.tsx                  │
│  [文档]   → DocumentManager.tsx             │
│  [评测]   → EvalDashboard.tsx               │
│  [配置]   → ConfigPanel.tsx                 │
│  ─── 管理员 ───                            │
│  [监控]   → MetricsDashboard.tsx  (admin)   │
│  [审计]   → AuditLog.tsx         (admin)    │
├────────────────────────────────────────────┤
│  用户状态 · Admin 徽章 · 退出               │
└────────────────────────────────────────────┘
  • 未登录 → 显示 LoginPage.tsx
  • 普通用户 → 隐藏管理员菜单项
  • 管理员 → 显示全部菜单

8.3 配置面板增强

V2 的配置面板支持更精细的调参:

检索策略(4 种):

  • standard — 标准检索
  • adaptive — 自适应检索
  • corrective — 纠正性检索
  • multi-hop — 多跳检索

分块策略(4 种):

  • recursive — 递归分块(默认)
  • markdown — 按标题层级
  • semantic — 语义边界
  • hierarchical — 父子结构

LLM 模型可选(智谱系列):

  • GLM-4.5-Air(默认)
  • GLM-4-Plus
  • GLM-4-Flash

九、环境配置变更

9.1 新增环境变量

变量 默认值 说明
EMBEDDING_BASE_URL https://open.bigmodel.cn/api/paas/v4 智谱 Embedding API
EMBEDDING_MODEL embedding-3 智谱向量模型
EMBEDDING_DIMENSION 2048 向量维度
RERANKER_PROVIDER cohere Reranker 提供商
RERANKER_API_KEY Reranker API Key
RERANKER_MODEL rerank-v3-multilingual Reranker 模型
JWT_SECRET JWT 签名密钥(≥16 字符)
JWT_ACCESS_EXPIRES_IN 15m Access Token 有效期
JWT_REFRESH_EXPIRES_IN 7d Refresh Token 有效期
RATE_LIMIT_PER_MINUTE 30 API 限流
STORAGE_PATH ./data/uploads 文件存储路径
MAX_FILE_SIZE 104857600 (100MB) 上传文件大小上限

9.2 变更的环境变量

变量 V1 值 V2 值
LLM_MODEL qwen3.6-plus GLM-4.5-Air
LLM_BASE_URL dashscope.aliyuncs.com/... open.bigmodel.cn/api/paas/v4
RAG_SIMILARITY_THRESHOLD 0.70.2 0.2

十、后端依赖变更

10.1 新增依赖

版本 用途
bcryptjs ^2.4.3 密码哈希
bullmq ^5.77.6 后台任务队列
canvas ^3.2.3 PDF 页面渲染为图片
ioredis ^5.4.0 Redis 客户端(替代 BullMQ 内置)
jsonwebtoken ^9.0.0 JWT 签发/验证
pdfjs-dist ^5.7.284 PDF 页面提取(配合 GLM-OCR)
tesseract.js ^7.0.0 本地 OCR(备选方案)

10.2 前端新增依赖

版本 用途
react-markdown ^10.0.0 Markdown 渲染(AI 回复)
rehype-highlight ^7.0.0 代码高亮

十一、数据库迁移

11.1 002_auth.sql

-- 用户表
CREATE TABLE users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  email VARCHAR(255) UNIQUE NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  name VARCHAR(100),
  role VARCHAR(20) DEFAULT 'user' CHECK (role IN ('admin', 'user')),
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Refresh Token 表
CREATE TABLE refresh_tokens (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES users(id) ON DELETE CASCADE,
  token_hash VARCHAR(255) NOT NULL,
  expires_at TIMESTAMPTZ NOT NULL,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- 为已有表添加 user_id
ALTER TABLE documents ADD COLUMN user_id UUID REFERENCES users(id);
ALTER TABLE chunks ADD COLUMN user_id UUID REFERENCES users(id);

11.2 003_audit.sql

CREATE TABLE audit_logs (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID,
  action VARCHAR(50) NOT NULL,
  resource VARCHAR(100),
  resource_id VARCHAR(255),
  detail JSONB,
  ip VARCHAR(45),
  user_agent TEXT,
  status_code INTEGER,
  duration_ms INTEGER,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE INDEX idx_audit_user ON audit_logs(user_id);
CREATE INDEX idx_audit_action ON audit_logs(action);
CREATE INDEX idx_audit_resource ON audit_logs(resource);
CREATE INDEX idx_audit_created ON audit_logs(created_at);

十二、升级踩坑记录

坑 1:LangChain OpenAIEmbeddings 返回零向量(智谱 API)

表现:文档入库日志显示成功(8 chunks → 8 embeddings → 8 indexed),但检索永远返回 0 条。检查 Milvus 数据发现向量全为 0。

排查过程

  1. Milvus count = 8 ✓
  2. 采样向量 → 全是 [0, 0, 0, ...]
  3. 写独立脚本测试 OpenAIEmbeddings + 智谱 API → 仍然是零向量
  4. curl 直接调智谱 API → 返回正常 2048 维向量 ✓

根因:LangChain OpenAIEmbeddings 内部对非 OpenAI API 的响应格式解析存在 Bug,将实际向量丢弃后填充零值。

解决:完全绕过 LangChain,用原生 fetch 调用智谱 API(见 1.3 节代码)。

教训:对于非 OpenAI 的兼容 API,不要盲目信任 LangChain 的封装。先用 curl 或原生 fetch 验证 API 本身是否正常,再决定是否走 SDK。


坑 2:向量维度 1024 → 2048 后 Milvus 集合不兼容

表现:修改 .envEMBEDDING_DIMENSION=2048 后重启,Milvus 插入报错「向量维度不匹配」。

根因:Milvus 集合一旦创建,向量维度不可修改。

解决

# 删除旧集合
node -e "
const { MilvusClient } = require('@zilliz/milvus2-sdk-node');
const client = new MilvusClient({ address: 'localhost:19530' });
await client.dropCollection({ collection_name: 'rag_chunks' });
await client.dropCollection({ collection_name: 'rag_document_summaries' });
"
# 重启后端 → 自动重建集合 → 重新上传文档

教训:生产环境应在集合创建时记录维度到元数据,并在启动时校验维度一致性。


坑 3:JWT 密钥长度不足导致签名失败

表现jsonwebtoken.sign() 抛出 Error: secret or private key must be at least 16 characters

解决:Zod schema 中添加 .min(16) 校验:

JWT_SECRET: z.string().min(16, 'JWT_SECRET must be at least 16 characters'),

坑 4:审计日志自我审计(循环写入)

表现:审计日志表疯狂增长,每秒写入数条——审计中间件在记录「写入审计日志」的请求,形成循环。

解决:在审计中间件中排除审计和健康检查路由:

if (request.url.startsWith('/health') || request.url.startsWith('/api/v1/audit')) return;

坑 5:前端 Token 刷新竞态

表现:多个并发请求同时遇到 401 时,各自发起刷新 Token 请求,导致第一个刷新成功后第二个刷新因旧 Token 已失效而报错。

解决:在 api/client.ts 中添加刷新锁:

let isRefreshing = false;
let refreshPromise: Promise<string> | null = null;

async function refreshToken(): Promise<string> {
  if (isRefreshing && refreshPromise) return refreshPromise;
  isRefreshing = true;
  refreshPromise = /* 实际刷新逻辑 */;
  try { return await refreshPromise; }
  finally { isRefreshing = false; refreshPromise = null; }
}

十三、LangGraph 图结构变化

V2 的 LangGraph 图从 V1 的 10 节点扩展为 12 节点(新增 decompose 的显式路由),并增加了 MemorySaver 支持对话状态持久化。

START → classify
           ├─ comparative / 长 factual → decompose → retrieve
           └─ 其他 → rewrite
                        ├─ enableHyDE=true  → hyde → retrieve
                        └─ enableHyDE=false → retrieve
           retrieve → rerank → compress → generate → evaluate
                                                        ├─ pass/ambiguous → format → END
                                                        └─ fail + 重试未满 → rewrite(循环)

关键变化

  1. decompose 从 V1 的条件分支升级为显式节点,支持多跳检索
  2. MemorySaver 替代无状态调用,支持多轮对话上下文
  3. config 字段从前端请求体传入,覆盖默认 RAG 配置

十四、升级后的架构总览

┌─────────────────────────────────────────────────────────────┐
│                     前端 (5173)                              │
│  Vite + React 19 + TypeScript + TailwindCSS 4               │
│  Zustand 状态管理 · React Query · Lucide 图标                │
│  ┌────────┬────────┬────────┬────────┬──────┬──────┐        │
│  │ 登录   │ 对话   │ 文档   │ 评测   │ 监控 │ 审计 │        │
│  │ 注册   │ SSE流式│ 上传   │ A/B测  │ 实时 │ 日志 │        │
│  └────────┴────────┴────────┴────────┴──────┴──────┘        │
├─────────────────────────────────────────────────────────────┤
│                     后端 (3000)                              │
│  Node.js + Fastify 5 + TypeScript + LangGraph               │
│  ┌──────────┬──────────┬──────────┬──────────┐              │
│  │ JWT 认证 │ 审计日志 │ 评测管道 │ 指标采集 │              │
│  │ 角色控制 │ 异步写入 │ LLM打分  │ Prometheus│             │
│  └──────────┴──────────┴──────────┴──────────┘              │
│  ┌────────────────────────────────────────────┐              │
│  │ LangGraph 12 节点 RAG 管道                  │              │
│  │ classify→rewrite→hyde→retrieve→rerank→     │              │
│  │ compress→generate→evaluate→format          │              │
│  │ MemorySaver 对话持久化 · 自纠正循环         │              │
│  └────────────────────────────────────────────┘              │
├──────┬──────────┬──────────┬────────────────────────────────┤
│Milvus│PostgreSQL│ Redis    │ 外部 API                       │
│2.5.4 │ 16       │ 7        │ 智谱 AI                        │
│2048维│ 用户/审计│ 缓存/限流│ LLM: GLM-4.5-Air              │
│+BM25 │ 评测数据 │ 队列     │ Embedding: embedding-3 2048维  │
│      │          │          │ OCR: glm-ocr                   │
└──────┴──────────┴──────────┴────────────────────────────────┘

十五、升级成本与收益

15.1 新增依赖统计

  • 后端新增 7 个运行时依赖 + 2 个开发依赖
  • 前端新增 2 个运行时依赖
  • 数据库新增 3 张表(users、refresh_tokens、audit_logs)

15.2 收益对照

维度 V1 V2
安全性 无认证,裸 API JWT + 角色 + 审计 + 限流
可观测性 console.log Prometheus + 审计日志 + 用户反馈
评测能力 空壳面板 端到端评测 + A/B 测试 + 6 项指标
文档解析 5 种文本格式 5 种文本 + 图片/扫描件(GLM-OCR)
向量稳定性 LangChain 封装(不可控) 原生 fetch(可控)
模型成本 通义 API 智谱 API(价格相当)
多租户 user_id 隔离

十六、给正在升级 RAG 平台的团队的建议

  1. 先验证 Embedding 再写代码:切换向量模型前,先用 curl 或原生 fetch 测试 API 返回的向量是否正常,不要信任 SDK 封装
  2. 维度变更 = 全量重建:生产环境在切换 Embedding 模型前,评估重建集合和重新入库的成本
  3. 审计日志要防循环:审计中间件必须排除自身路由,否则会自我审计导致写入爆炸
  4. Token 刷新加锁:前端并发请求遇到 401 时,只发起一次刷新请求,其他请求排队等待
  5. 评测先于上线:V1 的教训是「没有评测就无法证明效果」,V2 补全了评测管道后,调参有了数据依据
  6. LLM 评估的 Prompt 要稳定:评测管道中 LLM 打分的 Prompt 格式要固定(如「仅输出 JSON:{"score": 0.0-1.0}」),避免解析失败

附录:升级后完整文件清单(新增部分)

packages/backend/src/
├── server/
│   ├── middleware/
│   │   ├── auth.ts              ← 新增:JWT 认证
│   │   ├── audit.ts             ← 新增:审计日志
│   │   └── metrics.ts           ← 新增:指标采集
│   └── routes/
│       ├── auth.ts              ← 新增:认证端点
│       ├── audit.ts             ← 新增:审计查询
│       └── metrics.ts           ← 新增:Prometheus 端点
├── services/
│   ├── auth.service.ts          ← 新增:用户管理
│   ├── audit.service.ts         ← 新增:审计服务
│   ├── evaluation.service.ts    ← 新增:评测管道
│   ├── feedback.service.ts      ← 新增:反馈服务
│   └── metrics.service.ts       ← 新增:指标服务
├── parsers/
│   ├── glm-ocr.ts               ← 新增:GLM-OCR 客户端
│   └── image.parser.ts          ← 新增:图片解析器
├── db/migrations/
│   ├── 002_auth.sql             ← 新增:认证表
│   └── 003_audit.sql            ← 新增:审计表
├── embeddings/
│   └── openai.ts                ← 重写:绕过 LangChain
└── llm/
    └── openai.ts                ← 增强:实例缓存

packages/frontend/src/
├── components/
│   ├── auth/
│   │   └── LoginPage.tsx        ← 新增:登录注册
│   └── admin/
│       ├── AuditLog.tsx         ← 新增:审计日志
│       └── MetricsDashboard.tsx ← 新增:监控面板
└── store/
    └── authStore.ts             ← 新增:认证状态

freesky51_weixin

posted on 2026-06-02 07:23  天涯轩  阅读(43)  评论(0)    收藏  举报

导航