# 阶段四记录：RAG 和外部服务接入骨架

日期：2026-07-06

## 本次目标

把阶段四从纯 mock 推进到可替换的外部服务接入骨架：飞书检索、模型调用、外部异常、失败日志和配置开关都要有明确边界。

## 已完成

- 新增统一外部服务异常 `ExternalServiceError`。
- 拆出 `FeishuKnowledgeService`：
  - 默认 `FEISHU_MOCK_ENABLED=true`，继续使用本地 mock 文档。
  - 关闭 mock 后通过 `FEISHU_SEARCH_URL` 调用远端检索适配服务。
  - 支持 `FEISHU_TIMEOUT_SECONDS` 和 `FEISHU_RETRY_COUNT`。
  - 远端返回统一解析为 `RetrievedChunk`。
- 增强 `ModelClientService`：
  - 默认 `MOCK_MODEL_ENABLED=true`，继续使用 mock 模型。
  - 关闭 mock 且后台存在启用模型时，按 OpenAI 兼容 `chat/completions` 非流式格式调用。
  - 支持读取模型表中的 `api_url`、`api_key`、`model_name`、`temperature`、`max_token` 和 `timeout_second`。
- 增强 AI 请求日志：
  - 成功时记录完整请求日志。
  - 飞书或模型异常时记录失败日志。
- 增强 `/chat/completions`：
  - 外部服务异常会返回明确错误。
  - 失败时不消耗用户每日额度。

## 当前配置

```env
MOCK_RAG_ENABLED=true
MOCK_MODEL_ENABLED=true
FEISHU_MOCK_ENABLED=true
FEISHU_SEARCH_URL=
FEISHU_TIMEOUT_SECONDS=20
FEISHU_RETRY_COUNT=2
```

## 当前边界

- 真实飞书原生 API 尚未直接接入，因为还需要确认账号权限、SpaceID/NodeID 检索方式和返回结构。
- 当前预留的是 `FEISHU_SEARCH_URL` 适配服务入口，后续可以选择直接接飞书原生 API，也可以由单独适配服务封装飞书复杂鉴权。
- 真实模型当前先支持 OpenAI 兼容非流式响应；用户端仍通过后端 SSE 分块输出。
- 模型原生流式透传和后端真实停止生成需要在模型供应商和 SDK/协议确认后继续补。

## 阶段四判断

阶段四的工程边界已经建立，可以支持后续真实接入：

1. 开放知识库过滤在检索前执行。
2. 飞书检索 provider 可替换。
3. Prompt 组装已独立。
4. 模型 provider 可替换。
5. 成功和失败 AI 请求日志都有记录路径。
6. 无命中兜底规则已生效。
