Generated plan.md, research.md, data-model.md, contracts/api.md, quickstart.md, and CLAUDE.md agent context via /speckit-plan.
168 lines
5.3 KiB
Markdown
168 lines
5.3 KiB
Markdown
# Data Model: AI 服务
|
||
|
||
**Branch**: `001-ai-service-requirements` | **Date**: 2026-04-10
|
||
|
||
---
|
||
|
||
## 实体定义
|
||
|
||
### TripleItem(文本三元组)
|
||
|
||
从文档中提取的一条知识关系。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| subject | string | 非空 | 主语实体 |
|
||
| predicate | string | 非空 | 谓语/关系 |
|
||
| object | string | 非空 | 宾语实体 |
|
||
| source_snippet | string | 非空 | 原文中的证据片段(直接引用) |
|
||
| source_offset.start | int | ≥0 | 证据片段在全文中的起始字符偏移 |
|
||
| source_offset.end | int | >start | 证据片段在全文中的结束字符偏移 |
|
||
|
||
**状态转换**: 无(只读输出)
|
||
|
||
---
|
||
|
||
### QuadrupleItem(图像四元组)
|
||
|
||
从图像中提取的一条知识关系,带图像位置信息。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| subject | string | 非空 | 主体实体 |
|
||
| predicate | string | 非空 | 关系/属性 |
|
||
| object | string | 非空 | 客体实体 |
|
||
| qualifier | string | 可为空 | 修饰信息(时间、条件、场景) |
|
||
| bbox.x | int | ≥0 | 边界框左上角 x 像素坐标 |
|
||
| bbox.y | int | ≥0 | 边界框左上角 y 像素坐标 |
|
||
| bbox.w | int | >0 | 边界框宽度(像素) |
|
||
| bbox.h | int | >0 | 边界框高度(像素) |
|
||
| cropped_image_path | string | 非空 | 裁剪图在 RustFS 中的存储路径 |
|
||
|
||
**派生规则**: `cropped_image_path = "crops/{task_id}/{item_index}.jpg"`,由 image_service 自动生成并上传
|
||
|
||
---
|
||
|
||
### QAPair(文本问答对)
|
||
|
||
由文本三元组生成的训练候选问答对。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| question | string | 非空 | 问题文本 |
|
||
| answer | string | 非空 | 答案文本 |
|
||
|
||
---
|
||
|
||
### ImageQAPair(图像问答对)
|
||
|
||
由图像四元组生成的训练候选图文问答对。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| question | string | 非空 | 问题文本 |
|
||
| answer | string | 非空 | 答案文本 |
|
||
| image_path | string | 非空 | 对应裁剪图的存储路径(来源于 QuadrupleItem.cropped_image_path) |
|
||
|
||
---
|
||
|
||
### FrameInfo(视频帧信息)
|
||
|
||
视频帧提取任务中单帧的元数据。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| frame_index | int | ≥0 | 帧在视频中的原始帧序号 |
|
||
| time_sec | float | ≥0.0 | 帧对应的时间点(秒) |
|
||
| frame_path | string | 非空 | 帧图在 RustFS 中的存储路径 |
|
||
|
||
**派生规则**: `frame_path = "frames/{source_id}/{upload_index}.jpg"`
|
||
|
||
---
|
||
|
||
### VideoJobCallback(视频任务回调)
|
||
|
||
异步视频任务完成后发送给 Java 后端的通知载荷。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| job_id | int | 非空 | 由 Java 后端分配的任务 ID |
|
||
| status | string | SUCCESS \| FAILED | 任务最终状态 |
|
||
| frames | FrameInfo[] \| null | 仅帧提取时非 null | 提取的帧列表(可为空列表) |
|
||
| output_path | string \| null | 仅视频转文本时非 null | 输出文字描述的存储路径 |
|
||
| error_message | string \| null | 仅 FAILED 时非 null | 错误描述 |
|
||
|
||
---
|
||
|
||
### FinetuneJob(微调任务)
|
||
|
||
微调任务的状态快照。
|
||
|
||
| 字段 | 类型 | 约束 | 说明 |
|
||
|------|------|------|------|
|
||
| job_id | string | 非空 | 由 ZhipuAI 平台分配的任务 ID(如 "glm-ft-xxxxxx") |
|
||
| status | string | RUNNING \| SUCCESS \| FAILED | 当前状态 |
|
||
| progress | int \| null | 0-100 \| null | 完成百分比(ZhipuAI 支持时) |
|
||
| error_message | string \| null | 仅 FAILED 时非 null | 错误描述 |
|
||
|
||
**状态映射**:
|
||
```
|
||
ZhipuAI "running" → RUNNING
|
||
ZhipuAI "succeeded" → SUCCESS
|
||
ZhipuAI "failed" → FAILED
|
||
其他 → RUNNING(保守处理)
|
||
```
|
||
|
||
---
|
||
|
||
## RustFS 存储路径规范
|
||
|
||
| 资源类型 | 存储桶 | 路径格式 |
|
||
|----------|--------|----------|
|
||
| 上传文本文件 | `source-data` | `text/{年月}/{source_id}.txt` |
|
||
| 上传图片 | `source-data` | `image/{年月}/{source_id}.jpg` |
|
||
| 上传视频 | `source-data` | `video/{年月}/{source_id}.mp4` |
|
||
| 视频帧图 | `source-data` | `frames/{source_id}/{upload_index}.jpg` |
|
||
| 视频转译文本 | `source-data` | `video-text/{source_id}/{timestamp}.txt` |
|
||
| 图像/帧 bbox 裁剪图 | `source-data` | `crops/{task_id}/{item_index}.jpg` |
|
||
| 导出 JSONL 文件 | `finetune-export` | `export/{batchUuid}.jsonl` |
|
||
|
||
---
|
||
|
||
## 配置模型
|
||
|
||
### config.yaml(非敏感,提交 git)
|
||
|
||
```yaml
|
||
server:
|
||
port: 8000
|
||
log_level: INFO
|
||
|
||
storage:
|
||
buckets:
|
||
source_data: "source-data"
|
||
finetune_export: "finetune-export"
|
||
|
||
backend: {} # callback_url 由 .env 注入
|
||
|
||
video:
|
||
frame_sample_count: 8 # 视频转文本时均匀采样帧数
|
||
max_file_size_mb: 200 # 视频大小上限(可通过 MAX_VIDEO_SIZE_MB 覆盖)
|
||
|
||
models:
|
||
default_text: "glm-4-flash"
|
||
default_vision: "glm-4v-flash"
|
||
```
|
||
|
||
### 环境变量覆盖映射
|
||
|
||
| 环境变量 | YAML 路径 | 说明 |
|
||
|----------|-----------|------|
|
||
| ZHIPUAI_API_KEY | zhipuai.api_key | 必填 |
|
||
| STORAGE_ACCESS_KEY | storage.access_key | 必填 |
|
||
| STORAGE_SECRET_KEY | storage.secret_key | 必填 |
|
||
| STORAGE_ENDPOINT | storage.endpoint | RustFS 地址 |
|
||
| BACKEND_CALLBACK_URL | backend.callback_url | Java 后端回调接口 |
|
||
| LOG_LEVEL | server.log_level | 日志级别 |
|
||
| MAX_VIDEO_SIZE_MB | video.max_file_size_mb | 视频大小上限 |
|