Files
llm-in-text/backend/AGENTS.md
T
“ydy0615” 356108e792 feat: add video OCR/ASR, DOCX/PDF export, input block and risk config updates
- Video pipeline: video file OCR via VLM plus audio track ASR, integrated
  into job_handlers with progress emit per phase. New media_utils.py for
  audio extraction from video files.
- Document export: richExport.js replaces inline docx builder; DOCX and PDF
  export buttons are now enabled in MilkdownEditor. File size limit raised to
  100 MB.
- Input block: new InputBlockCrepe.vue component with inputBlockPlugin.ts
  and inputBlock.js for custom user-input nodes in the editor.
- Risk config: added Vite dev server ports (5173) to CORS allowlist and
  increased OCR max input from 10 MB to 100 MB.
- TTS/ASR refactor: simplified tts_asr.py model loading and warmup logic.
- Test coverage: updated tests for llm, main endpoints, pro completions and
  web search modules.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 16:32:31 +08:00

187 lines
9.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Backend 后端指引 (v0.2.0)
本文件适用于 backend/ 下的后端实现。进入 backend/tests/ 后,以子目录 AGENTS.md 为准。
## 后端职责
- 对外提供补全、取消补全、OCR、文档转换和 TTS/ASR 相关接口。
- 组织 Prompt,上下文清洗,调用 Ollama 模型。
- **通过 Redis Streams 异步任务队列处理各类作业(completion/PRO/web_search/compress/OCR/convert/TTS/ASR)。**
- 负责 API Key 校验、日志记录和部分启动预热逻辑。
## 先看哪里
- API 入口和路由:main.py
- **任务队列系统**job_system.pyRedis Streams 异步任务管理)
- **Worker 进程入口**worker.py(消费 Redis Streams 的独立 worker
- **任务处理器注册表**job_handlers.pycompletion/PRO/web_search/compress/OCR/convert/TTS/ASR 处理器)
- **会话管理**session_store.py(内存 + PostgreSQL 双后端)
- **API/LLM 审计日志**audit_store.pyPostgreSQL 持久化)
- **风控配置**risk_config.py(环境变量驱动的配置数据类)
- **风控引擎**risk_control.py(速率限制、并发控制、熔断器、预算追踪)
- **验证码路由**captcha_api.pyFastAPI router
- **文档存储**docs_store.pyMIME 类型检测、文本/二进制分类)
- **LLM 策略解析**llm_policy.py(按 job_type 解析模型配置)
- Ollama 调用封装:llm.py
- Prompt 清洗和拼装:prompt.py
- 数据模型:models.py
- 地理位置:geoip.py
- TTS 路由:tts_asr.py
- Prompt 模板:prompts/
- 后端测试:tests/
## 当前接口面
- POST /v1/completions
- POST /v1/completions/cancel
- POST /v1/ocr
- POST /v1/convert
- **POST /v1/web-search** - 网页搜索(SearXNG + Firecrawl
- **POST /v1/compress** - 文本压缩(用于 OCR/文档转换后的大段文本)
- **POST /captcha/generate** - 验证码生成
- **POST /captcha/verify** - 验证码验证
- /v1/tts-asr/* 由 tts_asr.py 延迟注册
## 请求流转
### /v1/completions
- 读取或生成 request_id。
- privacy_mode 为 false 时,尝试根据客户端 IP 生成 location 文本。
- 调用 prepare_prompt_context 清洗 prefix 和 suffix。
- 调用 build_completion_prompts 生成 system_prompt 和 user_prompt。
- **通过 job_system.py 提交到 Redis Streams 队列,由 worker.py 消费。**
- **成功时返回 JSONcontent 和 request_id。**
### /v1/completions/cancel
- 通过 request_id 在 ACTIVE_COMPLETIONS 中查找任务。
- 未找到返回 not_found。
- 已完成返回 already_done。
- 仍在执行则调用 task.cancel() 并返回 ok。
### /v1/ocr
- 把 base64 媒体内容解码成字节。
- 支持 `media_type=image|video``mime_type`
- 图片直接调用 call_vlm_ocr。
- 视频先把整段视频送入 OCR 模型,再用 ffmpeg 抽取音轨交给 ASR,最后合并文本。
- **结果通过 job_handlers.py ocr_handler 处理。**
- 返回识别文本、原始文件名,以及视频场景下的 `ocr_text` / `asr_text`
### /v1/convert
- 接收 base64 文件内容和文件名。
- 当前允许的扩展名只有 txt、docx、pptx、pdf。
- txt 直接解码后清洗。
- 其他格式写入临时文件,用 MarkItDown 转换,再做 Markdown 清洗。
- **结果通过 job_handlers.py convert_handler 处理。**
- 清洗逻辑会移除图片 Markdown 和 img HTML 标签,并压缩多余空行。
### /v1/web-search (新增)
- 接收搜索查询词和可选的引擎列表。
- **通过 job_handlers.py web_search_handler 处理。**
- **调用 SearXNG 搜索 API,再通过 Firecrawl 抓取页面内容。**
- **返回结构化的搜索结果(标题、链接、摘要)。**
### /v1/compress (新增)
- 接收长文本(OCR 结果、文档转换结果等)。
- **通过 job_handlers.py compress_handler 处理。**
- **调用 LLM 进行文本压缩,保留关键信息,移除冗余内容。**
- **返回压缩后的文本和压缩率统计。**
### /captcha/generate (新增)
- 生成随机验证码图片(4-6 位字母数字组合)。
- **通过 captcha_api.py captcha_generate_handler 处理。**
- **返回 base64 编码的验证码图片和明文答案。**
### /captcha/verify (新增)
- 验证用户输入的验证码是否正确。
- **通过 captcha_api.py captcha_verify_handler 处理。**
- **比对用户输入与存储的验证码答案,返回验证结果和错误信息(如有)。**
### /v1/tts-asr/*
- 通过 _register_tts_asr_routes 延迟导入并挂到主应用。
- **TTS 请求通过 job_handlers.py tts_handler 处理。**
- **ASR 请求通过 job_handlers.py asr_handler 处理。**
- **当前实现是 `Qwen3TTSModel + faster-whisper`,不是旧的 edge-tts / macos-say / MLX-only 路线。**
## 开发命令
- 安装依赖:pip install -r backend/requirements.txt
- **Docker 部署**docker compose up -d --build(在 /Users/allenyuan/lit/llm-in-text/ 目录下执行)
- 启动:python backend/main.py
- **Worker 进程**python backend/worker.py(独立运行,消费 Redis Streams
- 开发启动:uvicorn backend.main:app --reload --port 8001
- 路由相关测试:
- pytest backend/tests/test_main_endpoints.py -v
- pytest backend/tests/test_main_cancel.py -v
- Prompt 测试:
- pytest backend/tests/test_prompt.py -v
- pytest backend/tests/test_prompt_extended.py -v
- LLM 测试:
- pytest backend/tests/test_llm.py -v
- pytest backend/tests/test_llm_extended.py -v
- **新增测试**
- pytest backend/tests/test_web_search.py -v(网页搜索功能)
- pytest backend/tests/test_compress.py -v(文本压缩功能)
## 编码约定
- Python 使用 4 空格缩进。
- 函数、变量使用 snake_case,类使用 PascalCase。
- **新逻辑优先保留显式类型和明确的输入输出。**
- **异步边界要清晰;阻塞操作优先放进 asyncio.to_thread,而不是直接阻塞事件循环。**
- **异常要么转成 HTTPException,要么转成结构化 JSONResponse;不要静默吞掉后端错误。**
- **日志尽量带 request_id 或短 tag,便于把前后端一次请求串起来。**
## 容易误判的点
- **任务队列架构(v0.2.0 新增)**:后端从同步端点转向 Redis Streams 异步队列。job_system.py 定义 JOB_TYPESworker.py 消费队列,job_handlers.py 注册各类型处理器。
- **会话追踪**session_store.py 提供 InMemorySessionStore(开发)和 PostgresSessionStore(生产),通过 session_hash + ip_hash 追踪请求身份。
- **风控系统**risk_config.py + risk_control.py 实现速率限制(滑动窗口)、并发控制、熔断器模式和预算追踪,所有阈值通过环境变量配置。
- **验证码路由**captcha_api.py 提供 /captcha/generate 和 /captcha/verify 端点,用于前端验证用户输入。
- **文档存储**docs_store.py 提供 MIME 类型检测、文本/二进制分类和预览提取(8MB 限制)。
- **LLM 策略解析**llm_policy.py 按 job_type 解析模型配置(模型名、温度、最大 token、思考级别)。
- **OCR 明确关闭思考**llm.py 的 `call_vlm_ocr` 对 OCR 请求显式设置 `options.think = False``temperature = 0`
- **补全接口当前不是流式响应,不要按 SSE 方式改造周边代码。**
- **ACTIVE_COMPLETIONS 在补全和取消路径里都被读写,任务生命周期要谨慎处理。**
- **`/v1/export/pdf` 不是当前主链路**;DOCX/PDF 导出已经转到前端 `src/utils/richExport.js`
- **API_KEY 存在占位默认值,这更像本地开发兜底,不是推荐的安全模式。**
- **历史 TTS/ASR 文档和部分测试覆盖的是旧实现;代码与文档冲突时,先确认产品方向,再决定修代码还是修文档。**
## 改动时的定位建议
- **如果问题是补全结果不对,先查 prompt.py,再查 llm.py,不要只盯着 main.py。**
- **如果问题是取消不生效,先查 main.py 里的 request_id 生命周期,再对照前端的 X-Request-Id 和 cancel 调用。**
- **如果问题是 OCR 识别为空,先看 main.py 的 base64 解码,再看 llm.py 的 call_vlm_ocr。**
- **如果问题是转换结果脏,重点看 main.py 里的 _sanitize_converted_markdown。**
- **如果问题是 TTS 行为和文档不一致,以 tts_asr.py 为准,不要以 README 为准。**
- **如果问题是 Web Search 失败,检查 SearXNG 和 Firecrawl 服务状态(docker compose ps)。**
- **如果问题是任务队列积压,检查 worker.py 日志和 Redis Streams 长度(INFO keys=stream)。**
- **如果问题是会话丢失,检查 session_store.py 的 InMemory/Postgres 后端切换逻辑。**
- **如果问题是风控触发,检查 risk_config.py 的环境变量配置和风险阈值。**
## 测试映射
- **路由主行为**tests/test_main_endpoints.py
- **取消逻辑**tests/test_main_cancel.py
- **Prompt 逻辑**tests/test_prompt.py、tests/test_prompt_extended.py
- **LLM 包装层**tests/test_llm.py、tests/test_llm_extended.py
- **GeoIP**tests/test_geoip.py
- **TTS 相关**tests/test_tts_asr_*.py
- **网页搜索**tests/test_web_search.py(新增)
- **文本压缩**tests/test_compress.py(新增)
## 文档使用原则
- README.md、TTS_ASR_MACOS_FIX.md、tests/TESTING_GUIDE.md 可以作为背景材料。
- **一旦这些文档和 main.py、llm.py、prompt.py、tts_asr.py 冲突,以代码为准。**
- **新增模块(job_system、worker、job_handlers、session_store、audit_store、risk_config、risk_control、captcha_api、docs_store、llm_policy)的文档需与代码保持同步。**
- **Docker 部署相关文档(docker-compose.yml、backend/Dockerfile、Dockerfile.frontend、.dockerignore)需与 docker/ 目录下的配置保持一致。**