# df-ai + df-ai-core 代码走查报告

> 走查日期: 2026-08-02
> 范围: crates/df-ai (26 files, ~500KB) + crates/df-ai-core (4 files, ~55KB)

---

## 文件规模统计

| 文件 | 行数 | 类型 |
|---|---|---|
| openai_compat.rs | 58,524 | Provider HTTP 实现 |
| anthropic_compat.rs | 54,492 | Provider HTTP 实现 |
| context/mod.rs | 32,028 | 上下文管理器 |
| context/sanitize.rs | 51,416 | 畸形配对自愈 |
| coordinator.rs | 65,321 | 多 Agent 协调 |
| intent.rs | 57,390 | 意图识别 |
| context_helpers.rs | 63,660 | 上下文辅助 |
| planner.rs | 38,451 | 规划器 |
| plan_hint.rs | 26,621 | 规划提示 |
| df-ai-core/provider.rs | 24,849 | Provider trait + 类型 impl |
| df-ai-core/model.rs | 18,390 | 模型能力数据模型 |
| df-ai-core/types.rs | 12,835 | 核心类型定义 |

---

## 问题汇总

| # | 等级 | 文件 | 类型 | 简述 |
|---|---|---|---|---|
| 1 | 🔴 P0 | openai_compat(58KB) + anthropic_compat(54KB) | smell | 两个 provider 文件超 50KB，大量代码重复（流式解析/工具调用/错误处理） |
| 2 | 🔴 P0 | coordinator(65KB) | smell | 单文件 65KB，DevFlow 最大文件，职责过宽 |
| 3 | 🔴 P0 | context_helpers(63KB) | smell | 63KB 纯辅助函数，应拆分 |
| 4 | 🟡 P1 | intent(57KB) | smell | 意图识别 57KB，正则/模式匹配过多 |
| 5 | 🟡 P1 | context/sanitize(51KB) | smell | 畸形配对自愈逻辑 51KB，复杂度过高 |
| 6 | 🟡 P1 | router.rs | risk | cost_tier/intelligence 路由已解耦，但枚举保留，无实际数据源接入 |
| 7 | 🟡 P1 | retry.rs | risk | `MAX_COMPLETE_ATTEMPTS=3` 硬编码，不支持 per-provider 配置 |
| 8 | 🟢 P2 | types.rs | smell | `ChatMessage` 18 个字段，构造时 `..` 语法极易遗漏新字段 |
| 9 | 🟢 P2 | model.rs | smell | `ModelConfig` 11 个字段，`with_defaults` 默认值集中管理但调用方仍可改 |
| 10 | 🟢 P2 | sse_parser.rs | smell | SSE 解析器自实现替代 eventsource-stream，但 BUF_MAX 1MB 无保护 |

---

## 🔴 P0 问题详述

### #1 openai_compat + anthropic_compat 大量重复

**问题**: 两个文件合计 113KB，逐行阅读发现大量重复代码：
- `convert_request` 消息映射（OpenAI/Anthropic 格式互转）
- 流式解析逻辑（chunk 事件 → StreamChunk）
- 工具调用解析（tool_calls 提取）
- 错误处理（HTTP 状态码 → 错误分类）
- usage 累加

**具体重复区域**:
- 工具调用解析: `parse_tool_calls` 在 `openai_helpers.rs` 而 `anthropic_helpers.rs` 有等效实现
- 流式 chunk 解析: 两套 `parse_stream_line` / `parse_anthropic_event`
- 请求构建: `build_request_body` 两套

**建议**: 抽共享 `provider_helpers.rs`，通用逻辑（工具解析/usage 合并/错误分类）放 df-ai-core（零 HTTP），HTTP 特有逻辑放 df-ai 共享模块。

### #2 coordinator.rs 65KB

**问题**: 单文件 65KB，是 DevFlow 单体最大文件。职责包括：
- 多 agent 任务分发
- 状态管理
- 内存上下文
- Scheduling

**建议**: 拆为 `coordinator/mod.rs` + `coordinator/tasks.rs` + `coordinator/scheduler.rs` + `coordinator/state.rs`。

### #3 context_helpers.rs 63KB

**问题**: 63KB 纯辅助函数，包括 `TokenEstimator` / `ContextConfig` / `MessageGroup` / `EvictionUnit` / `classify_group` / `PROTECT_COUNT` 等。

**建议**: 拆为 `context_helpers/token.rs` / `context_helpers/config.rs` / `context_helpers/classify.rs`。

---

## 🟡 P1 问题

### #6 router cost_tier/intelligence 悬空

**文件**: `router.rs`
**风险**: 路由已解耦但枚举保留，无实际数据源接入。`cost_tier` 和 `intelligence` 字段在 `ModelConfig` 中存在但永远不参与路由判断。

**建议**: 添加注释说明恢复计划，或移除但保留 `ModelConfig` 字段供前端展示。

### #7 retry.rs 硬编码

**文件**: `retry.rs:26`
**现状**: `MAX_COMPLETE_ATTEMPTS=3` 硬编码，不支持 `AiProviderRecord.config` 覆盖。

**建议**: 暴露 `with_max_attempts(n)` 或从 config 读取。

---

## 正面评价

1. **df-ai-core 分层正确**: trait+类型拆到轻量 crate，df-ideas 等不引入 HTTP 重依赖
2. **retry.rs 设计优秀**: 指数退避 + jitter + 可重试/不可重试分类 + 预算上限，覆盖全面
3. **sse_parser 容错**: 宽松 UTF-8 处理，多字节续接，BUF_MAX 防御
4. **ChatMessage id 生成**: 单调递增 + 全局唯一，AtomicU64 双保险
5. **tool_call_id_or_fallback**: 全局计数器防跨轮重复，实证修复
6. **ModelConfig 向后兼容**: deserialize_model_configs 兼容老格式字符串数组
7. **router 过滤链清晰**: enabled → 模态 → 能力 → 窗口 → weight，5 步清晰