- 8 user stories (P1-P3): text triple extraction, image quadruple extraction, video frame extraction, video-to-text, QA generation (text/image), finetune management, health check - 18 functional requirements covering all 8 API endpoints - 9 success criteria with measurable metrics - Technical environment section: Python 3.12.13, FastAPI, conda label env - Quality checklist: all items pass
20 KiB
Feature Specification: AI 服务需求文档
Feature Branch: 001-ai-service-requirements
Created: 2026-04-10
Status: Draft
Input: User description: "@docs/superpowers/specs/2026-04-10-ai-service-design.md 根据设计文档完成需求文档"
概述
知识图谱智能标注平台需要一个独立的 AI 计算服务,接收 Java 后端的调用,完成文档结构化提取、图像分析、视频预处理、训练数据生成和模型微调管理等智能化任务,将大模型能力嵌入标注工作流,大幅降低人工标注成本。
User Scenarios & Testing (mandatory)
User Story 1 - ADMIN 从文档中提取知识三元组 (Priority: P1)
ADMIN 在标注平台上选择一份已上传的文本文件(TXT、PDF 或 Word 文档),触发 AI 辅助提取。AI 服务从存储系统中读取该文档,分析内容,识别其中的主谓宾知识关系(三元组),并为每个三元组标注原文出处片段和字符偏移位置,返回结构化结果供标注员审核确认。
Why this priority: 文本三元组提取是平台文本标注流水线的核心入口,所有文本类标注任务都依赖此能力。无此功能,平台的主要价值无法实现。
Independent Test: 向 AI 服务发送一个包含已知知识点的测试文档路径,验证返回结果包含正确的主语/谓语/宾语和对应的原文位置信息,即可独立验证此功能完整运行。
Acceptance Scenarios:
- Given 存储系统中存有一份 TXT 格式文档,When AI 服务收到该文档路径和提取请求,Then 返回包含至少一条三元组的结果,每条含 subject、predicate、object、原文片段和字符偏移。
- Given 存储系统中存有一份 PDF 格式文档,When AI 服务收到提取请求,Then 正确解析 PDF 内容并返回三元组结果。
- Given 存储系统中存有一份 Word(.docx)格式文档,When AI 服务收到提取请求,Then 正确解析文档内容并返回三元组结果。
- Given 请求包含不支持的文件格式(如 .xlsx),When AI 服务收到请求,Then 返回明确的格式不支持错误,不崩溃。
- Given 存储系统不可达,When AI 服务尝试下载文件,Then 返回存储故障错误,而非通用服务器错误。
User Story 2 - ADMIN 从图片中提取知识四元组并自动裁剪 (Priority: P1)
ADMIN 在标注平台选择一张已上传的图片,触发 AI 辅助提取。AI 服务读取该图片,通过多模态大模型分析图像内容,识别图中的知识实体关系(四元组:主体、关系、客体、修饰信息),同时给出每个知识点在图像中的位置框(bbox 坐标),并自动将对应区域裁剪保存,供标注员对照审核。
Why this priority: 图像四元组提取是图片标注流水线的核心入口,与文本三元组提取并列为平台两大主流水线的起点。
Independent Test: 向 AI 服务发送一张包含可识别对象关系的测试图片路径,验证返回结果包含四元组信息和裁剪图的存储路径,即可独立验证此功能完整运行。
Acceptance Scenarios:
- Given 存储系统中存有一张图片,When AI 服务收到该图片路径和提取请求,Then 返回包含至少一条四元组的结果,每条含 subject、predicate、object、qualifier 和 bbox 坐标。
- Given AI 服务成功提取四元组,When 处理完成,Then 每个四元组对应的图像区域已自动裁剪并上传至存储,响应中包含裁剪图的存储路径。
- Given bbox 坐标超出图像边界,When 裁剪时,Then 自动截断至图像有效区域,不报错。
- Given 大模型返回格式异常(非 JSON),When 解析响应,Then 返回解析失败错误,不返回部分结果。
User Story 3 - ADMIN 对视频进行帧提取(帧模式预处理) (Priority: P2)
ADMIN 在标注平台选择一段已上传的视频,选择"帧提取"模式(按固定间隔或关键帧),触发 AI 服务处理。AI 服务在后台异步完成帧提取,将每一帧图片上传至存储,处理完成后主动通知 Java 后端,后端随即为每一帧创建图片标注任务,进入图片标注流程。
Why this priority: 视频帧提取是视频进入图片标注流水线的预处理步骤,依赖图片提取流水线(P1)已就绪。
Independent Test: 向 AI 服务发送一个测试视频的存储路径和 job_id,服务立即返回 202 Accepted,稍后验证回调接口收到含帧路径列表的成功通知,即可独立验证。
Acceptance Scenarios:
- Given 存储系统中存有一段视频(大小在限制内),When AI 服务收到帧提取请求(interval 模式),Then 立即返回 202 Accepted 和 job_id,不等待处理完成。
- Given 帧提取任务在后台成功完成,When 处理完成,Then AI 服务向 Java 后端发送回调,包含 job_id、status=SUCCESS 和帧图存储路径列表。
- Given keyframe 模式,When AI 服务处理视频,Then 仅提取画面发生显著变化的帧,而非固定间隔。
- Given 视频文件大小超过系统上限(默认 200MB,可配置),When 收到请求,Then 立即返回 400 错误,不启动后台任务。
- Given 帧提取过程中发生错误,When 任务失败,Then AI 服务仍向 Java 后端发送回调,status=FAILED,包含错误描述。
User Story 4 - ADMIN 将视频片段转换为文字描述(片段模式预处理) (Priority: P2)
ADMIN 在标注平台选择一段已上传视频的时间段,触发"视频转文本"预处理。AI 服务在后台均匀采样该时间段的视频帧,用多模态大模型理解视频内容,生成结构化文字描述,将描述文本上传存储,完成后通知 Java 后端,后端将其创建为新的文本类原始资料,进入文本标注流程。
Why this priority: 视频转文本预处理使视频内容能够通过文本标注流水线处理,扩展了平台的数据来源范围。
Independent Test: 向 AI 服务发送测试视频路径、时间段和 job_id,验证回调收到 output_path 指向一个可读的文字描述文件,即可独立验证。
Acceptance Scenarios:
- Given 存储系统中存有一段视频(大小在限制内),When AI 服务收到视频转文本请求,Then 立即返回 202 Accepted 和 job_id。
- Given 视频转文本任务在后台成功完成,When 处理完成,Then AI 服务向 Java 后端发送回调,包含 job_id、status=SUCCESS 和文字描述的存储路径。
- Given 请求指定了起止时间段(start_sec、end_sec),When 处理视频,Then 仅分析该时间段内的内容,不处理其他片段。
- Given 视频文件大小超过上限,When 收到请求,Then 立即返回 400 错误。
- Given 大模型调用失败,When 任务异常,Then 回调 status=FAILED,包含错误描述。
User Story 5 - 系统自动为已审批三元组生成候选问答对 (Priority: P2)
标注员提交的文本三元组经审批员审批通过后,系统自动调用 AI 服务,将三元组列表和对应原文片段批量输入大模型,生成符合微调格式的候选问答对,作为后续训练数据的来源。
Why this priority: 问答对生成是平台训练数据产出流程的关键环节,依赖三元组提取(P1)已完成并通过审批。
Independent Test: 向 AI 服务发送一组测试三元组(含原文片段),验证返回包含可读、合理的问答对列表,即可独立验证。
Acceptance Scenarios:
- Given 一组已审批的文本三元组,When AI 服务收到文本 QA 生成请求,Then 返回包含 question 和 answer 的问答对列表,每个三元组至少对应一个问答对。
- Given 大模型返回合法 JSON,When 解析响应,Then 正确提取每对问答并返回。
- Given 大模型返回格式异常,When 解析响应,Then 返回解析失败错误。
- Given 大模型服务不可用,When 调用失败,Then 返回明确的服务不可用错误。
User Story 6 - 系统自动为已审批四元组生成候选图文问答对 (Priority: P2)
图像四元组经审批通过后,系统自动调用 AI 服务,将四元组信息与对应裁剪图一起输入多模态大模型,生成图文问答对,用于后续图像类训练数据集。
Why this priority: 图像 QA 生成是图片标注流水线产出训练数据的最终步骤,优先级与文本 QA 生成(P2)相同。
Independent Test: 向 AI 服务发送一组四元组(含裁剪图存储路径),验证返回的问答对引用了图片路径,即可独立验证。
Acceptance Scenarios:
- Given 一组已审批的图像四元组(含裁剪图路径),When AI 服务收到图像 QA 生成请求,Then 返回包含 question、answer 和 image_path 的问答对列表。
- Given 裁剪图存储路径有效,When AI 服务处理,Then 自动获取图片内容并结合四元组信息生成问答,无需调用方额外传输图片数据。
- Given 裁剪图无法从存储获取,When 处理请求,Then 返回存储错误,不返回空结果。
User Story 7 - ADMIN 提交微调任务并查询进度 (Priority: P3)
ADMIN 在标注平台完成训练数据集导出后,选择提交大模型微调任务。平台调用 AI 服务提交微调请求(包含训练数据文件地址、基础模型和超参数),获取微调任务 ID。此后,ADMIN 可随时查询该任务的运行状态(进行中/成功/失败)和完成进度。
Why this priority: 微调任务管理是平台最终目标(产出定制化模型)的关键步骤,但需要前置数据准备流程全部完成,故列为 P3。
Independent Test: 向 AI 服务发送微调请求,获取 job_id,再调用状态查询接口,验证能正确返回当前状态,即可独立验证。
Acceptance Scenarios:
- Given 训练数据 JSONL 文件已在存储中准备就绪,When AI 服务收到微调提交请求(含文件地址、基础模型、超参数),Then 返回微调任务 ID。
- Given 微调任务已提交,When 查询任务状态,Then 返回 job_id、当前状态(RUNNING/SUCCESS/FAILED)和进度百分比。
- Given 任务处于运行中,When 多次查询状态,Then 每次均返回最新状态,不缓存旧状态。
- Given 传入不存在的 job_id 查询状态,When 处理请求,Then 返回明确错误,不崩溃。
User Story 8 - 运维监控服务健康状态 (Priority: P3)
运维人员或监控系统定期探测 AI 服务的健康状态,判断服务是否正常运行,以便在异常时及时告警或自动重启。
Why this priority: 健康检查是服务稳定运行的基础保障,但不属于业务功能,列为 P3。
Independent Test: 对健康检查接口发起 HTTP GET 请求,验证收到表示正常的响应,即可独立验证。
Acceptance Scenarios:
- Given AI 服务正常运行,When 任何系统对健康检查接口发起请求,Then 立即返回服务正常的响应,响应时间不超过 1 秒。
- Given 容器运行中,When 容器编排系统定期发起健康探测,Then 通过探测的容器才被标记为可用状态并接收流量。
Edge Cases
- 文件存在于存储系统但内容损坏(如 PDF 页面为空)时,如何处理?→ 返回解析结果为空,不报错,日志记录警告。
- 视频帧提取结果为零帧(如视频文件损坏或间隔过大)时,如何处理?→ 回调 SUCCESS,返回空帧列表,Java 后端决定是否重试。
- 大模型返回的三元组/四元组超过合理数量(如数百条)时,如何处理?→ 全量返回,由 Java 后端或标注员筛选,AI 服务不做截断。
- 多个视频任务并发执行时,是否会互相影响?→ 每个任务独立使用临时文件,处理完成后清理,互不干扰。
- 视频文件大小恰好等于上限时,如何处理?→ 视为超限,拒绝处理,避免边界情况下的内存压力。
- 大模型以 Markdown 代码块格式(```json ... ```)返回 JSON 时,如何处理?→ 自动提取代码块内的 JSON 内容,兼容此格式。
Requirements (mandatory)
Functional Requirements
文本处理
- FR-001: 系统 MUST 支持从 TXT、PDF、DOCX 三种格式的文档中提取知识三元组(subject / predicate / object),并为每条三元组提供原文出处片段和字符偏移位置。
- FR-002: 系统 MUST 在文件格式不受支持时,返回明确的格式不支持错误(HTTP 400),拒绝处理请求。
图像处理
- FR-003: 系统 MUST 支持从图片中提取知识四元组(subject / predicate / object / qualifier),并提供每个知识点在图像中的位置框(bbox:x, y, w, h 像素坐标)。
- FR-004: 系统 MUST 在返回四元组结果时,自动将每个知识点对应的图像区域裁剪并保存至存储,响应中包含裁剪图的存储路径。
视频处理
- FR-005: 系统 MUST 支持视频帧提取,提供两种模式:固定间隔模式(按帧数间隔)和关键帧模式(场景切换时提取)。
- FR-006: 系统 MUST 以异步方式处理视频任务,接受请求后立即返回接受确认(HTTP 202),在后台完成处理后主动通知调用方。
- FR-007: 系统 MUST 支持视频片段转文字描述,输入起止时间段,输出视频内容的结构化文字描述,并将描述文本保存至存储。
- FR-008: 系统 MUST 在视频文件大小超过上限时,拒绝处理并返回明确错误;大小上限 MUST 支持运行时配置(默认 200MB),不需要重新构建服务即可调整。
问答对生成
- FR-009: 系统 MUST 支持基于文本三元组(含原文片段)批量生成候选问答对,每条三元组至少生成一个问答对。
- FR-010: 系统 MUST 支持基于图像四元组(含裁剪图存储路径)生成图文候选问答对,图片内容由系统自动从存储获取,调用方只需提供存储路径。
微调管理
- FR-011: 系统 MUST 支持向大模型服务提交微调任务,输入训练数据文件地址、基础模型名称和超参数,返回微调任务 ID。
- FR-012: 系统 MUST 支持通过任务 ID 查询微调任务当前状态(RUNNING / SUCCESS / FAILED)和完成进度。
服务运维
- FR-013: 系统 MUST 提供轻量健康检查接口,可被容器编排系统、反向代理和监控工具调用,无需认证,响应时间不超过 1 秒。
- FR-014: 系统 MUST 对每次请求记录结构化日志,包含请求路径、响应状态和耗时;对每次大模型调用记录模型名称和耗时;对视频后台任务记录任务 ID、阶段和结果;日志 MUST NOT 包含文件原文内容。
- FR-015: 系统 MUST 在大模型返回非法格式时(HTTP 502)、存储不可达时(HTTP 502)、大模型服务不可用时(HTTP 503),分别返回不同的结构化错误响应,便于调用方判断根因。
- FR-016: 系统 MUST 提供 Swagger/OpenAPI 自动文档,描述所有接口的请求和响应格式。
可扩展性
- FR-017: 系统 MUST 将大模型调用和存储访问封装为可替换的适配层,当前实现 ZhipuAI GLM 系列和 RustFS,替换实现时业务逻辑层无需修改。
- FR-018: 系统 MUST 通过配置文件和环境变量管理所有可变参数(模型名称、存储地址、密钥、视频大小上限等),支持不重建服务镜像的情况下切换环境配置。
Key Entities
- 三元组(Triple): 从文本中提取的知识关系,由主语(subject)、谓语(predicate)、宾语(object)、原文片段(source_snippet)和字符偏移(source_offset: start/end)组成。
- 四元组(Quadruple): 从图像中提取的知识关系,在三元组基础上增加修饰信息(qualifier)和图像位置框(bbox: x/y/w/h),并关联裁剪图存储路径(cropped_image_path)。
- 问答对(QA Pair): 由 question 和 answer 组成,文本类关联三元组上下文,图像类额外携带图片存储路径(image_path)。
- 视频任务回调(Video Job Callback): 异步任务完成通知,包含 job_id、status(SUCCESS/FAILED)、结果数据(帧路径列表或文字描述路径)和错误信息。
- 微调任务(Finetune Job): 包含任务 ID、当前状态(RUNNING/SUCCESS/FAILED)和进度百分比。
Success Criteria (mandatory)
Measurable Outcomes
- SC-001: 对于长度在 10,000 字以内的文档,三元组提取请求在 60 秒内完成并返回结果,满足标注员实时等待的体验预期。
- SC-002: 对于分辨率在 4K 以内的图片,四元组提取和裁剪图上传在 30 秒内完成,裁剪图区域与 bbox 坐标对应准确(误差 ≤2 像素)。
- SC-003: 视频帧提取和视频转文本任务提交后,接受响应在 1 秒内返回;后台处理完成后回调通知在 10 分钟内送达(针对 200MB 以内的视频)。
- SC-004: 视频大小超限的请求,拒绝响应在 3 秒内返回(含存储查询耗时),不启动任何后台处理。
- SC-005: 问答对生成请求(≤10 条三元组/四元组),在 90 秒内完成并返回全部问答对。
- SC-006: 健康检查接口在服务正常运行时,响应时间不超过 1 秒,容器编排系统依此判断服务可用状态。
- SC-007: 所有错误响应均返回结构化错误信息(含错误类型和描述),不返回通用服务器错误,便于调用方在不查看日志的情况下判断根因。
- SC-008: 替换大模型服务商或存储实现时,业务逻辑层代码零修改,仅需变更配置和适配层实现。
- SC-009: 所有业务接口通过自动化单元测试覆盖,包括正常路径、存储错误、大模型错误、格式解析错误等场景。
Technical Environment (mandatory)
注:本节记录项目已确定的技术约束,这些决定已由团队确认,不作为需求变更点。
- 运行时: Python 3.12.13
- Web 框架: FastAPI(含 uvicorn 服务器)
- 运行环境: conda 虚拟环境,环境名称
label - 大模型: ZhipuAI GLM 系列(文本:glm-4-flash,视觉:glm-4v-flash),通过官方 SDK 调用
- 对象存储: RustFS,通过 S3 兼容 API(boto3)访问
- 文档解析: TXT(UTF-8 解码)、PDF(pdfplumber)、DOCX(python-docx)
- 视频处理: OpenCV(帧提取 + 帧差分关键帧检测)
- 容器化: Docker + Docker Compose,提供 Dockerfile 和 docker-compose.yml
Assumptions
- Java 后端(label-backend)是 AI 服务的唯一调用方,AI 服务不对外直接暴露,无需用户认证机制。
- 大模型服务部署在公网(ZhipuAI 云端 API),RustFS 部署在 Docker 内网;因此图片内容必须以 base64 方式传递给大模型,不能依赖 RustFS 内网地址被云端服务访问。
- 文档、图片、视频等原始文件由 Java 后端负责上传至存储,AI 服务仅通过存储路径读取,不处理文件上传逻辑。
- 微调任务提交后的训练过程由 ZhipuAI 平台托管,AI 服务仅负责提交和查询,不管理训练算力资源。
- 视频任务为低频操作(由 ADMIN 手动触发),并发量有限(预计同时不超过 5 个视频任务),当前无需专用任务队列。
- 日志仅输出到标准输出(stdout),由容器运行时或日志收集系统负责落盘和归档;不记录文件原文内容,防止敏感信息泄露。
- ZhipuAI SDK 为同步阻塞调用;为保持服务并发能力,SDK 调用将在线程池中执行,不阻塞主事件循环。
- 视频大小上限默认 200MB,可通过环境变量(MAX_VIDEO_SIZE_MB)在容器运行时覆盖,无需重建镜像。