2025-01-29-photo-answer-feature-design.md 10 KB

拍照解题功能设计文档

文档版本: v1.0
创建日期: 2025-01-29
设计者: Backend Team
状态: 设计阶段


一、功能概述

1.1 核心能力

拍照解题功能基于阿里云百炼 EduTutor 服务,提供两大核心能力:

  • 试卷切题(Cut Questions): 上传试卷图片,自动识别并切分题目,返回结构化信息
  • 解题辅导(Answer): 上传题目图片,获取详细的解题思路和答案

1.2 业务价值

  • 提升学习效率:快速获取题目解析,节省查找时间
  • 智能化教学:提供结构化的解题思路,培养解题能力
  • 试卷数字化:自动切分试卷,便于题库管理和批量处理

二、功能架构

2.1 系统架构

┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   Frontend      │    │   Backend       │    │  百炼 EduTutor  │
│                 │    │                 │    │                 │
│ 图片上传        │───▶│ 图片处理        │───▶│ Cut API         │
│ 题目展示        │    │ 请求转发        │    │ Answer API      │
│ 答案渲染        │◀───│ 结果解析        │◀───│ (SSE 流式)      │
│                 │    │                 │    │                 │
└─────────────────┘    └─────────────────┘    └─────────────────┘
         │                      │
         │                      ▼
         │              ┌─────────────────┐
         │              │   PostgreSQL    │
         └─────────────▶│                 │
           (可选)        │ 题目记录        │
                        │ 解答历史        │
                        └─────────────────┘

2.2 数据流向

试卷切题流程:

  1. 用户上传试卷图片 → 前端
  2. 图片上传至 OSS → 后端
  3. 调用 Cut API → 百炼服务
  4. 返回题目列表(含坐标、结构化信息、子图链接)→ 后端
  5. 解析并展示题目 → 前端

解题辅导流程:

  1. 用户选择题目/上传图片 → 前端
  2. 调用 Answer API(SSE 流式)→ 后端
  3. 流式返回解题过程 → 百炼服务
  4. 实时渲染解答内容 → 前端

三、核心接口设计

3.1 试卷切题接口

端点: POST /api/edu/cut-questions

请求参数:

{
  "image_url": "https://oss.example.com/paper.png",
  "options": {
    "struct": true,           // 是否返回结构化信息
    "extract_images": true    // 是否返回子题图片链接
  }
}

响应结构:

{
  "success": true,
  "data": {
    "questions": [
      {
        "index": 0,
        "type": "填空题",
        "stem": {
          "text": "若 a + b = -1, ab = 4, 则...",
          "pos_list": [[21, 4, 364, 4, 364, 78, 21, 78]]
        },
        "options": [],
        "answer": [{"text": "-17"}],
        "merged_image": "https://oss.../question_0.png",
        "sub_images": ["https://oss.../sub_0_0.png"]
      }
    ]
  },
  "input_tokens": 80,
  "output_tokens": 38
}

3.2 解题辅导接口

端点: POST /api/edu/answer (SSE 流式)

请求参数:

{
  "image_url": "https://oss.example.com/question.png",
  "parameters": {
    "grade": 6,              // 年级(0-17, 99=其他)
    "stage": "小学",          // 学段
    "subject": "数学"         // 学科
  }
}

SSE 流式响应:

data: {"type": "start", "content": "### 【考点分析】:\n"}
data: {"type": "chunk", "content": "本题涉及代数表达式..."}
data: {"type": "chunk", "content": "### 【方法点拨】:\n"}
data: {"type": "finish", "finish_reason": "stop", "tokens": {"input": 654, "output": 457}}

四、数据模型设计

4.1 题目记录表 (question_records)

字段 类型 说明
id UUID 主键
user_id UUID 用户ID(外键)
image_url TEXT 原始图片链接
question_type VARCHAR(20) 题目类型
stem_text TEXT 题干文本
answer_text TEXT 答案文本
structured_data JSONB 完整结构化数据
created_at TIMESTAMP 创建时间

4.2 解答历史表 (answer_history)

字段 类型 说明
id UUID 主键
question_id UUID 题目ID(外键)
user_id UUID 用户ID(外键)
answer_content TEXT 解答内容(Markdown)
grade INTEGER 年级
subject VARCHAR(50) 学科
input_tokens INTEGER 输入Token数
output_tokens INTEGER 输出Token数
created_at TIMESTAMP 创建时间

五、技术实现要点

5.1 图片处理

上传策略:

  • 前端直传 OSS(推荐):减轻后端压力,提升上传速度
  • 后端中转:适用于需要图片预处理的场景

图片要求:

  • 格式:JPG、PNG
  • 分辨率:建议 1080p 以上
  • 大小限制:< 10MB
  • 必须是公网可访问的 URL

5.2 SSE 流式处理

后端实现:

