TgWitness / 文档

已测试的内容 →

参考 / 存档与集成

Telegram · 全文搜索

根据词形、精确短语、域名和 @用户名 查找已保存的消息,按最匹配结果优先排序,索引与签名日志绑定。

TgWitness / 文档 · 调查

调查

存档分析 · 本地 OCR 和转录 · 维基

预览。在“日志”中,选择搜索框旁边的“最佳匹配 · 词形变体” 选项。结果按 BM25 算法排序,并匹配同一单词的其他形式: 搜索“перевод”会找到“переводом”和“переводы”,搜索“transfer”会找到“transfers”,中文 短语在搜索时不保留空格。选择“最新优先 · 精确文本”可保留之前 对整个记录进行的子字符串搜索。

索引是衍生数据。它由签名日志重建而成,本身从未被签名, 也从未被导出。原始记录不会发生任何变化。

本页内容

搜索语法#

撰写 查找
перевод карта 同时包含这两个词的记录(形式不限)
"переводом на карту" 请按此顺序保留确切的短语
бонус OR подарок 任一词
перевод -казино 不含被排除词的记录
example.com 该域名及其子域名,包括隐藏链接和按钮 URL 中的域名
@username, t.me/username 该账号的提及和链接,以及其发送的消息
#tag 话题标签
+79991234567,一个钱包地址,一个电子邮件地址 文本或链接中的相同值
from:@username, from:123456 来自该发件人的消息
chat:-1001234567890 一个聊天窗口;它只能限制您自己的访问权限
id:42 消息 42 的已保存版本
since:2026-01-01 until:2026-01-31 观察时段;仅含日期而不含时间的日期表示全天
kind:edited 仅编辑(new, snapshot, edited, recovered)
source:ocr, source:transcription, source:all 识别出的文本,可替代消息或与消息并存

当存在其他单词时,介词和其他功能词将被忽略。 混入单词中的易混淆字母(例如西里尔字母单词中的拉丁字母 a)、全角 及装饰性 Unicode 字母以及不可见字符均将被规范化处理。

语言#

系统会根据每条记录中的脚本和字母来检测语言:

脚本 匹配
西里尔字母 使用 pymorphy3 处理俄语和乌克兰语词干。若未启用可选的乌克兰语词典,则使用轻量级乌克兰语词干提取器
拉丁文 英语 Snowball 词干提取器;忽略音标符号
中文、日语、韩语、泰语、老挝语、高棉语、缅甸语 重叠字符对:查找不包含空格的任何短语。中文查询将使用 jieba 拆分为单词
其他脚本 精确词句

乌克兰语词典(pymorphy3-dicts-uk)依据 GPL-3.0 协议发布,因此 默认情况下不会安装。请使用以下命令进行安装 pip install "tgwitness[uk-dictionary]"; 索引会自动识别新的分析器并重新构建自身。

索引的位置#

模式 存储 用法
磁盘存储(默认) search/fulltext.sqlite3 在工作区目录中 支持大型存档;重启后数据仍可保留
仅限内存中 磁盘上不留任何数据;每次启动时都会重新构建 磁盘上不保留消息文本的任何衍生副本
关闭 不设索引;按最新内容优先排序 · 保留原文精确表述 最低配置

主管理员可在“日志”→“过滤器”→“搜索索引”中 为每个工作区选择模式。 TGWITNESS_FULLTEXT=disk|memory|off 为 未自行选择的 Workspace 设置默认值。切换至“内存”或“关闭”将删除该文件。 索引文件与日志具有相同的保护措施:它位于私有数据 目录中。该文件未加密,也不包含在备份或异地副本中。

新记录会在后台数秒内完成索引;搜索时也会优先索引 短暂的积压记录,因此刚保存的记录也能被检索到。现有日志会在 更新后完成索引,且不会阻塞面板;在此之前,搜索结果涵盖 已索引的记录,日志会显示进度。重建索引时将从 第一条记录开始重新进行。

python -m tgwitness index status --data-dir data/live
python -m tgwitness index rebuild --data-dir data/live --json

rebuild 需要停止该面板(否则退出代码为 3)。使用 --json, 标准输出仅显示结果;进度信息将输出到标准错误。

结果及签名日志#

索引存储其所涵盖的最后一条日志记录的序列号和哈希值, 并在打开日志时将其与日志进行比对。若日志被替换、恢复或编辑, 则会触发索引重建。每次响应都会报告该位置,每次查询结果均 通过序列号从签名日志中读取:索引仅决定显示哪些 记录以及显示顺序,绝不涉及记录内容。聊天权限仅适用于 日志自身的聊天字段,而不适用于索引内容。

识别出的文本#

