# 项目修改日志 (Changelog)

本文档记录了项目的主要功能修改和代码变更。

## 修改日期
2025-11-24

---

## 一、模型服务器 (Models Server) 修改

### 1.1 文件：`scripts/ai_agent/models/models_server.py`

#### 修改内容：

**1. 配置解析改进**
- **位置**：`get_model_server()` 函数
- **修改**：
  - 修正配置文件路径，使用 `project_root` 变量
  - 添加配置文件读取错误检查（`read_json_file()` 返回 `None` 的情况）
  - 支持 `models_server` 配置为列表或字典两种格式
  - 修复 `global _process_instance` 声明位置（必须在函数开始处）

**2. 消息构建逻辑修复**
- **位置**：`_build_message()` 方法
- **修改**：
  - 修复纯文本和多模态消息格式不一致的问题
  - 纯文本推理：`system_prompt` 和 `user_prompt` 的 `content` 字段为字符串
  - 多模态推理：`system_prompt` 和 `user_prompt` 的 `content` 字段为列表（包含文本和图像对象）
  - 解决了 `TypeError: can only concatenate str (not "list") to str` 错误

**3. JSON Schema 支持**
- **位置**：`text_inference()`, `multimodal_inference()`, `model_inference()` 方法
- **修改**：
  - 添加 `response_format` 参数支持，用于约束模型输出格式
  - 当 `request.json_schema` 存在时，构建 `response_format` 对象传递给 `create_chat_completion`
  - 格式：`{"type": "json_object", "schema": request.json_schema}`

**4. 错误处理增强**
- **位置**：`text_inference()` 方法
- **修改**：
  - 添加 `messages` 为 `None` 的检查
  - 显式设置 `image_data=None` 用于纯文本请求
  - 改进错误日志，使用 `exc_info=True` 记录完整堆栈信息

**5. GPU 日志增强**
- **位置**：`init_vlm_llamacpp()` 方法
- **修改**：
  - 当 `n_gpu_layers > 0` 时，设置 `verbose=True` 以输出 GPU 使用信息
  - 添加 GPU 层数日志输出

**6. 主函数启用**
- **位置**：`main()` 函数
- **修改**：
  - 取消注释 `uvicorn.run()` 调用，使模型服务器可以独立启动

---

### 1.2 文件：`scripts/ai_agent/models/model_definition.py`

#### 修改内容：

**JSON Schema 字段添加**
- **位置**：`TextInferenceRequest` 和 `InferenceRequest` 类
- **修改**：
  - 添加 `json_schema: Optional[Dict[str, Any]] = None` 字段
  - 用于在推理请求中传递 JSON Schema，约束模型输出格式

---

### 1.3 文件：`scripts/ai_agent/models/models_client.py`

#### 修改内容：

**Pydantic 兼容性改进**
- **位置**：`text_inference()` 和 `multimodal_inference()` 方法
- **修改**：
  - 添加 Pydantic v1/v2 兼容的 JSON 序列化逻辑
  - 优先使用 `model_dump_json()` (Pydantic v2)
  - 降级使用 `json()` (Pydantic v1)
  - 最后使用 `dict()`/`model_dump()` + `json.dumps()` 作为兜底方案
  - 解决了 `Object of type TextInferenceRequest is not JSON serializable` 错误

**服务器等待逻辑改进**
- **位置**：`wait_for_server()` 方法
- **修改**：
  - 接受 "loading" 状态作为有效状态
  - 增强连接失败时的错误消息

---

## 二、后端服务 (Backend Service) 修改

### 2.1 文件：`scripts/ai_agent/groundcontrol/backend_service/src/main.py`

#### 修改内容：

**子进程输出处理改进**
- **位置**：`start_model_server()` 函数
- **修改**：
  - 使用线程实时输出模型服务器的 stdout 和 stderr
  - 移除 `bufsize=1` 参数（二进制模式下不支持行缓冲）
  - 解决了 `RuntimeWarning: line buffering (buffering=1) isn't supported in binary mode` 警告

---

### 2.2 文件：`scripts/ai_agent/groundcontrol/backend_service/src/py_tree_generator.py`

#### 修改内容：

**1. RAG 初始化改进**
- **位置**：`__init__()` 方法
- **修改**：
  - 从 `rag_config.json` 读取 RAG 配置
  - 计算 `ai_agent_root` 路径（相对于 `base_dir` 向上三级）
  - 使用配置中的 `vectorstore_persist_directory` 和 `collection_name`
  - 添加向量数据库加载状态日志

