migration: preserve mentor and llm streaming slice
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
# 切片 07:问师、模型 Skill 与 LLM 流式链路
|
||||
|
||||
> 基线:`4bab921`(切片 06)
|
||||
> 回档标签:`xiaobai-preservation-slice-07-20260731`
|
||||
> 结论:源码、API、数据库、Skill 资产、真实页面和全量回归通过;最终视觉仍等待全站人工验收
|
||||
|
||||
## 1. 原实现归位
|
||||
|
||||
本切片只移动原版问师、Skill 注册、模型访问与流式协议,没有从`next/`取用代码,也没有改写
|
||||
提示词、数据侧重、模型排序、权限、计次、回退或流式去重逻辑。
|
||||
|
||||
| 原位置 | 新的唯一实现位置 | 兼容方式 |
|
||||
|---|---|---|
|
||||
| `app/mentor_agent.py` | `app/backend/features/mentor/agent.py` | 根级模块指向同一模块对象 |
|
||||
| `DashboardService`问师方法 | `app/backend/features/mentor/service.py` | `MentorServiceMixin` |
|
||||
| 问师消息和偏好持久化 | `app/backend/features/mentor/repository.py` | `MentorRepositoryMixin` |
|
||||
| 问师流式HTTP方法 | `app/backend/features/mentor/http.py` | `MentorHttpMixin` |
|
||||
| `app/llm_stream.py` | `app/backend/llm/stream.py` | 根级模块指向同一模块对象 |
|
||||
| `DashboardService`模型访问方法 | `app/backend/llm/service.py` | `LLMServiceMixin` |
|
||||
| LLM调用审计持久化 | `app/backend/llm/repository.py` | `LLMAuditRepositoryMixin` |
|
||||
| 旧个人模型HTTP兼容入口 | `app/backend/llm/http.py` | `LLMHttpMixin` |
|
||||
|
||||
模型池的增删、主辅模型选择及会员每日额度仍由系统管理负责;`backend/llm`只负责解析当前可用模型、
|
||||
鉴权、计次、首段前回退、流式传输和调用审计,避免复制第二套系统设置逻辑。
|
||||
|
||||
## 2. 源码与 Skill 等价
|
||||
|
||||
- `mentor_agent.py`和`llm_stream.py`与原版文件SHA-256一致,根级兼容模块与正式模块为同一模块对象。
|
||||
- 8个问师服务方法、5个问师Repository方法、2个LLM审计Repository方法与原版无位置信息AST一致。
|
||||
- 21个LLM服务方法中19个与原版AST一致;`_platform_usage_today`及按用户查询的辅助方法保留切片01
|
||||
已验证的用户边界适配,使会员管理可在不切换请求上下文的情况下显示每位用户当日用量。
|
||||
- 问师流式和旧模型HTTP方法仅把原全局`SERVICE`改为Mixin的`self.application_service`,响应状态、
|
||||
Content-Type、NDJSON事件、异常和断连处理不变。
|
||||
- 公开`游资skills`共190个文件,原版与迁移版逐路径、逐SHA-256比较,差异为0。
|
||||
- 私有“小白”Skill仍位于Git忽略的`data/private-mentor-skills`,未复制到公开目录或证据文件。
|
||||
|
||||
## 3. API与数据库差分
|
||||
|
||||
- 原版`8786`和迁移版`8787`使用同一数据库的独立副本。
|
||||
- `/api/mentors/setup`和按用户、模型、日期读取消息的API状态码及业务JSON完全一致。
|
||||
- 两版均为62个schema对象;`mentor_messages` 28行、`mentor_preferences` 45行、`llm_usage` 72行、
|
||||
`system_settings` 1行、`users` 3行,均逐行一致。
|
||||
- 接口证据见`api-requests.json`、`api-diff.json`,数据库证据见`database-diff.json`。
|
||||
- 差分只在系统临时目录的数据库副本上运行,登录会话和后台任务运行数据未纳入业务表比较;临时副本
|
||||
已在验收后删除,正式数据库未写入测试消息或LLM调用记录。
|
||||
|
||||
## 4. 真实浏览器检查
|
||||
|
||||
- 迁移版真实服务载入24个思维模型,管理员可见私有“小白”,公开模型的A/B/C标签、简介和置顶按钮正常。
|
||||
- A级筛选显示13个模型;全部、A级、B级、C级、搜索、整理、清空对话、建议问题、输入框和发送按钮均存在。
|
||||
- 页面宽度与1280像素视口一致,无横向溢出;浏览器控制台无错误。
|
||||
- 浏览器不调用真实外部模型,防止模型容量和网络波动污染迁移结论;流式首段回退、输出后禁止切模、
|
||||
完整快照去重和空响应处理由`test_llm_gateway`、`test_mentor_stream`与`test_llm_stream`覆盖。
|
||||
- 截图SHA-256:
|
||||
- `mentor-all.jpg`:`9cda4d6896da6932b8e9db014eed4882359287d6999e2181af7d945ea6272bd9`
|
||||
- `mentor-a-filter.jpg`:`5dca958d5edf7ab11767474a3c4405d4cb96029f7a1efb35fa8155c61c863984`
|
||||
|
||||
## 5. 自动验证与保留边界
|
||||
|
||||
| 验证 | 结果 |
|
||||
|---|---:|
|
||||
| 原版`python -m unittest discover -s tests -q` | 231项通过 |
|
||||
| 迁移版`python -m unittest discover -s tests -q` | 273项通过 |
|
||||
| `python -m unittest tests.test_preservation_slice_mentor_llm -q` | 8项通过 |
|
||||
| `npx.cmd playwright test --reporter=dot` | 45项通过 |
|
||||
| `git diff --check` | 通过 |
|
||||
|
||||
- `assistant_agent.py`属于切片09复盘助手,本切片不提前移动。
|
||||
- 问天的模型调用属于切片08,本切片只复用统一LLM网关,不移动问天业务。
|
||||
- 前端DOM、页面JS、CSS和移动端行为未改动,统一归档延至切片10。
|
||||
- 没有删除待定代码、没有修改正式数据库、没有切换Docker/NAS。
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"all_equal": true,
|
||||
"endpoints": [
|
||||
{
|
||||
"name": "mentor setup and public skill catalog",
|
||||
"method": "GET",
|
||||
"endpoint": "/api/mentors/setup?trade_date=2026-07-30",
|
||||
"original_status": 200,
|
||||
"migrated_status": 200,
|
||||
"original_sha256": "3a5bd83b58e849757664bbfe8cf54e704bc9a7682333deb8297212c488aa3ddc",
|
||||
"migrated_sha256": "3a5bd83b58e849757664bbfe8cf54e704bc9a7682333deb8297212c488aa3ddc",
|
||||
"equal": true,
|
||||
"first_difference": null
|
||||
},
|
||||
{
|
||||
"name": "mentor messages scoped by user mentor and date",
|
||||
"method": "GET",
|
||||
"endpoint": "/api/mentors/messages?mentor_id=kobe92-perspective&trade_date=20260730",
|
||||
"original_status": 200,
|
||||
"migrated_status": 200,
|
||||
"original_sha256": "eef46741adfc3a9f76294d3b78f37a45f113092ac9d44ee77c7a038a88ff09a1",
|
||||
"migrated_sha256": "eef46741adfc3a9f76294d3b78f37a45f113092ac9d44ee77c7a038a88ff09a1",
|
||||
"equal": true,
|
||||
"first_difference": null
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"name": "mentor setup and public skill catalog",
|
||||
"method": "GET",
|
||||
"endpoint": "/api/mentors/setup?trade_date=2026-07-30",
|
||||
"payload": null
|
||||
},
|
||||
{
|
||||
"name": "mentor messages scoped by user mentor and date",
|
||||
"method": "GET",
|
||||
"endpoint": "/api/mentors/messages?mentor_id=kobe92-perspective&trade_date=20260730",
|
||||
"payload": null
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"all_equal": true,
|
||||
"schema": {
|
||||
"object_count": 62,
|
||||
"original_sha256": "60a4e044f0ddb6502e44b45f65bedc1a0a31d4bd596f386d4ccfe153a6c8ddd1",
|
||||
"migrated_sha256": "60a4e044f0ddb6502e44b45f65bedc1a0a31d4bd596f386d4ccfe153a6c8ddd1",
|
||||
"equal": true
|
||||
},
|
||||
"tables": [
|
||||
{
|
||||
"table": "mentor_messages",
|
||||
"original_count": 28,
|
||||
"migrated_count": 28,
|
||||
"original_sha256": "b906b776d575ff6fe459b2aa0e8b396267feed36d3d85f7edd7947b284482aeb",
|
||||
"migrated_sha256": "b906b776d575ff6fe459b2aa0e8b396267feed36d3d85f7edd7947b284482aeb",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"table": "mentor_preferences",
|
||||
"original_count": 45,
|
||||
"migrated_count": 45,
|
||||
"original_sha256": "c19c7d05e6745e4f1787d1eed5f39d7e555ec24f8e490b585c19158edc2505ec",
|
||||
"migrated_sha256": "c19c7d05e6745e4f1787d1eed5f39d7e555ec24f8e490b585c19158edc2505ec",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"table": "llm_usage",
|
||||
"original_count": 72,
|
||||
"migrated_count": 72,
|
||||
"original_sha256": "03a070316a125cef904bbfb2bb06b06e792242d5713142e70354402c741393c3",
|
||||
"migrated_sha256": "03a070316a125cef904bbfb2bb06b06e792242d5713142e70354402c741393c3",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"table": "system_settings",
|
||||
"original_count": 1,
|
||||
"migrated_count": 1,
|
||||
"original_sha256": "86d333a5c7feaf7111cd79b2db29513326a9b0d3781607f78bf633579e2ca8e9",
|
||||
"migrated_sha256": "86d333a5c7feaf7111cd79b2db29513326a9b0d3781607f78bf633579e2ca8e9",
|
||||
"equal": true
|
||||
},
|
||||
{
|
||||
"table": "users",
|
||||
"original_count": 3,
|
||||
"migrated_count": 3,
|
||||
"original_sha256": "4a0f135bef8ebae454693d3f40e1157d84d814d18d849f33e2e760ed1d8a7f89",
|
||||
"migrated_sha256": "4a0f135bef8ebae454693d3f40e1157d84d814d18d849f33e2e760ed1d8a7f89",
|
||||
"equal": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 83 KiB |
Reference in New Issue
Block a user