当文字藏在图片里,搜索会变成另一件事。文件名无法描述截图,扫描 PDF 可能没有文字层,网页的有效内容也可能藏在 HTML 里。
Syzygy 为这些情况建立本地搜索索引。索引器(indexer)不会替代历史记录,而是读取历史事件并提取可搜索字段。
它写入持久化搜索文档。原始条目仍然是真源。
一条搜索结果包含两条时间线
历史记录时间线从采集开始,搜索时间线从索引任务完成开始。两个时刻可能不同,列表可以先显示新条目。
搜索索引稍后补充正文。OCR 可能比标题更新耗时更久,大文件可能需要等待后台任务。界面应该显示这段差异。
它不应该把暂时缺少结果报告成数据丢失,也不应该因为 OCR 阻塞采集。
持久化任务流程
每个索引任务携带条目身份和内容指纹,并记录任务状态与重试信息。
后台任务按有限批次领取工作,读取能够访问的内容,提取文字和元数据,再构建搜索文档。
它会更新或插入文档(upsert),也会在条目删除时移除对应文档(delete document),再把任务标记为完成。提取失败时记录错误,任务可以重试。
重启后,过期的占用声明可以回到队列。队列避免一次崩溃丢掉建立索引请求。
搜索文档包含什么
文档标识原始条目。它保存来源或对端设备上下文、序号值和内容类型。
它保存元数据令牌和文件名。正文提取成功时保存正文文字,OCR 成功时保存 OCR 文本。
它保存标签、来源应用和用于过滤的日期字段。文档只是索引投影。
它不是第二份内容块(blob)存储。打开结果会回到历史记录,历史记录流程检查本地化状态,用户看到当前内容状态。
文本提取从安全字节开始
纯文本直接进入提取,Markdown 直接进入提取,源代码保留行结构,UTF-8 BOM 会被处理。
UTF-16 小端和大端 BOM 都会被处理。非法 UTF-8 会在最后合法边界停止,提取器不会制造大量损坏的替换文本。
索引收到可以比较的内容,查询就能在不读取原始文件的情况下完成初步匹配。
HTML 提取会移除传输层噪声
HTML 可以包含有效文章,也可以包含脚本、样式和模板。
它还可以包含注释和隐藏元数据。提取器忽略非内容节点,保留可见文字。
它保留块边界、有意义的换行和代码容器中的源内容空白,也可以使用图片替代文本作为后备线索。
搜索文档得到可读文字,原始 HTML 仍供预览界面使用,预览和索引因此各自保留适合自己的表示。
PDF 先提取文字,再使用 OCR
文字型 PDF 已经有可用文字层。Syzygy 先读取这层文字,提取成功时不需要 OCR,可以减少 CPU 工作。
扫描 PDF 可能没有文字层。内容服务会渲染限定页数,当前默认处理前两页,PDF 上限是 32 MiB。
OCR 把渲染页变成文字,搜索文档保存提取结果,原始 PDF 二进制保持不变。
图片 OCR 处理截图
图片可以来自截图工具、浏览器复制或同步设备。OCR 服务提供方可以使用 PaddleOCR。
也可以使用 Tesseract CLI。大图片可以先缩放,识别结果会映射回原图坐标。语言提示会选择服务提供方参数。
输出可以按语言分组。OCR 结果会保存为结构化 JSON,搜索索引使用其中的文字字段,预览可以使用其中的坐标。
OCR 缓存键保护正确性
OCR 结果属于一张输入图片、一个服务提供方、一组语言设置和一个像素上限。
它还属于一个引擎标识和坐标版本。这些值共同组成缓存键,更换服务提供方会得到新结果。
更换语言、缩放上限或坐标语义都会得到新结果。缓存使用 TTL。
缓存使用最大条目数,过期条目不会修改原始条目。
文件索引遵守明确限制
多文件条目可以包含多个文件。索引器(indexer)可以索引文件名、文件扩展名和可读正文。
它也可以索引 PDF 内容和图片 OCR 文本。文件匹配规则决定哪些文件进入提取,字节上限保护后台任务。
并发上限保护桌面。集合仍然通过成员身份定位,两个成员可以同名,搜索文档保存稳定的出现位置或内容引用。
高级搜索缩小工作范围
搜索可以按大小写、文件扩展名、最大字节数和对端设备过滤。
也可以按来源应用、开始日期和结束日期过滤。查询有结果数量限制。
扫描有工作量限制,请求有并发限制。这些限制保护交互操作,结果仍然指向历史记录。
标签和全文一起使用
标签提供人工分类,OCR 提供图片里的文字,文件名提供粗粒度过滤,来源应用提供上下文。
日期范围提供时间边界,可以组合其中两个信号。在项目标签中搜索 research,再在支持应用的截图中搜索错误码。
在日期范围内搜索 PDF 词语。索引不需要另一套数据库查询服务。
任务失败时会发生什么
任务记录错误。条目仍然保留在历史记录,元数据仍然可以搜索,后台任务可以重试正文提取。
OCR 服务提供方可能暂时不可用。索引器(indexer)可以先保留文件名,之后再补充 OCR 文本。 损坏文档不应该让整个批次崩溃。
过期的后台任务占用声明不应该卡住队列。删除条目会产生索引删除,旧的更新或插入(upsert)不能复活已经删除的内容。
搜不到结果时的诊断
确认条目存在于历史记录,确认条目没有处于本地未完成状态,检查是否有索引任务和内容指纹。
检查任务状态、提取动作错误、OCR 服务提供方状态和查询筛选条件。
检查日期范围、查询语言和结果是否已删除。搜索应区分索引延迟和条目缺失。
搜索正文过期时的诊断
比较条目内容哈希值和索引指纹,检查是否存在等待中的更新或插入(upsert)和失败的替换任务。
检查界面是否缓存旧结果。从历史记录打开条目,历史记录内容仍然是最终参考。
真实流程:会议截图
截取会议幻灯片。历史记录条目立即出现,索引任务进入队列,后台任务执行 OCR。
结果保存识别到的文字。给条目加项目标签,搜索项目标签,再加入幻灯片中的一句话。
打开匹配条目,复制原始图片。OCR 文本帮助你找到图片,但不会替换图片。
真实流程:扫描发票 PDF
把 PDF 复制到历史记录。PDF 在 OCR 完成前就出现,提取器先检查嵌入文本;如果文字层为空,再进入 OCR。
服务渲染前几页,OCR 提取发票号码,索引器(indexer)保存号码,搜索可以通过号码找到 PDF。
打开结果,用 PDF 预览查看原始排版;需要时用文本工作台(TextWorkbench)创建文字快照。
真实流程:搜索代码
从终端复制命令。内容计划标记源文本,索引器(indexer)保存命令,稍后可以搜索选项名称。
按来源应用过滤,打开源内容预览并复制准确命令。搜索结果不会删除重要标点。
历史记录条目仍然是源数据,索引只提供更快的入口。
常见问题
搜索需要网络吗?
本地索引在设备上运行。服务提供方提供的 OCR 可能有自己的配置。历史记录和元数据搜索仍然可以本地执行。
新条目为什么没有出现在搜索里?
索引任务可能还在等待中。大文件可能需要等待后台任务。先检查任务状态,不要重复复制同一条目。
索引可以搜索图片像素吗?
索引搜索 OCR 文本和元数据。它不是图片相似度服务。
PDF 有多少页会使用 OCR?
当前默认最多渲染前两页。PDF 上限为 32 MiB。
有文字层的 PDF 可以搜索吗?
可以。提取器会优先读取嵌入文本。
OCR 会修改截图吗?
不会。OCR 只增加结构化结果和索引字段。
插件可以打开索引目录吗?
插件应该使用搜索接口。索引目录属于内部实现细节。
永久删除后会怎样?
搜索文档会被删除,同步会收到删除证据。
标签可以过滤 OCR 结果吗?
可以。标签和全文是不同字段,可以在查询中组合。
OCR 失败会删除条目吗?
不会。条目仍然在历史记录,任务会记录失败。
验证清单
复制一条文本。搜索它的完整短语。复制一张截图。等待 OCR。
搜索一个可见词。复制文字型 PDF。搜索其中的短语。复制扫描 PDF。
搜索 OCR 词语。加一个标签,组合标签和短语,再永久删除条目。
确认搜索结果消失。重启桌面端,确认等待中任务恢复。
先判断你要找的是哪一种文字
搜索截图时,先想清楚词语来自哪里。它可能来自图片上的印刷文字,也可能来自图片替代文本、文件名或你手动添加的标签。 这些字段都能帮助定位条目,但只有 OCR 文字能回答“这几个字出现在图像哪里”这个问题。把字段混在一起,会让你误以为 OCR 已经完成。
搜索 PDF 时先看预览页面。文字型 PDF 的文字层通常可以直接复制;扫描 PDF 只能依赖渲染后的图像和 OCR。两种 PDF 都可以被找到, 但结果状态应该告诉你搜索命中的是嵌入文字还是识别文字。需要精确引用时,打开原始页面检查换行、页眉和脚注,不能只凭搜索片段下结论。
OCR 结果与原图坐标
OCR 返回的文字不是一条没有位置的字符串。每个识别片段都可以带有边界框,预览层据此高亮原图中的区域。缩放图片只影响识别输入的像素尺寸, 坐标仍然要映射回原图,用户点击搜索结果时才不会跳到错误位置。若图片被旋转或裁剪,系统应记录变换,重新计算框的位置,不要复用旧坐标。
坐标用于定位,不等于编辑结果。你可以从高亮区域复制文字,也可以回到原始图片查看上下文;修改 OCR 文本不会改写图片。需要保存修订内容时, 请在文本工作台(TextWorkbench)中创建新快照,并保留原始条目作为证据。
索引任务的重试边界
一次任务失败不应让整批文件消失。任务会记录失败原因,例如文件过大、格式损坏、服务提供方暂时不可用或本地磁盘不足。可恢复错误可以重试, 无法恢复的输入则应保持失败并允许用户打开原始内容。队列为每个任务设定重试上限,避免网络不可用时持续消耗电量和流量。
内容发生变化时,系统会依据新的内容指纹建立替换任务。旧任务即使晚到,也不能覆盖新结果。条目进入回收站或被永久删除后,索引删除任务应优先于旧的文字更新, 这样搜索不会重新出现已经清理的内容。重启应用后,未完成任务从持久化队列恢复,用户无需再次复制文件。
同名文件和多文件集合
一个项目集合可能含有多个 README.md 或同名截图。搜索结果需要显示集合来源、成员位置和文件大小,不能只显示文件名。点击结果后,
界面应打开对应成员,而不是让用户在集合中再次猜测。成员被替换时,新的内容指纹会生成新的搜索投影;旧成员被删除时,旧投影随删除事件移除。
集合索引遵守整体预算。文件数量、单个文件大小和总字节数都有限制。超过限制的成员会显示为未索引,并说明原因;其他成员仍然可以完成索引。 这比让一个异常文件阻塞整个集合更容易恢复。
一次可复现的验证流程
使用下面的材料做验证:一段纯文本、一张包含清晰标题的截图、一个文字型 PDF、一个扫描 PDF,以及一个包含两个同名文件的集合。先确认五个条目都出现在历史记录。
- 搜索纯文本中的完整短语,确认结果立即可见。
- 等待截图索引完成,搜索图中的独特词语,打开结果并检查高亮位置。
- 复制文字型 PDF,搜索一段带标点的句子,确认结果来自文字层。
- 复制扫描 PDF,等待限定页面完成 OCR,搜索发票号码并核对页面排版。
- 搜索集合中的同名文件,确认结果显示成员位置和正确内容。
- 把其中一个条目移入回收站,再搜索它,确认状态和搜索结果一致。
- 永久删除测试条目,等待删除任务完成,确认搜索结果消失。
- 在索引任务进行时重启应用,确认任务回到队列而不是重新生成重复条目。
如果某一步失败,复制不含正文的诊断摘要。摘要只需要包含条目标识、内容类型、任务状态、重试次数、提取阶段和时间,不要把截图文字或 PDF 正文放入工单。
对使用者的承诺
本地索引的价值不在于把所有内容塞进一个搜索框,而在于让每一次命中都能回到真实条目。你可以知道结果来自文件名、标签、文字层还是 OCR; 可以知道正文是否已经在本地;也可以在提取失败时保留原始文件。索引只提供更快的入口,不改变你的历史记录、图片和 PDF。
结果排序需要解释
搜索结果通常同时命中标题、标签、文件名和正文。排序时,系统会优先展示与你输入的词语更接近、时间更近且状态可用的条目。相关性排序只是帮助你缩短选择时间, 不能替代打开原始内容后的核对。相同分数的结果应保持稳定顺序,避免你在两次搜索之间看到条目来回跳动。
等待索引的条目可以出现在结果里,但必须带有等待标记。点击它时,界面应说明当前只拥有元数据、正在等待 OCR,或正在等待远程内容下载。 如果你只想看已经可以打开的文件,可以使用“已就绪”筛选条件;如果你在整理项目,可以保留等待中结果,先补充标签和标题。
多语言 OCR 的取舍
同一张截图可能同时包含中文、英文和数字。选择语言范围越窄,识别速度通常越快;选择多语言,覆盖范围更广,但误识别的机会也会增加。保存 OCR 结果时, 系统记录使用的语言设置,让你知道为什么同一张图片在不同设置下可能得到不同文字。需要准确引用时,回到原图核对大小写、标点和数字,特别是订单号与版本号。
资源预算保护交互
索引任务在后台运行,但后台不等于没有上限。每个任务受到文件大小、页数、像素数和运行时间约束;多个任务还会共享并发额度。超过额度的任务进入可理解的失败状态, 不会拖慢前台的命令面板、预览和复制。你可以先处理小文件,再单独重试大文件,也可以调整策略后重新建立索引。
如何判断索引是否可信
选一条已知短语,分别从原始文本、PDF 文字层、截图 OCR 和文件名中搜索。四种来源都命中时,打开结果核对来源标记。再修改原始条目,确认旧短语不会继续命中, 新短语会在替换任务完成后出现。最后把条目移入回收站并恢复,检查索引状态随历史状态变化。这个过程能发现过期投影、删除传播和任务重试中的边界问题。
索引的职责是提供入口,不是替你判断内容。它把词语、来源和状态摆在一起,最终决定仍然由你在原始条目上完成。
搜索结果应该告诉你证据来自哪里
同一个词语可能同时出现在文件名、标签、PDF 文字层和图片 OCR 中。结果列表应标明命中的来源,让你知道这是文件名筛选、人工分类,还是图像识别。来源标记还能解释为什么一个结果可以立即打开,而另一个结果仍在等待内容块(blob)或 OCR 任务。
打开结果后,预览页面回到原始条目,并保留页码、图像位置或来源应用等上下文。搜索片段只负责帮你定位,不能替代原始页面的核对。订单号、金额和版本号这类信息,始终应回到原图或 PDF 页面确认。
如果索引使用了多语言 OCR,结果还应显示识别语言和任务时间。更换语言设置会产生新的识别结果,旧结果可以按保留策略清理,但不会修改原始图片。这样,搜索变化有明确原因,用户也能判断是否需要重新运行 OCR。
旧结果为什么不会重新出现
索引更新需要处理一个常见竞态:用户修改条目的速度可能超过后台提取速度。系统为每次内容变化生成新的指纹,任务只允许写入仍然匹配当前指纹的结果;旧任务即使晚一些完成,也只能被丢弃,不能覆盖新文字。删除动作拥有更高优先级,回收站和永久删除会先写入状态,再让索引投影移除对应文档。
sequenceDiagram
participant H as 历史条目
participant Q as 索引队列
participant X as 提取任务
participant I as 搜索索引
H->>Q: 内容指纹 A
Q->>X: 提取 A
H->>Q: 内容指纹 B
Q->>X: 提取 B
X-->>I: A 完成
I->>H: 校验当前指纹
H-->>I: 当前为 B,拒绝 A
X-->>I: B 完成
I->>H: 校验当前指纹
H-->>I: 接受 B查询因此可以短暂看到“等待索引”,但不会看到一个已经被替换的旧片段。界面应把索引时间、内容状态和命中来源放在同一条结果里。支持人员拿到摘要后,可以判断问题发生在采集、提取、写入还是查询缓存,而不需要查看原始正文。
当你要验证这条边界时,先复制一段包含独特词语的文字,等待搜索命中,再修改其中一个词并立即搜索新旧两个词。旧词应在替换任务完成后消失,新词随后出现。把条目移入回收站,再恢复它,最后永久删除;每一步都检查历史列表、搜索结果和任务状态。这个流程比只运行一次搜索更能发现过期投影和删除传播问题。
继续阅读
阅读持久化标签和回收站,了解如何管理可检索的元数据。阅读文本工作台和翻译,了解如何把识别结果变成新的快照。阅读P2P 同步,了解等待中内容如何在设备之间安全到达。索引结果应始终诚实地表达自己的延迟。