POST /api/chat 增加可选的 pictures、files 字符串数组。省略与 [] 等价,null、字符串代替数组、非字符串元素或多余字段返回HTTP 422。thread_id、非空 question 的原校验及SSE协议保持;图片和文件不会拼接改写原问题。
F109:两个数组现在也接受相对路径。接口先以 API_ATTACHMENT_BASE_URL 补齐路径,再按原有规则校验和下载;本地 .env 配置为 http://121.43.55.7:10081/dms/。例如 /upload/a.png 解析为 http://121.43.55.7:10081/dms/upload/a.png。已是HTTP(S)完整地址的元素保持原样;未配置前缀时相对路径仍返回HTTP 422。服务端重启后读取新配置。
{
"thread_id": "chat-example",
"question": "请结合图片中的设备和附件预算,说明有哪些支持方向及需要核实的条件。",
"pictures": ["https://files.example.com/download?id=picture"],
"files": ["https://files.example.com/download?id=budget"]
}
链接必须无需登录即可由后端GET下载。允许无扩展名、带签名查询参数的HTTP(S)链接;按实际文件内容识别格式,不依赖URL后缀或响应文件名。浏览器依赖Cookie才能下载的地址不符合此契约。服务不转发用户Cookie或Authorization;签名URL不传给模型、不写终端日志或Redis附件记录。图片下载后以Base64发送到视觉模型。
本轮未增加域名白名单配置。下载器默认拒绝解析到非公网地址的主机,并在每次重定向重新检查与固定连接IP;因此内网文件服务尚不在当前可访问范围,后续如需接入需单独定义可信下载范围。最多跟随3次重定向,不接受带用户名密码、片段或控制字符的URL。相对路径补齐不会绕过这些下载限制。
| 字段 | 格式 | 处理 |
|---|---|---|
| pictures | JPEG/JPG、PNG、静态GIF、静态WebP | deepseek-flash读取图片文字、表格和可观察信息,生成带不确定性的视觉笔记 |
| files | XLSX、XLSM、XLS | pandas读取全部工作表;新格式使用openpyxl,XLS使用xlrd |
| files | DOCX | python-docx按正文顺序读取段落及表格 |
| files | 文字PDF | pdfplumber逐页提取文字;保留页码 |
Excel保留工作表和行号,使用存储值及已有公式缓存,不计算公式、不运行宏、不读取图表中的图片文字;数字格式显示的前导零、货币等样式不等于实际单元格值。DOCX范围为正文段落及表格,不含图片OCR、文本框和页眉页脚;PDF不做OCR。F111起,PDF任一页无法提取文字即视为该附件读取不完整,本轮终止;空白页也会触发这一规则,请提供每页均有可提取文字的PDF。加密、损坏、无文字或不支持的文件同样终止本轮,不假装读取成功。多帧GIF/WebP当前提示改传静态图。
图片API依据:官方Vision文档。图片识别使用同一模型服务地址/凭据、独立的deepseek-flash模型名;后续文字问答沿用现有DEEPSEEK_MODEL。服务端必须支持该视觉模型。视觉笔记不是图片逐字原文或已核实的企业事实。
F110:视觉提示要求在没有可辨文字时仍描述可观察的主体和画面;最终回答提示按用户实际问题区分图片观察与知识库规则。图片本身不能证明广告排版、申报条件等未呈现的事实;用户明确询问规则时才依据知识资料另答,并标明不是从图片读出。是否能辨识具体内容仍取决于原图与视觉模型,本轮未取得用户原图复现。
incomplete,用于理解“这个/这些资料”等;不能把摘录当作完整文件。附件来源可辅助寻找政策,但不独立证明资格。user_attachment,与政策来源分开。即使没有知识库命中也能依据附件回答;同题QA不再绕过本轮附件。附件不产生政策卡片。可接收范围不等于所有文件都能在单次请求时间内完成;长文摘要会增加模型调用及延迟,摘要存在遗漏风险,不等于逐页独立语义审计。
| 处理边界 | 当前值 |
|---|---|
| pictures + files数量 | 合计最多8个 |
| 请求JSON | 保持64 KiB上限,单URL最多8192字符 |
| 单附件/本轮累计下载 | 10 MiB / 32 MiB |
| 单次下载 | 总预算30秒,阻塞socket读取最长10秒,故可能有一次读取的超出;DNS使用系统解析超时 |
| 单文档解析子进程 | 最长30秒 |
| 单图片视觉请求 | 最长45秒服务读取超时;阻塞期间保持会话占用 |
| 图片尺寸 | 单边最多8192,最多3200万像素 |
| Office ZIP展开 | 最多64 MiB、5000个内部条目 |
| Excel | 最多32工作表,每表10000行、256列 |
| 最多200页 | |
| 单文档提取文字 | 最多200000 UTF-8字节;最多10000个非空片段 |
| 本轮全部文字/视觉笔记 | 最多400000 UTF-8字节 |
F111(2026-09-23):附件串行处理,遇到首个下载、格式、可读性或限额失败立即停止,不再读取后续链接,也不进入需求分类、企业查询、知识检索和回答。已成功读取的前序附件仅保留在本轮attachments状态事件,不用于生成部分答案;下次提问需重新提交全部所需附件。原有请求超时/断连约束保持,超时后的工作者实际退出才释放会话锁。
若链接本身的语法或协议在请求接纳前无效,接口仍返回HTTP 422;响应新增message与attachment.kind/index/title/error,指出具体“图片N”或“附件N”,不会启动SSE或下载。数组结构整体无效仍返回普通invalid_request。
新增progress.stage=attachments的开始/结束事件,以及attachments事件;外层仍为thread_id/request_id/data。
{"items":[
{"id":"attachment_随机ID","kind":"file","index":1,"title":"附件1","status":"ready","format":"docx","warnings":["docx_body_only"]},
{"id":"attachment_另一个ID","kind":"file","index":2,"title":"附件2","status":"failed","error":"document_no_text","message":"文档没有可提取的文字,可能为空或为扫描件。"}
]}
全部成功时,result.data.attachments重复完整处理状态,index是各字段数组内从1起的序号,成功下载后fetched_at记录上海时间。空输入时该字段为[],无需新事件。处理失败时先发attachments(含处理到的状态),再发progress.stage=attachments/status=failed,最后以error.code=attachment_processing_failed结束SSE;错误message指明“图片N”或“附件N”及原因,attachment提供kind/index/title/error,不回传下载URL。此时没有result、summary或政策卡片,前端应显示error.data.message,请用户更换附件后重新提问。知识检索失败仍与没有命中区分。
成功附件通过原有source事件和recommendation.sources提供:type=user_attachment,source.provider=user_attachment,source.kind/format描述来源;full_record.sections[]保留location/text,warnings记录提取边界。summary.source_ids/citations关联实际采用的来源,文档引用path=/sections/N/text及页/行/段落位置。图片引用指向视觉笔记,前端不能将其标为人工核验原文。下载URL不回传;前端通过kind/index关联自己的原始链接。
公司确认中断和/retry恢复保留原轮次的附件,不重复下载;确认/恢复请求请发送空数组或省略字段。此时提交新的非空附件会通过SSE返回attachments_during_resume,保留原中断供再次确认,避免静默丢弃新文件。后续新问题不会自动继承旧附件全文;如需再次分析请重新提交链接。历史答复仍按既有有界对话上下文保留,不视为独立证据。
附件提取文字及视觉笔记会随本轮图状态保存在同一thread的Redis检查点,沿用现有保留周期。原始下载二进制仅用于内存/解析子进程,不写资料目录或开发文档。DMS问答记录仍由前端保存,本轮不修改DMS结构、不把附件原文件写入DMS。
python -m unittest discover -s src/step4_api/tests -q覆盖真实合成DOCX/Excel/PDF解析、图片四格式请求、失败隔离、下载限制、预算分批、联合QA来源、可选字段与中断恢复;python -m unittest discover -s src/step3_question_answer/tests -q验证原问答行为。
python -m src.step4_api.attachment_check是主动调用真实模型的纯合成检查,生成图片及文档,不使用真实用户附件。仅保存检查布尔值、预算与安全错误码到output/checks/attachments.json,不记录正文/密钥。
依赖已写入pyproject.toml及uv.lock。安装锁定依赖并重启后端后生效;外部前端按新字段发送即可,处理状态可选展示。生产附件下载、前端来源呈现、大型真实文档及模型语义质量仍需联调验收。