OCR 结果和转录文本保留在其加密的原始文件中。其索引仅存在于 内存中,并在识别任务完成时重建。匹配结果将显示在其 media.saved 记录中显示,标注为“机器识别”,并附带引擎、模型及 摘录内容;该内容绝不会以 Telegram 中发送的文本形式呈现。同一索引还用于 “搜索已识别文本”功能,该功能仍可匹配纯文本子字符串。

访问#

“聊天范围”访问仅查找来自其聊天的记录,包括 其附件中被识别的文本。 chat: 以及其他过滤条件仅能进一步缩小该数据集范围。向范围限定访问显示的索引状态 不包含日志总数。仅主管理员可以更改 模式或重建索引。

向存档和 MCP 咨询#

当索引构建完成后,Ask the Archive 将从该索引中检索数据源:即 所选聊天记录中匹配度最高的条目,且每条已保存的文本仅计数一次。最多发送 24 个数据源;长文本将在匹配位置处截断,并标记为“截断”。 关于近期更改、单条消息的已保存版本以及在 索引仍在构建期间进行的搜索,均使用之前的按时间顺序检索方式。预览 界面会显示所使用的方法。

MCP 客户端可调用 search_messages 使用 ranked=true ,并使用 next_offset。范围限定连接仅接收其所属的聊天内容。

排序分页最多显示前1,000条结果,无论页面大小如何。请缩小查询范围、聊天范围或时间范围以查看更多匹配结果。按最新优先搜索会在选择每页之前,对消息、OCR 结果和转录结果进行排序。

依赖项#

软件包 许可协议 为什么
pymorphy3、pymorphy3-dicts-ru、DAWG2-Python MIT 俄语和乌克兰语词干;词典在本地加载
snowballstemmer BSD-3-Clause 英文词干,纯 Python 代码
jieba MIT 中文查询分词,纯 Python 实现(仅提供源代码分发)
pymorphy3-dicts-uk(可选) GPL-3.0 完整的乌克兰语词典

SQLite FTS5 需要 unicode61 分词器;该分词器是当前 Python 构建版本中 SQLite 的一部分。若缺少该分词器,最佳匹配搜索将报告其不可用。

基准测试#

python tools/bench_fulltext.py --messages 1000000 --work <empty directory>生成一个确定性的签名日志,其中包含来自 200 个聊天群组中混合使用俄语、乌克兰语、英语、 中文和日语的消息,以及其中的链接和标识符;构建索引 并测量典型搜索的耗时(50 条结果,7 次运行的中位数)。

测试环境:Windows 11、Intel Core i9-13900K、128 GB 内存、Python 3.12.10、SQLite 3.49.1,数据存储于 exFAT 分区,分析器 fulltext-v1+pymorphy3-ru+light-uk+snowball-en:

度量 结果
签名日志 1,000,000 条消息,1.50 GiB,19 分钟内写入
基于日志构建索引 71 秒,约每秒 14,141 条消息
索引文件 58 MiB,占日志总量的 3.8%
在新记录生成后立即进行搜索 中位数 8 毫秒,P95 值 9 毫秒
之前的子字符串搜索,同一日志 перевод 3.2 秒, 银行转账 2.6 秒, verify-account.example 2.6 秒
搜索 匹配记录 最佳匹配,中位数 p95 最新优先,中位数排序
常用词及词形: перевод 134,403 82 毫秒 85 毫秒 7 毫秒
两个词: оплата карта 28,996 43 毫秒 43 毫秒 14 毫秒
生僻词: розыгрыш подарок 28,881 42 毫秒 47 毫秒 13 毫秒
精确短语: "переказ коштів на картку" 不计入 35 毫秒 36 毫秒 6 毫秒
域名及子域名: verify-account.example 12,435 17 毫秒 17 毫秒 3 毫秒
@用户名: @support_desk_bot 10,331 15 毫秒 16 毫秒 3 毫秒
中文无空格: 银行转账 17,691 23 毫秒 24 毫秒 3 毫秒
日语: リンク 16,603 23 毫秒 25 毫秒 3 毫秒
英文词干: withdrawal 27,775 26 毫秒 26 毫秒 2 毫秒
或与排除: бонус OR подарок -казино 268,034 190 毫秒 193 毫秒 19 毫秒
聊天过滤器: chat:-1000000000007 перевод 652 9 毫秒 9 毫秒 6 毫秒
时间范围筛选器: since:2026-01-01 until:2026-01-31 выплата 115,732 155 毫秒 156 毫秒 81 毫秒

系统会按排名顺序逐一检查候选结果中是否存在完全匹配的短语,直到页面 填满为止,因此该项的总数不计入统计。耗时随匹配记录数量的增加而增长; 缩小聊天范围或时间范围可加快广泛搜索的速度。合成语料库中 词汇量有限,因此常见词匹配到的记录数量远多于真实聊天记录。