**2. JSON Schema 支持**
- **位置**：`generate()` 方法
- **修改**：
  - 分类请求：传递 `classifier_schema` 约束输出格式
  - 生成请求：根据模式（simple/complex）传递对应的 schema（`self.schema` 或 `self.simple_schema`）
  - 确保模型输出符合预期的 JSON 结构

**3. RAG 检索调用更新**
- **位置**：`_retrieve_context()` 方法
- **修改**：
  - 将 `score_threshold=0.6` 改为 `score_threshold=None`
  - 使用自适应阈值，自动适应 L2 距离（ChromaDB 默认使用 L2 距离）

**4. 正则表达式修复**
- **位置**：`_parse_allowed_nodes_from_prompt()` 函数
- **修改**：
  - 修复正则表达式，正确匹配 "可用节点定义" 部分
  - 解决了 `ERROR - 在系统提示词中未找到'可用节点定义'部分的JSON代码块` 错误

---

## 三、RAG 系统 (Retrieval Augmented Generation) 修改

### 3.1 文件：`scripts/ai_agent/tools/memory_mag/rag/rag.py`

#### 修改内容：

**1. 向量数据库加载改进**
- **位置**：`load_vector_database()` 函数
- **修改**：
  - 添加集合存在性检查（使用 ChromaDB 客户端）
  - 列出所有可用集合及其文档数量
  - 检查目标集合是否有数据
  - 自动检测并提示有数据的集合
  - 即使集合为空也返回数据库对象（允许后续添加数据）
  - 添加详细的日志输出，包括集合信息和文档数量

**2. 检索逻辑优化**
- **位置**：`retrieve_relevant_info()` 函数
- **修改**：
  - 将 `score_threshold` 默认值改为 `None`，支持自适应阈值
  - 自适应阈值逻辑：
    - 取前 k 个结果中的最高分数
    - 乘以 1.5 作为阈值（确保包含所有前 k 个结果）
    - 自动适应 L2 距离（分数范围通常在 10000-20000）
  - 修复日志格式化错误（`score_threshold` 可能为 `None`）
  - 添加相似度分数范围日志输出
  - 解决了阈值过小（0.6）导致所有结果被过滤的问题

**3. 嵌入模型配置容错**
- **位置**：`set_embeddings()` 函数
- **修改**：
  - 使用 `.get()` 方法访问 `model_config` 参数，提供默认值
  - 支持的参数：`n_ctx`, `n_threads`, `n_gpu_layers`, `n_seq_max`, `n_threads_batch`, `flash_attn`, `verbose`
  - 解决了 `KeyError: 'n_threads_batch'` 等配置缺失错误

---

### 3.2 文件：`scripts/ai_agent/config/rag_config.json`

#### 修改内容：

**配置更新**
- **修改项**：
  1. `vectorstore_persist_directory`：更新为 `/home/huangfukk/AI_Agent/scripts/ai_agent/memory/knowledge_base/map/vector_store/osm_map1`
  2. `embedding_model_path`：更新为 `/home/huangfukk/models/gguf/Qwen/Qwen3-Embedding-4B/Qwen3-Embedding-4B-Q4_K_M.gguf`
  3. `collection_name`：从 `"osm_map_docs"` 改为 `"drone_docs"`（使用有数据的集合）
  4. `model_config_llamacpp`：添加 `n_threads_batch: 4` 字段

---

### 3.3 文件：`scripts/ai_agent/config/model_config.json`

#### 修改内容：

**模型配置更新**
- **修改项**：
  1. `verbose`：从 `0` 改为 `1`（启用详细日志）
  2. `n_gpu_layers`：设置为 `40`（启用 GPU 加速）

---

## 四、主要问题修复总结

### 4.1 已修复的错误

1. **模型服务器启动超时**
   - **原因**：`main()` 函数被注释，服务器无法启动
   - **修复**：取消注释 `uvicorn.run()` 调用

2. **配置解析 KeyError**
   - **原因**：`models_server` 配置格式不一致（列表 vs 字典）
   - **修复**：添加格式判断，支持两种格式

3. **消息格式类型错误**
   - **原因**：纯文本和多模态消息格式混用
   - **修复**：区分纯文本（字符串）和多模态（列表）格式

4. **JSON 序列化错误**
   - **原因**：Pydantic 模型直接序列化失败
   - **修复**：添加 Pydantic v1/v2 兼容的序列化逻辑

5. **RAG 检索返回空结果**
   - **原因**：
     - 集合名称不匹配（`osm_map_docs` 为空，`drone_docs` 有数据）
     - 相似度阈值过小（0.6），而 L2 距离分数通常在 10000+ 范围
   - **修复**：
     - 更新集合名称为 `drone_docs`
     - 实现自适应阈值机制

