feat(wiki): expose method=tika short-circuit on extract_document_text

This commit is contained in:
matevip 2026-04-25 19:02:35 +08:00
parent c752c1f2ae
commit c13d9b4c88

View File

@ -45,20 +45,26 @@ public class DocumentExtractTool {
- Excel (.xlsx, .xls) - 提取为文本表格
- PowerPoint (.pptx, .ppt)
提取策略自动选择最优方式
提取策略默认自动选择最优方式
1. 优先使用系统命令pdftotext, textutil, pandoc
2. 系统命令不可用时使用纯 Java 实现
3. 返回详细的提取过程和元数据
3. PDF 扫描版进入 OCR
4. 全部失败前用 Apache Tika 兜底覆盖 SmartArt共享字符串表等盲区
5. 返回详细的提取过程和元数据
参数 options 可包含
- pages: 指定页码范围 "1-5" "1,3,5"
- preserveLayout: 是否保留布局默认 true
- method: 强制指定提取器跳过自动 fallback 当前支持
* "auto"默认 走完整 fallback
* "tika" 直接用 Apache Tika 抽取适合 Windows 上没装
Poppler/Python 的环境或验证 Tika 单独是否能解开
如果提取失败会返回详细的尝试过程和错误信息
""")
public String extract_document_text(
@ToolParam(description = "文件的绝对路径或相对路径") String filePath,
@ToolParam(description = "可选参数 JSON如 {\"pages\": \"1-5\", \"preserveLayout\": true}", required = false) String options) {
@ToolParam(description = "可选参数 JSON如 {\"pages\": \"1-5\", \"method\": \"tika\"}", required = false) String options) {
JSONObject result = new JSONObject();
result.set("filePath", filePath);
@ -75,6 +81,38 @@ public class DocumentExtractTool {
String mimeType = detectMimeType(path);
result.set("mimeType", mimeType);
// RFC-051: method=tika 短路 跳过整条 fallback 直接调 Tika
// 用于1) 测试 Tika 集成是否健康2) 用户明知系统命令不可用想免去
// 那一长串失败日志的场景结果里仍然带 attempts 数组告知"应用户要求跳过自动链"
String forcedMethod = extractOption(options, "method");
if ("tika".equalsIgnoreCase(forcedMethod)) {
long t = System.currentTimeMillis();
String text = TikaExtractor.extract(path);
attempts.add("user-forced method=tika: skipped automatic fallback chain");
if (text == null || text.isBlank()) {
attempts.add("tika: 失败或不可用 (" + (System.currentTimeMillis() - t) + "ms)");
return errorResult(filePath, "Tika 抽取无文本(可能格式不支持或文件损坏)", attempts);
}
attempts.add("tika: 成功 (" + (System.currentTimeMillis() - t) + "ms)");
String capped = text;
boolean trunc = false;
if (capped.length() > MAX_OUTPUT_LENGTH) {
capped = capped.substring(0, MAX_OUTPUT_LENGTH)
+ "\n\n... [内容已截断,总长度: " + text.length() + " 字符]";
trunc = true;
}
result.set("text", capped);
result.set("method", "tika");
result.set("pages", estimatePages(text));
result.set("attempts", attempts);
result.set("truncated", trunc);
result.set("success", true);
log.info("[DocumentExtract] {} 使用 method=tika 强制提取成功,{} 字符",
filePath, text.length());
return JSONUtil.toJsonPrettyStr(result);
}
// 根据类型选择提取器
ExtractedContent content;
if (mimeType.contains("pdf")) {