async def answer_stream(image_url: str, params: dict):
    client = create_edututor_client()
    request = build_answer_request(image_url, params)
    
    async for chunk in client.answer_sse_async(request):
        yield format_sse_event(chunk)

前端实现:

const eventSource = new EventSource('/api/edu/answer');
eventSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  appendAnswer(data.content);
};

5.3 错误处理

常见错误场景:

  • 图片无法访问:返回 400,提示图片链接无效
  • API 调用超时:设置 100s 超时,超时后返回 504
  • 识别失败:返回 422,提示图片质量不佳或题目不清晰
  • 配额不足:返回 429,提示今日调用次数已达上限

六、性能与成本

6.1 性能指标

指标 目标值
切题响应时间 < 5s(单页试卷)
解题首字响应 < 2s
解题完整响应 < 15s
并发支持 100 QPS

6.2 成本控制

优化策略:

  • 缓存相同题目的解答结果
  • 对重复图片进行去重识别
  • 用户侧限流:每用户每天最多 50 次调用 ---

七、安全与合规

7.1 数据安全

  • 图片链接有效期:7 天(百炼返回的临时链接)
  • 敏感信息过滤:检测并脱敏个人信息(姓名、学号等)
  • 访问控制:仅用户本人可查看历史记录

八、用户体验设计

8.1 交互流程

试卷切题:

  1. 点击"上传试卷"按钮
  2. 选择图片(支持拖拽)
  3. 显示上传进度
  4. 展示切分后的题目列表(卡片式布局)
  5. 点击题目卡片查看详情

解题辅导:

  1. 选择题目或上传单题图片
  2. 选择年级、学科(可选)
  3. 点击"开始解题"
  4. 流式展示解题过程(打字机效果)
  5. 支持复制、收藏、分享

8.2 UI 组件

  • 上传组件: 拖拽上传 + 点击上传,显示预览和进度
  • 题目卡片: 显示题号、类型、题干预览、缩略图
  • 解答面板: Markdown 渲染,支持数学公式(LaTeX)
  • 历史记录: 时间线展示,支持搜索和筛选

九、开发计划

9.2 技术依赖

后端:

  • alibabacloud-edututor20250707: 百炼 SDK
  • alibabacloud-credentials: 凭证管理
  • oss2: 阿里云 OSS SDK(图片上传)

前端:

  • react-markdown: Markdown 渲染
  • katex: 数学公式渲染
  • react-dropzone: 文件上传组件

十、测试策略

10.1 单元测试

  • 图片上传逻辑
  • API 请求构造和响应解析
  • SSE 流式数据处理
  • 数据库 CRUD 操作

10.2 集成测试

  • 完整的切题流程
  • 完整的解题流程
  • 错误场景处理
  • 并发请求测试

10.3 用户测试

  • 不同类型试卷的识别准确率
  • 不同学科题目的解答质量
  • 流式输出的流畅度
  • 移动端适配效果

十一、后续优化方向

11.1 功能增强

  • 支持手写题目识别
  • 支持拍照后本地裁剪和标注
  • 支持多题批量解答
  • 支持解答过程的语音播报

11.2 智能化升级

  • 根据用户历史推荐相似题目
  • 智能识别薄弱知识点
  • 生成个性化练习题
  • 错题本自动整理

11.3 社区化

  • 用户可分享优质解答
  • 支持题目讨论和评论
  • 教师可创建题目集合
  • 学生可组队刷题

十二、风险与应对

风险 影响 应对措施
API 调用超限 服务不可用 实现本地缓存 + 用户限流
识别准确率低 用户体验差 提供手动编辑入口 + 反馈机制
图片加载慢 响应时间长 CDN 加速 + 图片压缩
成本超预算 运营压力 实施分级收费策略

附录

A. 相关文档

B. 环境变量配置

# 阿里云凭证
ALIBABA_CLOUD_ACCESS_KEY_ID=your_access_key_id
ALIBABA_CLOUD_ACCESS_KEY_SECRET=your_access_key_secret

# 百炼 Workspace ID
BAILIAN_WORKSPACE_ID=llm-uflun9q7q59osmbb

# OSS 配置(图片上传)
OSS_ENDPOINT=oss-cn-hangzhou.aliyuncs.com
OSS_BUCKET=your-bucket-name
OSS_ACCESS_KEY_ID=your_oss_ak
OSS_ACCESS_KEY_SECRET=your_oss_sk

C. API 调用示例

切题示例:

curl -X POST "http://localhost:8000/api/edu/cut-questions" \
  -H "Content-Type: application/json" \
  -d '{
    "image_url": "https://example.com/paper.png",
    "options": {"struct": true, "extract_images": true}
  }'

解题示例:

curl -N "http://localhost:8000/api/edu/answer" \
  -H "Content-Type: application/json" \
  -d '{
    "image_url": "https://example.com/question.png",
    "parameters": {"grade": 6, "subject": "数学"}
  }'

文档结束