6. **配置缺失 KeyError**
   - **原因**：`rag_config.json` 缺少 `n_threads_batch` 字段
   - **修复**：添加字段，并在代码中使用 `.get()` 提供默认值

---

## 五、新增功能

### 5.1 JSON Schema 约束输出

- **功能描述**：支持在推理请求中传递 JSON Schema，约束模型输出格式
- **应用场景**：
  - 分类任务：确保输出符合 `{"mode": "simple"|"complex"}` 格式
  - 生成任务：确保输出符合 Pytree JSON 结构
- **实现位置**：
  - `model_definition.py`：添加 `json_schema` 字段
  - `models_server.py`：构建 `response_format` 参数
  - `py_tree_generator.py`：传递动态生成的 schema

### 5.2 自适应相似度阈值

- **功能描述**：根据检索结果自动调整相似度阈值
- **优势**：
  - 自动适应不同的距离度量（L2、余弦距离等）
  - 无需手动调整阈值参数
  - 确保返回前 k 个最相关的结果
- **实现位置**：`rag.py` 的 `retrieve_relevant_info()` 函数

### 5.3 向量数据库诊断功能

- **功能描述**：加载向量数据库时自动检查集合状态
- **功能**：
  - 列出所有可用集合
  - 显示每个集合的文档数量
  - 提示有数据的集合
  - 诊断集合不存在或为空的情况
- **实现位置**：`rag.py` 的 `load_vector_database()` 函数

---

## 六、配置变更

### 6.1 必须更新的配置

1. **`rag_config.json`**
   - 更新 `vectorstore_persist_directory` 路径
   - 更新 `embedding_model_path` 路径
   - 更新 `collection_name` 为有数据的集合
   - 确保 `model_config_llamacpp` 包含所有必需字段

2. **`model_config.json`**
   - 根据需求调整 `n_gpu_layers`（GPU 加速层数）
   - 根据需求调整 `verbose`（日志详细程度）

---

## 七、测试建议

### 7.1 功能测试

1. **模型服务器启动测试**
   ```bash
   cd scripts/ai_agent/models
   python models_server.py
   ```

2. **RAG 检索测试**
   ```python
   from tools.memory_mag.rag.rag import set_embeddings, load_vector_database, retrieve_relevant_info
   # 测试检索功能
   ```

3. **JSON Schema 约束测试**
   - 发送分类请求，验证输出格式
   - 发送生成请求，验证 Pytree JSON 结构

### 7.2 集成测试

1. **端到端测试**
   - 启动后端服务
   - 发送 "起飞，飞到匡亚明学院" 请求
   - 验证 RAG 检索是否返回地点信息
   - 验证生成的 Pytree 是否包含正确的地点坐标

---

## 八、注意事项

1. **向量数据库集合**
   - 确保使用有数据的集合（当前为 `drone_docs`）
   - 如果更换集合，需要更新 `rag_config.json` 中的 `collection_name`

2. **嵌入模型路径**
   - 确保嵌入模型路径正确
   - 嵌入模型必须与向量数据库创建时使用的模型一致

3. **GPU 配置**
   - 根据硬件配置调整 `n_gpu_layers`
   - 如果使用 CPU，设置 `n_gpu_layers=0`

4. **日志级别**
   - 生产环境建议设置 `verbose=0`
   - 调试时可以使用 `verbose=1` 查看详细信息

---

## 九、后续优化建议

1. **性能优化**
   - 考虑缓存嵌入模型实例
   - 优化向量数据库查询性能

2. **错误处理**
   - 添加更细粒度的错误分类
   - 提供更友好的错误消息

3. **配置管理**
   - 考虑使用环境变量覆盖配置
   - 添加配置验证逻辑

4. **文档完善**
   - 添加 API 文档
   - 添加部署指南

---

## 十、启动脚本

### 10.1 后端服务启动脚本

**文件**：`scripts/ai_agent/groundcontrol/backend_service/start_backend.sh`

**功能**：
- 提供便捷的后端服务启动方式
- 自动设置工作目录和 Python 路径
- 启动 FastAPI 后端服务，监听 `0.0.0.0:8001`

**使用方法**：
```bash
cd scripts/ai_agent/groundcontrol/backend_service
./start_backend.sh
```

**脚本内容**：
- 自动切换到脚本所在目录
- 设置 Python 路径
- 使用 uvicorn 启动 FastAPI 应用：`python -m uvicorn src.main:app --host 0.0.0.0 --port 8001`

---

**文档版本**：1.1  
**最后更新**：2025-11-24

