agent-data-gateway 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. agent_data_gateway-0.2.0/PKG-INFO +300 -0
  2. agent_data_gateway-0.2.0/README.md +275 -0
  3. agent_data_gateway-0.2.0/agent_data_gateway.egg-info/PKG-INFO +300 -0
  4. agent_data_gateway-0.2.0/agent_data_gateway.egg-info/SOURCES.txt +136 -0
  5. agent_data_gateway-0.2.0/agent_data_gateway.egg-info/dependency_links.txt +1 -0
  6. agent_data_gateway-0.2.0/agent_data_gateway.egg-info/entry_points.txt +3 -0
  7. agent_data_gateway-0.2.0/agent_data_gateway.egg-info/requires.txt +15 -0
  8. agent_data_gateway-0.2.0/agent_data_gateway.egg-info/top_level.txt +3 -0
  9. agent_data_gateway-0.2.0/gateway/__init__.py +9 -0
  10. agent_data_gateway-0.2.0/gateway/__main__.py +8 -0
  11. agent_data_gateway-0.2.0/gateway/agent_api.py +500 -0
  12. agent_data_gateway-0.2.0/gateway/anchor.py +121 -0
  13. agent_data_gateway-0.2.0/gateway/cli.py +96 -0
  14. agent_data_gateway-0.2.0/gateway/commands/__init__.py +18 -0
  15. agent_data_gateway-0.2.0/gateway/commands/_common.py +46 -0
  16. agent_data_gateway-0.2.0/gateway/commands/anchor.py +48 -0
  17. agent_data_gateway-0.2.0/gateway/commands/check.py +60 -0
  18. agent_data_gateway-0.2.0/gateway/commands/doctor.py +102 -0
  19. agent_data_gateway-0.2.0/gateway/commands/get.py +70 -0
  20. agent_data_gateway-0.2.0/gateway/commands/index_.py +43 -0
  21. agent_data_gateway-0.2.0/gateway/commands/list_.py +63 -0
  22. agent_data_gateway-0.2.0/gateway/commands/parse.py +114 -0
  23. agent_data_gateway-0.2.0/gateway/commands/report.py +148 -0
  24. agent_data_gateway-0.2.0/gateway/commands/routes.py +58 -0
  25. agent_data_gateway-0.2.0/gateway/commands/scan.py +144 -0
  26. agent_data_gateway-0.2.0/gateway/commands/search.py +58 -0
  27. agent_data_gateway-0.2.0/gateway/commands/setup.py +325 -0
  28. agent_data_gateway-0.2.0/gateway/commands/status.py +52 -0
  29. agent_data_gateway-0.2.0/gateway/commands/verify.py +48 -0
  30. agent_data_gateway-0.2.0/gateway/discover.py +462 -0
  31. agent_data_gateway-0.2.0/gateway/dispatcher.py +848 -0
  32. agent_data_gateway-0.2.0/gateway/errors.py +34 -0
  33. agent_data_gateway-0.2.0/gateway/gap.py +190 -0
  34. agent_data_gateway-0.2.0/gateway/hardware.py +142 -0
  35. agent_data_gateway-0.2.0/gateway/hashing.py +82 -0
  36. agent_data_gateway-0.2.0/gateway/index.py +651 -0
  37. agent_data_gateway-0.2.0/gateway/inventory.py +128 -0
  38. agent_data_gateway-0.2.0/gateway/lineage.py +38 -0
  39. agent_data_gateway-0.2.0/gateway/magic.py +335 -0
  40. agent_data_gateway-0.2.0/gateway/manifest.py +486 -0
  41. agent_data_gateway-0.2.0/gateway/mirrors.py +189 -0
  42. agent_data_gateway-0.2.0/gateway/models.py +226 -0
  43. agent_data_gateway-0.2.0/gateway/privacy.py +88 -0
  44. agent_data_gateway-0.2.0/gateway/quality.py +170 -0
  45. agent_data_gateway-0.2.0/gateway/render.py +208 -0
  46. agent_data_gateway-0.2.0/gateway/routing.py +356 -0
  47. agent_data_gateway-0.2.0/gateway/schema.py +147 -0
  48. agent_data_gateway-0.2.0/gateway/security.py +229 -0
  49. agent_data_gateway-0.2.0/gateway/selftest.py +720 -0
  50. agent_data_gateway-0.2.0/gateway/signals.py +82 -0
  51. agent_data_gateway-0.2.0/gateway/workers.py +609 -0
  52. agent_data_gateway-0.2.0/models/evidence_document.v0.1.json +323 -0
  53. agent_data_gateway-0.2.0/models/evidence_document.v0.2.json +739 -0
  54. agent_data_gateway-0.2.0/models/package_manifest.v0.1.json +160 -0
  55. agent_data_gateway-0.2.0/models/package_manifest.v0.2.json +442 -0
  56. agent_data_gateway-0.2.0/models/quality_dimensions.v0.1.json +132 -0
  57. agent_data_gateway-0.2.0/models/security_policy.v0.1.json +69 -0
  58. agent_data_gateway-0.2.0/models/worker_protocol.v0.1.json +141 -0
  59. agent_data_gateway-0.2.0/packs/__init__.py +1 -0
  60. agent_data_gateway-0.2.0/packs/extended/__init__.py +5 -0
  61. agent_data_gateway-0.2.0/packs/legal/__init__.py +100 -0
  62. agent_data_gateway-0.2.0/packs/legal/av_lite.py +114 -0
  63. agent_data_gateway-0.2.0/packs/legal/chat_lite.py +257 -0
  64. agent_data_gateway-0.2.0/packs/legal/csv_lite.py +92 -0
  65. agent_data_gateway-0.2.0/packs/legal/doc_lite.py +72 -0
  66. agent_data_gateway-0.2.0/packs/legal/docx_lite.py +273 -0
  67. agent_data_gateway-0.2.0/packs/legal/dxf_lite.py +177 -0
  68. agent_data_gateway-0.2.0/packs/legal/eml_lite.py +188 -0
  69. agent_data_gateway-0.2.0/packs/legal/html_lite.py +121 -0
  70. agent_data_gateway-0.2.0/packs/legal/image_lite.py +179 -0
  71. agent_data_gateway-0.2.0/packs/legal/pdf_lite.py +261 -0
  72. agent_data_gateway-0.2.0/packs/legal/ppt_old.py +86 -0
  73. agent_data_gateway-0.2.0/packs/legal/pptx_lite.py +212 -0
  74. agent_data_gateway-0.2.0/packs/legal/text_lite.py +83 -0
  75. agent_data_gateway-0.2.0/packs/legal/xlsx_lite.py +176 -0
  76. agent_data_gateway-0.2.0/pyproject.toml +43 -0
  77. agent_data_gateway-0.2.0/setup.cfg +4 -0
  78. agent_data_gateway-0.2.0/tests/test_agent_facing.py +94 -0
  79. agent_data_gateway-0.2.0/tests/test_agent_interface.py +379 -0
  80. agent_data_gateway-0.2.0/tests/test_chain_plan.py +162 -0
  81. agent_data_gateway-0.2.0/tests/test_identity.py +73 -0
  82. agent_data_gateway-0.2.0/tests/test_magic.py +158 -0
  83. agent_data_gateway-0.2.0/tests/test_manifest_integrity.py +200 -0
  84. agent_data_gateway-0.2.0/tests/test_mirrors.py +151 -0
  85. agent_data_gateway-0.2.0/tests/test_parsers.py +213 -0
  86. agent_data_gateway-0.2.0/tests/test_pipeline.py +255 -0
  87. agent_data_gateway-0.2.0/tests/test_profile_execution.py +153 -0
  88. agent_data_gateway-0.2.0/tests/test_quality.py +179 -0
  89. agent_data_gateway-0.2.0/tests/test_routing.py +155 -0
  90. agent_data_gateway-0.2.0/tests/test_security.py +70 -0
  91. agent_data_gateway-0.2.0/tests/test_setup_index.py +41 -0
  92. agent_data_gateway-0.2.0/tests/test_signals.py +119 -0
  93. agent_data_gateway-0.2.0/tests/test_worker_protocol.py +182 -0
  94. agent_data_gateway-0.2.0/workers/README.md +50 -0
  95. agent_data_gateway-0.2.0/workers/anydoc/adapter.py +201 -0
  96. agent_data_gateway-0.2.0/workers/anydoc/worker.json +52 -0
  97. agent_data_gateway-0.2.0/workers/docling/adapter.py +143 -0
  98. agent_data_gateway-0.2.0/workers/docling/worker.json +59 -0
  99. agent_data_gateway-0.2.0/workers/dwg_render/adapter.py +93 -0
  100. agent_data_gateway-0.2.0/workers/dwg_render/worker.json +12 -0
  101. agent_data_gateway-0.2.0/workers/dwgread/adapter.py +200 -0
  102. agent_data_gateway-0.2.0/workers/dwgread/worker.json +12 -0
  103. agent_data_gateway-0.2.0/workers/extract_msg/adapter.py +117 -0
  104. agent_data_gateway-0.2.0/workers/extract_msg/worker.json +12 -0
  105. agent_data_gateway-0.2.0/workers/ezdxf/adapter.py +117 -0
  106. agent_data_gateway-0.2.0/workers/ezdxf/worker.json +12 -0
  107. agent_data_gateway-0.2.0/workers/libpff/adapter.py +68 -0
  108. agent_data_gateway-0.2.0/workers/libpff/worker.json +12 -0
  109. agent_data_gateway-0.2.0/workers/libredwg/adapter.py +63 -0
  110. agent_data_gateway-0.2.0/workers/libredwg/worker.json +12 -0
  111. agent_data_gateway-0.2.0/workers/mineru/adapter.py +124 -0
  112. agent_data_gateway-0.2.0/workers/mineru/worker.json +35 -0
  113. agent_data_gateway-0.2.0/workers/officecli/adapter.py +183 -0
  114. agent_data_gateway-0.2.0/workers/officecli/worker.json +31 -0
  115. agent_data_gateway-0.2.0/workers/paddleocr/adapter.py +105 -0
  116. agent_data_gateway-0.2.0/workers/paddleocr/worker.json +38 -0
  117. agent_data_gateway-0.2.0/workers/pdf_render/adapter.py +131 -0
  118. agent_data_gateway-0.2.0/workers/pdf_render/worker.json +33 -0
  119. agent_data_gateway-0.2.0/workers/pdfplumber/adapter.py +134 -0
  120. agent_data_gateway-0.2.0/workers/pdfplumber/worker.json +12 -0
  121. agent_data_gateway-0.2.0/workers/py7zr/adapter.py +99 -0
  122. agent_data_gateway-0.2.0/workers/py7zr/worker.json +12 -0
  123. agent_data_gateway-0.2.0/workers/pypdf/adapter.py +101 -0
  124. agent_data_gateway-0.2.0/workers/pypdf/worker.json +12 -0
  125. agent_data_gateway-0.2.0/workers/qpdf/adapter.py +71 -0
  126. agent_data_gateway-0.2.0/workers/qpdf/worker.json +12 -0
  127. agent_data_gateway-0.2.0/workers/rapidocr/adapter.py +103 -0
  128. agent_data_gateway-0.2.0/workers/rapidocr/worker.json +33 -0
  129. agent_data_gateway-0.2.0/workers/tika/adapter.py +75 -0
  130. agent_data_gateway-0.2.0/workers/tika/worker.json +12 -0
  131. agent_data_gateway-0.2.0/workers/trafilatura/adapter.py +99 -0
  132. agent_data_gateway-0.2.0/workers/trafilatura/worker.json +12 -0
  133. agent_data_gateway-0.2.0/workers/video_frames/adapter.py +99 -0
  134. agent_data_gateway-0.2.0/workers/video_frames/worker.json +12 -0
  135. agent_data_gateway-0.2.0/workers/whisper/adapter.py +123 -0
  136. agent_data_gateway-0.2.0/workers/whisper/worker.json +45 -0
  137. agent_data_gateway-0.2.0/workers/xls/adapter.py +143 -0
  138. agent_data_gateway-0.2.0/workers/xls/worker.json +12 -0
@@ -0,0 +1,300 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-data-gateway
3
+ Version: 0.2.0
4
+ Summary: Agent Data Gateway — 让 Agent 获得可信、完整、可追溯的数据输入(摄取编排层,不是 parser)
5
+ Author: ADG
6
+ License: Apache-2.0
7
+ Keywords: ingestion,agent,evidence,legal,pdf,docx,ocr
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3 :: Only
10
+ Classifier: License :: OSI Approved :: Apache Software License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Topic :: Text Processing
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+ Provides-Extra: pdf
16
+ Requires-Dist: pypdf; extra == "pdf"
17
+ Provides-Extra: html
18
+ Requires-Dist: trafilatura; extra == "html"
19
+ Provides-Extra: dxf
20
+ Requires-Dist: ezdxf; extra == "dxf"
21
+ Provides-Extra: email
22
+ Requires-Dist: extract-msg; extra == "email"
23
+ Provides-Extra: test
24
+ Requires-Dist: pytest; extra == "test"
25
+
26
+ # Agent Data Gateway
27
+
28
+ <p align="center">
29
+ <a href="https://github.com/CSlawyer1985/agent-data-gateway/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License"></a>
30
+ <a href="https://github.com/CSlawyer1985/agent-data-gateway"><img src="https://img.shields.io/badge/version-v0.2.0-brightgreen" alt="Version"></a>
31
+ <a href="https://github.com/CSlawyer1985/agent-data-gateway"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome"></a>
32
+ <br>
33
+ <b>让 Agent 获得可信、完整、可追溯的数据输入</b>
34
+ <br>
35
+ <b>摄取编排层(Agent Ingestion),不是又一个 Document Parser</b>
36
+ <br>
37
+ 合同 · 证据 · 判决书 · 财务表 · 聊天记录 · 邮件 · 音视频 · 图纸 · 压缩包
38
+ </p>
39
+
40
+ ---
41
+
42
+ > **新用户?** 从 [快速开始](#快速开始) 开始——三个命令跑通一个材料包。本文是完整参考手册。
43
+ >
44
+ > **核心承诺:不假装成功。** 读不了的文件进 `unresolved_items` 并给出原因与建议;本地解决不了的问题显性失败,绝不静默降质。
45
+
46
+ ---
47
+
48
+ ## 为什么做
49
+
50
+ 律师、文字工作者的真实输入是一个格式极杂的数据包:PDF 扫描件、带批注修订的 docx、财务表、聊天记录、邮件及附件、音视频、工程图纸……
51
+
52
+ 当前 Agent 最大的问题不是不会分析,而是**无法可靠地知道自己是否已完整读取全部材料**:
53
+
54
+ | 现实问题 | 后果 |
55
+ |---------|------|
56
+ | 文件遗漏(压缩包未展开、附件未拆出) | 分析建立在残缺事实上 |
57
+ | OCR 未执行(扫描件当成空文件) | "无文字层"被误读为"无内容" |
58
+ | 表格读取失败(多工作表、合并单元格) | 关键数字缺失无人知晓 |
59
+ | 解析失败被静默跳过 | 无法区分"读全了"与"读不了" |
60
+ | 来源无法回溯 | 引用时找不到原文位置 |
61
+ | 解析器悄悄换成了低质量兜底 | 报告看起来正常,实际不可引用 |
62
+
63
+ 开源生态(MinerU / Docling / Tika / Whisper / PaddleOCR 等)解决的是 **Document Parsing**——怎么把一个文件解析出来。本工具做 **Agent Ingestion**——怎么把一个案件材料包**可靠地**变成 Agent 可消费、可追溯、可信的数据。
64
+
65
+ ## 当前状态(v0.2.0)
66
+
67
+ | 维度 | 状态 |
68
+ |------|------|
69
+ | **版本** | v0.2.0(2026-08-23);v0.1.0 于 2026-08-05 首次发布 |
70
+ | **编排器核心** | ✅ 完整可用:发现/安全展开/类型识别/特征路由/调度/质量/锚点/谱系/渲染,纯 stdlib |
71
+ | **Legal Pack** | ✅ 11 个 lite parser + 预检钩子已注册 |
72
+ | **外部 worker** | ✅ 22 个适配器随 wheel 发布(含 anydoc / pdf_render / dwgread),按环境安装;可用性以本机 `adg check` 为准 |
73
+ | **Agent 接口** | ✅ 元素级检索索引 + `adg index/search/anchor/get`:命中带来源锚点与可引用标注,纯 stdlib |
74
+ | **验证矩阵** | ✅ `adg verify` 27/28 通过、0 失败(1 跳过为环境依赖项);跨 parser 对齐(L3)已用真实材料验证 |
75
+ | **真实数据验证** | ✅ input 混合材料包(23 物理文件 → 展开/派生后 41 items):全量入账、覆盖率 **97.6%**、仅剩 1 项未解决(CAJ 属知网专有格式,无开源解析器),带原因与可执行建议 |
76
+ | **资料利用率** | 📋 设计已定稿未实现:增益轨(多视角并行)+ 信号探测度量 + 快速/均衡/质量三档成本控制([ADR 0002](docs/adr/0002-utilization-as-first-class-goal.md) / [spec 11](docs/spec/11-utilization.md)) |
77
+ | **云端扩展** | 📋 设计预留(远程 worker 后端、云端模型路由),未实现 |
78
+ | **Extended Packs** | 📋 规划(CAD 深入/GIS/DICOM 等),未发布 |
79
+
80
+ 已知限制与已知问题见下方「迭代日志」最新条目;全部规格以 `docs/spec/` 与 `models/*.v0.1.json` 为准。
81
+
82
+ ## 目标
83
+
84
+ 1. **完整入账**:包内每个文件都有 item 记录或显式排除记录(`all_items_accounted`),"读全了"是可验证的事实而非感觉。
85
+ 2. **失败显性化**:任何文件未能可靠读取,必须带着阶段、原因、建议出现在清单里——Agent 和律师都知道"哪里还没读全"。
86
+ 3. **诚实降级**:解析器沿降级链回退时,产物必须携带质量标注(如 `layout=fail`、`quotation=False`),让下游知道"这份内容能检索、但不能可靠引用"。
87
+ 4. **提高资料利用率**(设计中):同一份材料用多个工具从多个角度处理——文字视角、视觉视角、容器视角、密码学视角——把"一个工具只利用了 60%"提到尽可能高,并如实报告还有多少信号没提取。见 [spec 11](docs/spec/11-utilization.md)。
88
+ 5. **本地最优**:默认全链路本地处理,客户材料、律师执业秘密不出本机。
89
+ 6. **云端可扩**:本地无解时(无 GPU、缺重型模型、格式无本地 parser),沿显式授权路径扩展云端服务与模型,产物与来源标注规则不变。
90
+ 7. **摄取 ≠ 取证**:提取技术信号(EXIF、哈希、电子签章线索),但真伪鉴定恒为 `false`,标注"需人工/鉴定复核"。
91
+
92
+ ## 实现方法
93
+
94
+ ### 架构总览
95
+
96
+ ```
97
+ 原始材料包(不可信输入)
98
+
99
+
100
+ ┌─────────────────────────────────────────────────┐
101
+ │ ADG 编排器(gateway/,纯 stdlib) │
102
+ │ 发现 → 安全展开 → 类型识别 → 特征路由 → 调度 │
103
+ │ → 质量定稿 → 锚点派生 → 谱系记录 → 渲染输出 │
104
+ │ │
105
+ │ ├─ Worker 协议:JSON Lines over stdio(spec 04) │
106
+ │ ├─ 降级链:特征路由 + 诚实回退(spec 08) │
107
+ │ ├─ 安全模型:ZIP bomb / 路径穿越 / 符号链接 / │
108
+ │ │ 宏 / PDF JS / 资源耗尽(spec 06) │
109
+ │ └─ 隐私:产物只含包内相对路径(spec 09) │
110
+ └─────────────────────────────────────────────────┘
111
+
112
+
113
+ EvidenceDocument(统一模型,spec 02)
114
+ 三身份 source/rendition/run + 八维质量 + fitness + 锚点 + 谱系
115
+ ```
116
+
117
+ ### 核心机制
118
+
119
+ | 机制 | 实现 | 解决的问题 |
120
+ |------|------|-----------|
121
+ | **完整入账** | 递归发现 + 压缩包/邮件安全展开,每文件必有 item 或排除记录 | 文件遗漏无人知晓 |
122
+ | **不可信输入安全模型** | ZIP bomb / 路径穿越 / 符号链接逃逸 / 宏 / PDF JavaScript / worker 资源耗尽,第一版即内置,拦截显性记录 | 恶意或损坏材料击穿管线 |
123
+ | **三身份模型** | `source_id`(原件,跨 parser 稳定)/ `rendition_id`(解析产物)/ `run_id`(执行) | parser 升级后结果对比与追溯 |
124
+ | **特征路由 + 降级链** | `gateway.routing.ROUTE_RULES` 同时驱动调度与 `adg routes` 总表;按文档特征选最优 parser,不可用沿链回退并记录每级失败原因 | 拿最优工具处理最优场景,失败原因可诊断,文档不与实现漂移 |
125
+ | **质量多维化** | 八维质量(发现/类型/文本/版面/OCR/附件/元数据/锚定)+ fitness 五旗标(可检索/可提取/可引用/版面敏感/真伪鉴定) | 一份文件"能检索 ≠ 能引用"如实区分 |
126
+ | **来源锚点** | 元素级定位:页码/坐标/表格单元/时间码/字段,引用可回溯原件 | 结论无法定位到证据位置 |
127
+ | **处理谱系** | 每次解析记录 operation/tool/exit_code/哈希,链式可查 | 产物来源与处理历史不可追溯 |
128
+ | **隐私保护** | 产物默认只含包内相对路径,绝对路径只在本地私有日志;输出前 scrub 兜底清洗 | 客户名、目录结构、磁盘位置不泄露 |
129
+ | **检索与回溯** | 元素级 SQLite/FTS5 索引(中文逐字切分)+ `adg anchor` 回溯;命中带 `quotable` 标注 | Agent 查得到、引得回,且知道哪句不能引 |
130
+
131
+ ## 格式范围与总路由表
132
+
133
+ 项目不再在 README 里手工复制一份容易过期的 worker 链。实际调度和总表共用 `gateway.routing.ROUTE_RULES`:
134
+
135
+ ```bash
136
+ adg routes # 全部:扩展名、触发条件、动作、工具链、选择原因
137
+ adg routes --kind pdf # 查看 PDF 的加密/损坏/扫描/混合/数字分流
138
+ adg routes --format .msg --json # 查看单个格式,或让 Agent 读取 JSON
139
+ adg check # 验证这些 worker 在当前机器是否真的可用
140
+ ```
141
+
142
+ 总表会区分 `parse`(内容解析)、`expand`(容器安全展开)和 `unresolved`(可识别但当前没有安全处理路径)。因此“识别到 `.rar`”不会被误报为“已经支持解析”;未知格式也不会猜测工具后假装成功。完整语义见 [路由策略](docs/spec/08-routing.md)。
143
+
144
+ ## 本地最优:数据不出本机
145
+
146
+ 律师材料的默认边界:**客户秘密与执业秘密在本地闭环内处理**。
147
+
148
+ - **worker 隔离**:重/异构解析走独立 venv 或 docker 容器(只读挂载原件、`network=none`、资源限额),不链入编排器;GPL 组件(extract-msg、LibreDWG、MinerU)以独立进程调用,规避许可证传染。
149
+ - **隐私三规则**(spec 09):产物只出现包内相对路径;绝对路径只进本地私有日志(可 `--no-abs-log` 关闭);输出前兜底 scrub。
150
+ - **无暗网行为**:worker 默认 `network=false` 禁止外联;需要网络的 enrich 类 worker 必须显式声明并说明用途。
151
+ - **本地能力自查**:`adg check` 一键列出本机 25+ worker 可用性,`adg doctor` 按实际材料诊断缺口,`adg setup` 一键补装。
152
+
153
+ ## 云端扩展:本地无路径时
154
+
155
+ 本地没有解析路径(无 GPU 跑不了重型模型、缺特定依赖、格式无本地 parser、或超大批量需要算力)时,沿以下设计路径扩展云端服务与模型。**扩展不是默认动作——需要显式配置与授权。**
156
+
157
+ | 扩展点 | 机制 | 状态 |
158
+ |--------|------|------|
159
+ | **远程 worker 后端** | Worker 协议是统一的 JSON Lines over stdio 接口(spec 04),执行后端(docker/subprocess/inproc)是声明式可插拔的——新增 `remote` 后端(SSH/HTTP/云函数)即可把任意解析服务接入降级链,协议与产物规则不变 | 设计预留 |
160
+ | **云端模型路由** | 降级链末端挂 `remote_xxx` 占位:本地链全失败时显性转向云端,产物同样过质量定稿与 fitness 标注 | 设计预留 |
161
+ | **网络声明纪律** | `network=true` 的 worker 必须说明用途;涉密材料默认禁止外发,云端路径需用户显式授权 | 已内置 |
162
+ | **结果回灌一致性** | 云端产物回灌后走同一套锚点派生、哈希、谱系记录——来源是本地还是云端不影响模型与追溯规则 | 已内置 |
163
+
164
+ **云端扩展的隐私边界**:涉及客户秘密、执业秘密的材料,默认不配置云端路径;确需云端的,由用户在材料包级别显式开启,并承担相应合规判断。
165
+
166
+ ## 安装
167
+
168
+ ```bash
169
+ pip install agent-data-gateway # 编排器 + Core(纯 stdlib,零硬依赖)
170
+ adg setup --auto # 一条命令:自动选最快的源 + 装齐免系统依赖的 worker + 预下模型
171
+ ```
172
+
173
+ `adg setup --auto` 做三件事,不需要你懂任何一项:
174
+
175
+ 1. **自动选线路**——并发测速 pypi 官方 / 清华 / 阿里 / 腾讯 / 中科大,选最快的那个(结果缓存 7 天)。
176
+ 直连官方就用官方,不硬塞镜像。显式 `--index-url` 或环境变量 `ADG_PIP_INDEX_URL` 永远优先。
177
+ 2. **只装该装的**——收无系统依赖、体积可接受的 worker;需要 Docker 或数 GB 模型的(docling/mineru/paddleocr/whisper)
178
+ 不进一键档,装完会告诉你它们各自的一行安装命令。准入写在各 `worker.json` 的 `auto_install`,不是代码里的硬编码名单。
179
+ 3. **模型在安装阶段下好**——whisper 等 worker 声明 `network: false`,但模型是首次运行才下载的。
180
+ 预热让那句声明成真;下载走自动选出的镜像(`HF_ENDPOINT`),线路全不通时直接给出 ModelScope 手动路径,
181
+ 而不是让你第一次解析音视频时莫名卡住。
182
+
183
+ 装完会打印一张「本机现在能读什么、还差什么、缺的那个怎么补」的表——**装到什么程度,就诚实报到什么程度**。
184
+
185
+ > **运行前提**:本机有 Python 3.10+(实际部署统一 3.12)并能开终端。这不是待补的门槛——
186
+ > `adg` 的调用者是**开发机上的编码 Agent**(Claude Code、Codex 这类),其宿主本就具备。
187
+ > 单文件可执行(免 Python)与图形界面**已决定不做**,PyInstaller 的实测否决依据见
188
+ > [ADR 0003](docs/adr/0003-distribution-and-target-runtime.md)。
189
+
190
+ 开发模式:`pip install -e .`
191
+
192
+ ## 快速开始
193
+
194
+ ```bash
195
+ adg setup --auto # 一键装齐(自动选源 + 预下模型),不熟命令行就用这个
196
+ adg check # 环境检测:Python/容器/GPU + 各 worker 可用性
197
+ adg routes # 总路由表:格式 → 条件 → 工具 → 原因
198
+ # adg setup --worker whisper # 按需单装重型 worker(音视频转写)
199
+ adg scan ./案件材料 # 全量发现 → manifest(不解析内容)
200
+ adg parse ./案件材料 # 解析(自动特征路由 + 降级)
201
+ adg report ./案件材料 # 包级质量报告
202
+ adg status ./案件材料 # 哪些文件还没被可靠读取
203
+
204
+ adg search ./案件材料 "担保 效力" # 元素级检索(命中带页码/坐标/单元格/时间码锚点)
205
+ adg anchor ./案件材料 el_45f85d56e61a # 把命中回溯到原件位置,确认能不能引用
206
+ adg get ./案件材料 "合同.pdf" # 取出解析产物、质量八维与降级链
207
+
208
+ adg verify # 跑验证矩阵自检
209
+ ```
210
+
211
+ `adg parse` 结束后会顺手建好检索索引(`--no-index` 可关),因此 `search/anchor` 开箱即用。
212
+
213
+ 所有命令 stdout 只打一行摘要,详情写 `<out>/`(默认 `./adg-output/<包名>/`)下的 Markdown/JSON。exit code 三态:`0`=pass / `1`=pass_with_warnings / `2`=fail。
214
+
215
+ ## 与 Agent 的关系
216
+
217
+ ADG 是**给 Agent 用的命令行工具**:Claude Code 等 Agent 经 Bash 调子命令,每个命令加 `--json`
218
+ 就是可直接消费的结构化结果——`adg status` 回答"哪些没读全",`adg search` 检索,`adg anchor` 回溯,
219
+ `adg get` 取产物。全部查询走同一份 `gateway.agent_api` 实现,同一问题不会有两种答案。
220
+
221
+ 三条诚实语义贯穿所有查询:
222
+
223
+ - **检索范围只覆盖已可靠读取的材料**,结果里带 `coverage_caveat` 提示还有几项没读全——"没搜到"不等于"不存在"。
224
+ - **每条命中带 `quotable`**:来自该 rendition 的 `fitness.quotation`。false 表示能检索、能作线索,但锚点不足以可靠引用。
225
+ - **每条命中可回溯**:`resolve_anchor(element_id)` 给出原件路径、parser 与版本、页码/坐标/单元格/时间码及前后文。
226
+
227
+ **由使用者主动调用**:ADG 不往项目里装 skill、不写 `CLAUDE.md` / `AGENTS.md` 片段、不做 MCP server,
228
+ 也不试图让 Agent 自动发现自己。需要用它的人自己让 Agent 去跑 `adg`——工具负责在被调用时给出诚实结果,
229
+ 不负责推销自己([ADR 0003](docs/adr/0003-distribution-and-target-runtime.md) 决策 6)。
230
+
231
+ **但被调用之后必须能被读懂**——被误读的诚实结果不是诚实结果。`adg --help` 因此承载三件事:
232
+ 典型流程顺序、退出码三态(**`1` 是「完成但有未读全项」,不是失败**,而它是常态)、
233
+ 以及检索范围只覆盖已可靠读取的材料。这些承诺由测试与真实退出码绑定,不允许漂移
234
+ ([ADR 0003](docs/adr/0003-distribution-and-target-runtime.md) 决策 7)。
235
+
236
+ ## 目录结构
237
+
238
+ ```
239
+ agent-data-gateway/
240
+ ├── gateway/ # Core 编排器(纯 stdlib):发现/调度/质量/锚点/谱系/CLI
241
+ │ ├── commands/ # adg check/doctor/setup/scan/parse/report/status/list/index/search/anchor/get/routes/verify
242
+ │ ├── index.py # 元素级检索索引(SQLite + FTS5,中文逐字切分)
243
+ │ ├── agent_api.py # 六个只读查询操作的唯一实现(各查询子命令共用)
244
+ │ └── selftest.py # 验证矩阵(程序化 fixtures,无二进制资产)
245
+ ├── packs/legal/ # Legal Pack:11 个 stdlib lite parser + 预检钩子
246
+ ├── workers/ # 22 个外部 worker 适配器(docling/mineru/whisper/anydoc/pdf_render/dwgread/... 各自 venv)
247
+ ├── models/ # 冻结 Schema v0.1(EvidenceDocument/Manifest/WorkerProtocol/Quality/Security)
248
+ ├── docs/spec/ # 12 份规格文档(00-11)
249
+ ├── docs/adr/ # 契约权威、写入所有权、分发形态等架构决策记录
250
+ ├── input/ scratch/ output/ # 三层目录契约
251
+ └── pyproject.toml
252
+ ```
253
+
254
+ ## 设计原则
255
+
256
+ 1. **不自研 parser**——能用成熟开源 parser 解决的格式绝不重写。项目价值在编排层与模型层。
257
+ 2. **失败显性化**——不假装成功。读不了的文件进 `unresolved_items` 并给原因与建议。
258
+ 3. **诚实降级**——lite parser / 兜底产物必须带降级质量标注(如 pdflite:无版面坐标、锚点近似)。
259
+ 4. **范围分三层**——Core + Legal Pack 进主仓库测试矩阵;CAD/GIS/DICOM 等属 Extended Packs,独立扩展。
260
+ 5. **本地最优、云端可扩**——本地能解决的绝不上云;本地无解时沿显式授权路径扩展,产物规则不变。
261
+
262
+ ## 规范文档
263
+
264
+ `docs/spec/` 下 00-11 是权威说明;`models/*.v0.1.json` 是机器可读 Schema(normative,冲突时以 Schema 为准)。
265
+
266
+ 做到哪了、接着做什么,见 [`docs/roadmap.md`](docs/roadmap.md)(含开发环境与几个已知的坑)。
267
+
268
+ 架构决策记录在 `docs/adr/`——**读这个项目(人或 AI)应先看这三份,它们解释了「为什么是这样」**:
269
+
270
+ | ADR | 决定了什么 |
271
+ |---|---|
272
+ | [0001 契约权威与写入所有权](docs/adr/0001-contract-authority-and-write-ownership.md) | 谁拥有哪个事实的定稿权;Schema / spec / README 冲突时以谁为准;同一输出目录单写者 |
273
+ | [0002 资料利用率作为一等目标](docs/adr/0002-utilization-as-first-class-goal.md) | 完整性之外并列利用率;降级链(or)之外增加增益轨(and)。**设计已定稿,实现未开始** |
274
+ | [0003 分发形态与目标运行环境](docs/adr/0003-distribution-and-target-runtime.md) | 面向开发机上的编码 Agent,走 pip / uv tool 分发;冻结打包已实测否决;venv 落 `~/.adg`;不做 Agent 自动发现入口 |
275
+ | [0004 利用率不是一个可计算的比值](docs/adr/0004-utilization-is-not-a-ratio.md) | 撤销利用率度量:分子需要 ground truth,有 ground truth 就不需要这些工具。改输出「探测到什么 + 跑过什么」两组事实,不做除法、不评判结果好坏 |
276
+ | [0005 工作流由 profile 选择](docs/adr/0005-workflow-selection-by-profile.md) | 机制与策略分离(Linux "mechanism, not policy"):ADG 提供识别/路由/执行/记录,跑几条链与哪个结果可用由调用方经 `--profile` 决定。取代 ADR 0002 的「信号缺口驱动」,不新增名词、不加第四种 action |
277
+
278
+ ## 迭代日志
279
+
280
+ > **自动同步约定**:每次迭代(功能新增、缺陷修复、验证结果)完成后,由 Claude 自动在本节追加条目并推送。条目格式:`日期 | 版本 | 类型 | 要点`。历史详情见 `CHANGELOG.md`。
281
+
282
+ | 日期 | 版本 | 类型 | 要点 |
283
+ |------|------|------|------|
284
+ | 2026-08-05 | v0.1.0 | 初始发布 | 编排器核心 + Legal Pack + 14 worker 适配器 + 10 份 spec + 验证矩阵 |
285
+ | 2026-08-05 | v0.1.0 | 修复 | 真实混合数据包健壮性测试后:①单文件包 scan+parse 路径还原(P1-1)②dwgbmp 位置参数与无缩略图提示(P1-2)③降级链失败原因逐级聚合输出(P2-1)④PSD 魔数识别 ⑤detected_type/mtime 落盘(渲染物类型显示)⑥scan 阶段状态与 exit code 语义对齐 ⑦verify L3 alignment 路径修正 ⑧产物路径 scrub 覆盖 /private/tmp 与 /var/folders(隐私回归) |
286
+ | 2026-08-05 | v0.1.0 | 验证 | `adg verify` 17/19 → 20/21(含新增回归用例:单文件包、失败链聚合);input 混合包未解决项 5→4,PSD 从"类型无法识别"转为"已解析 pass" |
287
+ | 2026-08-22 | v0.2.0 | 安全/一致性修复 | Worker 协议与产物路径严格录取;Manifest/Evidence Schema+哈希+身份读取校验;单写者锁、陈旧写入检测与孤儿 rendition 恢复;locator、图片 fitness、force 刷新、质量缓存、derived_from 和 wheel Worker 打包修复;源码 87 项测试、真实材料包与独立安装验证通过 |
288
+ | 2026-08-23 | v0.2.0 | 缺陷/校准 | officecli 适配器实测校准:补 `--json`、按 `{success,data.results}` 解析、正文改段落级锚点、批注/修订经 anchoredTo 挂回段落;**查询失败不再退化成「0 条」而是显性失败**。同时修正 docx fixture 为合规 OOXML(此前缺 `document.xml.rels` 与 Content_Types 声明,Word 与任何规范实现都读不到那条批注,验证矩阵在测一个假场景)。L3 跨 parser 对齐首次真实通过:916 元素配对 score=1.0 |
289
+ | 2026-08-23 | v0.2.0 | 能力/缺陷 | DWG 改为 dwgread 直读(dwg2dxf 中转的 DXF 结构性损坏,ezdxf.recover 亦拒绝加载),真实图纸提出 9777 条文字并带图层/句柄锚点;修复所有 adapter 用 UTF-8 硬解子进程输出(中文工具输出 GBK 一个字节即崩)。覆盖率 95.1%→**97.6%**,仅剩 CAJ 一项 |
290
+ | 2026-08-23 | v0.2.0 | 设计决策 | 增益轨的触发方式改为 profile 驱动(ADR 0005 取代 ADR 0002 决策 2 的缺口驱动):`parse` 从「跑一条链到成功」扩展为「按 `--profile fast\|balanced\|quality` 跑 N 条链」,链内仍 `or`、链间可选 `and`,各自产出独立 rendition。不新增「工作流」名词(链本身就是),不加第四种 action,去掉「信号↔能力」映射——净变化是减少。机制与策略分离:ADG 不拥有「哪个结果更好」,链的优先级来自开发期离线评估,运行时不评判 |
291
+ | 2026-08-23 | v0.2.0 | 设计修正 | 撤销「资料利用率」作为比值度量(ADR 0004 修订 ADR 0002 决策 1):分子「已成功提取的信号数」需要 ground truth,而有 ground truth 就不必调用这些解析工具——原理上不可知,实现到接分子时暴露。改为输出「探测到哪些信号(三态)+ 实际跑过哪些工具」两组并列事实,不做除法、不合成评分,哪个结果好由调用方判断。增益轨方向不变,被推翻的只是给它打分的尺子 |
292
+ | 2026-08-23 | v0.2.0 | 设计决策 | 确立分发形态与目标运行环境:调用者是开发机上的编码 Agent,分发走 `pip`/`uv tool`,不做 `.app`/图形界面/代码签名。PyInstaller 冻结**实测否决**——能打出 20MB 单文件并发现 36 个 worker,但冻结二进制无 `venv`/`ensurepip` 装不了三方包,且 onefile 每次解包到新临时目录、装了下次即失。worker venv 落点随之移出 `site-packages`,改由 `ADG_HOME`(默认 `~/.adg`)承载。ADR 0003 |
293
+ | 2026-08-22 | v0.2.0 | 能力/缺陷 | 加密 PDF 先试空用户口令(多数只是所有者限制,此前一律谎报"需密码");扫描 PDF 新增 pdf_render 本地位图链(无需 Docker/GPU);接入 anydoc(Rust/MIT)补齐 RTF/EPUB/ODS/ODP 等格式;CAJ 从"类型无法识别"升级为带建议的显性未解决;修复"内容经派生物提取却报没读到"的核心误报。真实包覆盖率 88.6%→95.1% |
294
+ | 2026-08-22 | v0.2.0 | 设计决策 | 确立「资料利用率」为一等目标:降级链(or 语义)之外增加增益轨(and 语义),多视角并行提取;分母靠廉价信号探测而非估计;多轨分歧只记录不裁决;成本靠探测门控/页级增益/身份缓存/条件升级/预算调度五机制,`--profile fast\|balanced\|quality` 是其上的界面。ADR 0002 + spec 11,实现未开始 |
295
+ | 2026-08-22 | v0.2.0 | Agent 接口(P5) | 元素级检索索引(SQLite/FTS5,中文逐字切分,新鲜度指纹增量复用)+ `adg index/search/anchor/get`:命中带来源锚点、`quotable` 与未读全提示;查询逻辑单一权威(`gateway.agent_api`);`adg verify` 20/22 → 25/27;新增 24 项测试 |
296
+ | 2026-08-22 | v0.2.0 | 安装体验 | `adg setup` 支持 `--index-url`/`ADG_PIP_INDEX_URL` 国内镜像(不污染全局 pip 配置);whisper 模型 ModelScope 国内路径指引 + `--worker-option model=` 本地注入;`.gitignore` 忽略 worker 本地模型权重;真实材料包补装 5 个 worker 后覆盖率 34.3%→88.6% |
297
+
298
+ ## 许可证
299
+
300
+ Apache-2.0。注意:部分 worker 适配器调用的工具是 GPL/AGPL(extract-msg、LibreDWG、MinerU)——它们隔离为独立进程调用,不链入编排器,详见各 `workers/*/worker.json` 的 `license` 字段。
@@ -0,0 +1,275 @@
1
+ # Agent Data Gateway
2
+
3
+ <p align="center">
4
+ <a href="https://github.com/CSlawyer1985/agent-data-gateway/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-Apache%202.0-blue.svg" alt="License"></a>
5
+ <a href="https://github.com/CSlawyer1985/agent-data-gateway"><img src="https://img.shields.io/badge/version-v0.2.0-brightgreen" alt="Version"></a>
6
+ <a href="https://github.com/CSlawyer1985/agent-data-gateway"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs Welcome"></a>
7
+ <br>
8
+ <b>让 Agent 获得可信、完整、可追溯的数据输入</b>
9
+ <br>
10
+ <b>摄取编排层(Agent Ingestion),不是又一个 Document Parser</b>
11
+ <br>
12
+ 合同 · 证据 · 判决书 · 财务表 · 聊天记录 · 邮件 · 音视频 · 图纸 · 压缩包
13
+ </p>
14
+
15
+ ---
16
+
17
+ > **新用户?** 从 [快速开始](#快速开始) 开始——三个命令跑通一个材料包。本文是完整参考手册。
18
+ >
19
+ > **核心承诺:不假装成功。** 读不了的文件进 `unresolved_items` 并给出原因与建议;本地解决不了的问题显性失败,绝不静默降质。
20
+
21
+ ---
22
+
23
+ ## 为什么做
24
+
25
+ 律师、文字工作者的真实输入是一个格式极杂的数据包:PDF 扫描件、带批注修订的 docx、财务表、聊天记录、邮件及附件、音视频、工程图纸……
26
+
27
+ 当前 Agent 最大的问题不是不会分析,而是**无法可靠地知道自己是否已完整读取全部材料**:
28
+
29
+ | 现实问题 | 后果 |
30
+ |---------|------|
31
+ | 文件遗漏(压缩包未展开、附件未拆出) | 分析建立在残缺事实上 |
32
+ | OCR 未执行(扫描件当成空文件) | "无文字层"被误读为"无内容" |
33
+ | 表格读取失败(多工作表、合并单元格) | 关键数字缺失无人知晓 |
34
+ | 解析失败被静默跳过 | 无法区分"读全了"与"读不了" |
35
+ | 来源无法回溯 | 引用时找不到原文位置 |
36
+ | 解析器悄悄换成了低质量兜底 | 报告看起来正常,实际不可引用 |
37
+
38
+ 开源生态(MinerU / Docling / Tika / Whisper / PaddleOCR 等)解决的是 **Document Parsing**——怎么把一个文件解析出来。本工具做 **Agent Ingestion**——怎么把一个案件材料包**可靠地**变成 Agent 可消费、可追溯、可信的数据。
39
+
40
+ ## 当前状态(v0.2.0)
41
+
42
+ | 维度 | 状态 |
43
+ |------|------|
44
+ | **版本** | v0.2.0(2026-08-23);v0.1.0 于 2026-08-05 首次发布 |
45
+ | **编排器核心** | ✅ 完整可用:发现/安全展开/类型识别/特征路由/调度/质量/锚点/谱系/渲染,纯 stdlib |
46
+ | **Legal Pack** | ✅ 11 个 lite parser + 预检钩子已注册 |
47
+ | **外部 worker** | ✅ 22 个适配器随 wheel 发布(含 anydoc / pdf_render / dwgread),按环境安装;可用性以本机 `adg check` 为准 |
48
+ | **Agent 接口** | ✅ 元素级检索索引 + `adg index/search/anchor/get`:命中带来源锚点与可引用标注,纯 stdlib |
49
+ | **验证矩阵** | ✅ `adg verify` 27/28 通过、0 失败(1 跳过为环境依赖项);跨 parser 对齐(L3)已用真实材料验证 |
50
+ | **真实数据验证** | ✅ input 混合材料包(23 物理文件 → 展开/派生后 41 items):全量入账、覆盖率 **97.6%**、仅剩 1 项未解决(CAJ 属知网专有格式,无开源解析器),带原因与可执行建议 |
51
+ | **资料利用率** | 📋 设计已定稿未实现:增益轨(多视角并行)+ 信号探测度量 + 快速/均衡/质量三档成本控制([ADR 0002](docs/adr/0002-utilization-as-first-class-goal.md) / [spec 11](docs/spec/11-utilization.md)) |
52
+ | **云端扩展** | 📋 设计预留(远程 worker 后端、云端模型路由),未实现 |
53
+ | **Extended Packs** | 📋 规划(CAD 深入/GIS/DICOM 等),未发布 |
54
+
55
+ 已知限制与已知问题见下方「迭代日志」最新条目;全部规格以 `docs/spec/` 与 `models/*.v0.1.json` 为准。
56
+
57
+ ## 目标
58
+
59
+ 1. **完整入账**:包内每个文件都有 item 记录或显式排除记录(`all_items_accounted`),"读全了"是可验证的事实而非感觉。
60
+ 2. **失败显性化**:任何文件未能可靠读取,必须带着阶段、原因、建议出现在清单里——Agent 和律师都知道"哪里还没读全"。
61
+ 3. **诚实降级**:解析器沿降级链回退时,产物必须携带质量标注(如 `layout=fail`、`quotation=False`),让下游知道"这份内容能检索、但不能可靠引用"。
62
+ 4. **提高资料利用率**(设计中):同一份材料用多个工具从多个角度处理——文字视角、视觉视角、容器视角、密码学视角——把"一个工具只利用了 60%"提到尽可能高,并如实报告还有多少信号没提取。见 [spec 11](docs/spec/11-utilization.md)。
63
+ 5. **本地最优**:默认全链路本地处理,客户材料、律师执业秘密不出本机。
64
+ 6. **云端可扩**:本地无解时(无 GPU、缺重型模型、格式无本地 parser),沿显式授权路径扩展云端服务与模型,产物与来源标注规则不变。
65
+ 7. **摄取 ≠ 取证**:提取技术信号(EXIF、哈希、电子签章线索),但真伪鉴定恒为 `false`,标注"需人工/鉴定复核"。
66
+
67
+ ## 实现方法
68
+
69
+ ### 架构总览
70
+
71
+ ```
72
+ 原始材料包(不可信输入)
73
+
74
+
75
+ ┌─────────────────────────────────────────────────┐
76
+ │ ADG 编排器(gateway/,纯 stdlib) │
77
+ │ 发现 → 安全展开 → 类型识别 → 特征路由 → 调度 │
78
+ │ → 质量定稿 → 锚点派生 → 谱系记录 → 渲染输出 │
79
+ │ │
80
+ │ ├─ Worker 协议:JSON Lines over stdio(spec 04) │
81
+ │ ├─ 降级链:特征路由 + 诚实回退(spec 08) │
82
+ │ ├─ 安全模型:ZIP bomb / 路径穿越 / 符号链接 / │
83
+ │ │ 宏 / PDF JS / 资源耗尽(spec 06) │
84
+ │ └─ 隐私:产物只含包内相对路径(spec 09) │
85
+ └─────────────────────────────────────────────────┘
86
+
87
+
88
+ EvidenceDocument(统一模型,spec 02)
89
+ 三身份 source/rendition/run + 八维质量 + fitness + 锚点 + 谱系
90
+ ```
91
+
92
+ ### 核心机制
93
+
94
+ | 机制 | 实现 | 解决的问题 |
95
+ |------|------|-----------|
96
+ | **完整入账** | 递归发现 + 压缩包/邮件安全展开,每文件必有 item 或排除记录 | 文件遗漏无人知晓 |
97
+ | **不可信输入安全模型** | ZIP bomb / 路径穿越 / 符号链接逃逸 / 宏 / PDF JavaScript / worker 资源耗尽,第一版即内置,拦截显性记录 | 恶意或损坏材料击穿管线 |
98
+ | **三身份模型** | `source_id`(原件,跨 parser 稳定)/ `rendition_id`(解析产物)/ `run_id`(执行) | parser 升级后结果对比与追溯 |
99
+ | **特征路由 + 降级链** | `gateway.routing.ROUTE_RULES` 同时驱动调度与 `adg routes` 总表;按文档特征选最优 parser,不可用沿链回退并记录每级失败原因 | 拿最优工具处理最优场景,失败原因可诊断,文档不与实现漂移 |
100
+ | **质量多维化** | 八维质量(发现/类型/文本/版面/OCR/附件/元数据/锚定)+ fitness 五旗标(可检索/可提取/可引用/版面敏感/真伪鉴定) | 一份文件"能检索 ≠ 能引用"如实区分 |
101
+ | **来源锚点** | 元素级定位:页码/坐标/表格单元/时间码/字段,引用可回溯原件 | 结论无法定位到证据位置 |
102
+ | **处理谱系** | 每次解析记录 operation/tool/exit_code/哈希,链式可查 | 产物来源与处理历史不可追溯 |
103
+ | **隐私保护** | 产物默认只含包内相对路径,绝对路径只在本地私有日志;输出前 scrub 兜底清洗 | 客户名、目录结构、磁盘位置不泄露 |
104
+ | **检索与回溯** | 元素级 SQLite/FTS5 索引(中文逐字切分)+ `adg anchor` 回溯;命中带 `quotable` 标注 | Agent 查得到、引得回,且知道哪句不能引 |
105
+
106
+ ## 格式范围与总路由表
107
+
108
+ 项目不再在 README 里手工复制一份容易过期的 worker 链。实际调度和总表共用 `gateway.routing.ROUTE_RULES`:
109
+
110
+ ```bash
111
+ adg routes # 全部:扩展名、触发条件、动作、工具链、选择原因
112
+ adg routes --kind pdf # 查看 PDF 的加密/损坏/扫描/混合/数字分流
113
+ adg routes --format .msg --json # 查看单个格式,或让 Agent 读取 JSON
114
+ adg check # 验证这些 worker 在当前机器是否真的可用
115
+ ```
116
+
117
+ 总表会区分 `parse`(内容解析)、`expand`(容器安全展开)和 `unresolved`(可识别但当前没有安全处理路径)。因此“识别到 `.rar`”不会被误报为“已经支持解析”;未知格式也不会猜测工具后假装成功。完整语义见 [路由策略](docs/spec/08-routing.md)。
118
+
119
+ ## 本地最优:数据不出本机
120
+
121
+ 律师材料的默认边界:**客户秘密与执业秘密在本地闭环内处理**。
122
+
123
+ - **worker 隔离**:重/异构解析走独立 venv 或 docker 容器(只读挂载原件、`network=none`、资源限额),不链入编排器;GPL 组件(extract-msg、LibreDWG、MinerU)以独立进程调用,规避许可证传染。
124
+ - **隐私三规则**(spec 09):产物只出现包内相对路径;绝对路径只进本地私有日志(可 `--no-abs-log` 关闭);输出前兜底 scrub。
125
+ - **无暗网行为**:worker 默认 `network=false` 禁止外联;需要网络的 enrich 类 worker 必须显式声明并说明用途。
126
+ - **本地能力自查**:`adg check` 一键列出本机 25+ worker 可用性,`adg doctor` 按实际材料诊断缺口,`adg setup` 一键补装。
127
+
128
+ ## 云端扩展:本地无路径时
129
+
130
+ 本地没有解析路径(无 GPU 跑不了重型模型、缺特定依赖、格式无本地 parser、或超大批量需要算力)时,沿以下设计路径扩展云端服务与模型。**扩展不是默认动作——需要显式配置与授权。**
131
+
132
+ | 扩展点 | 机制 | 状态 |
133
+ |--------|------|------|
134
+ | **远程 worker 后端** | Worker 协议是统一的 JSON Lines over stdio 接口(spec 04),执行后端(docker/subprocess/inproc)是声明式可插拔的——新增 `remote` 后端(SSH/HTTP/云函数)即可把任意解析服务接入降级链,协议与产物规则不变 | 设计预留 |
135
+ | **云端模型路由** | 降级链末端挂 `remote_xxx` 占位:本地链全失败时显性转向云端,产物同样过质量定稿与 fitness 标注 | 设计预留 |
136
+ | **网络声明纪律** | `network=true` 的 worker 必须说明用途;涉密材料默认禁止外发,云端路径需用户显式授权 | 已内置 |
137
+ | **结果回灌一致性** | 云端产物回灌后走同一套锚点派生、哈希、谱系记录——来源是本地还是云端不影响模型与追溯规则 | 已内置 |
138
+
139
+ **云端扩展的隐私边界**:涉及客户秘密、执业秘密的材料,默认不配置云端路径;确需云端的,由用户在材料包级别显式开启,并承担相应合规判断。
140
+
141
+ ## 安装
142
+
143
+ ```bash
144
+ pip install agent-data-gateway # 编排器 + Core(纯 stdlib,零硬依赖)
145
+ adg setup --auto # 一条命令:自动选最快的源 + 装齐免系统依赖的 worker + 预下模型
146
+ ```
147
+
148
+ `adg setup --auto` 做三件事,不需要你懂任何一项:
149
+
150
+ 1. **自动选线路**——并发测速 pypi 官方 / 清华 / 阿里 / 腾讯 / 中科大,选最快的那个(结果缓存 7 天)。
151
+ 直连官方就用官方,不硬塞镜像。显式 `--index-url` 或环境变量 `ADG_PIP_INDEX_URL` 永远优先。
152
+ 2. **只装该装的**——收无系统依赖、体积可接受的 worker;需要 Docker 或数 GB 模型的(docling/mineru/paddleocr/whisper)
153
+ 不进一键档,装完会告诉你它们各自的一行安装命令。准入写在各 `worker.json` 的 `auto_install`,不是代码里的硬编码名单。
154
+ 3. **模型在安装阶段下好**——whisper 等 worker 声明 `network: false`,但模型是首次运行才下载的。
155
+ 预热让那句声明成真;下载走自动选出的镜像(`HF_ENDPOINT`),线路全不通时直接给出 ModelScope 手动路径,
156
+ 而不是让你第一次解析音视频时莫名卡住。
157
+
158
+ 装完会打印一张「本机现在能读什么、还差什么、缺的那个怎么补」的表——**装到什么程度,就诚实报到什么程度**。
159
+
160
+ > **运行前提**:本机有 Python 3.10+(实际部署统一 3.12)并能开终端。这不是待补的门槛——
161
+ > `adg` 的调用者是**开发机上的编码 Agent**(Claude Code、Codex 这类),其宿主本就具备。
162
+ > 单文件可执行(免 Python)与图形界面**已决定不做**,PyInstaller 的实测否决依据见
163
+ > [ADR 0003](docs/adr/0003-distribution-and-target-runtime.md)。
164
+
165
+ 开发模式:`pip install -e .`
166
+
167
+ ## 快速开始
168
+
169
+ ```bash
170
+ adg setup --auto # 一键装齐(自动选源 + 预下模型),不熟命令行就用这个
171
+ adg check # 环境检测:Python/容器/GPU + 各 worker 可用性
172
+ adg routes # 总路由表:格式 → 条件 → 工具 → 原因
173
+ # adg setup --worker whisper # 按需单装重型 worker(音视频转写)
174
+ adg scan ./案件材料 # 全量发现 → manifest(不解析内容)
175
+ adg parse ./案件材料 # 解析(自动特征路由 + 降级)
176
+ adg report ./案件材料 # 包级质量报告
177
+ adg status ./案件材料 # 哪些文件还没被可靠读取
178
+
179
+ adg search ./案件材料 "担保 效力" # 元素级检索(命中带页码/坐标/单元格/时间码锚点)
180
+ adg anchor ./案件材料 el_45f85d56e61a # 把命中回溯到原件位置,确认能不能引用
181
+ adg get ./案件材料 "合同.pdf" # 取出解析产物、质量八维与降级链
182
+
183
+ adg verify # 跑验证矩阵自检
184
+ ```
185
+
186
+ `adg parse` 结束后会顺手建好检索索引(`--no-index` 可关),因此 `search/anchor` 开箱即用。
187
+
188
+ 所有命令 stdout 只打一行摘要,详情写 `<out>/`(默认 `./adg-output/<包名>/`)下的 Markdown/JSON。exit code 三态:`0`=pass / `1`=pass_with_warnings / `2`=fail。
189
+
190
+ ## 与 Agent 的关系
191
+
192
+ ADG 是**给 Agent 用的命令行工具**:Claude Code 等 Agent 经 Bash 调子命令,每个命令加 `--json`
193
+ 就是可直接消费的结构化结果——`adg status` 回答"哪些没读全",`adg search` 检索,`adg anchor` 回溯,
194
+ `adg get` 取产物。全部查询走同一份 `gateway.agent_api` 实现,同一问题不会有两种答案。
195
+
196
+ 三条诚实语义贯穿所有查询:
197
+
198
+ - **检索范围只覆盖已可靠读取的材料**,结果里带 `coverage_caveat` 提示还有几项没读全——"没搜到"不等于"不存在"。
199
+ - **每条命中带 `quotable`**:来自该 rendition 的 `fitness.quotation`。false 表示能检索、能作线索,但锚点不足以可靠引用。
200
+ - **每条命中可回溯**:`resolve_anchor(element_id)` 给出原件路径、parser 与版本、页码/坐标/单元格/时间码及前后文。
201
+
202
+ **由使用者主动调用**:ADG 不往项目里装 skill、不写 `CLAUDE.md` / `AGENTS.md` 片段、不做 MCP server,
203
+ 也不试图让 Agent 自动发现自己。需要用它的人自己让 Agent 去跑 `adg`——工具负责在被调用时给出诚实结果,
204
+ 不负责推销自己([ADR 0003](docs/adr/0003-distribution-and-target-runtime.md) 决策 6)。
205
+
206
+ **但被调用之后必须能被读懂**——被误读的诚实结果不是诚实结果。`adg --help` 因此承载三件事:
207
+ 典型流程顺序、退出码三态(**`1` 是「完成但有未读全项」,不是失败**,而它是常态)、
208
+ 以及检索范围只覆盖已可靠读取的材料。这些承诺由测试与真实退出码绑定,不允许漂移
209
+ ([ADR 0003](docs/adr/0003-distribution-and-target-runtime.md) 决策 7)。
210
+
211
+ ## 目录结构
212
+
213
+ ```
214
+ agent-data-gateway/
215
+ ├── gateway/ # Core 编排器(纯 stdlib):发现/调度/质量/锚点/谱系/CLI
216
+ │ ├── commands/ # adg check/doctor/setup/scan/parse/report/status/list/index/search/anchor/get/routes/verify
217
+ │ ├── index.py # 元素级检索索引(SQLite + FTS5,中文逐字切分)
218
+ │ ├── agent_api.py # 六个只读查询操作的唯一实现(各查询子命令共用)
219
+ │ └── selftest.py # 验证矩阵(程序化 fixtures,无二进制资产)
220
+ ├── packs/legal/ # Legal Pack:11 个 stdlib lite parser + 预检钩子
221
+ ├── workers/ # 22 个外部 worker 适配器(docling/mineru/whisper/anydoc/pdf_render/dwgread/... 各自 venv)
222
+ ├── models/ # 冻结 Schema v0.1(EvidenceDocument/Manifest/WorkerProtocol/Quality/Security)
223
+ ├── docs/spec/ # 12 份规格文档(00-11)
224
+ ├── docs/adr/ # 契约权威、写入所有权、分发形态等架构决策记录
225
+ ├── input/ scratch/ output/ # 三层目录契约
226
+ └── pyproject.toml
227
+ ```
228
+
229
+ ## 设计原则
230
+
231
+ 1. **不自研 parser**——能用成熟开源 parser 解决的格式绝不重写。项目价值在编排层与模型层。
232
+ 2. **失败显性化**——不假装成功。读不了的文件进 `unresolved_items` 并给原因与建议。
233
+ 3. **诚实降级**——lite parser / 兜底产物必须带降级质量标注(如 pdflite:无版面坐标、锚点近似)。
234
+ 4. **范围分三层**——Core + Legal Pack 进主仓库测试矩阵;CAD/GIS/DICOM 等属 Extended Packs,独立扩展。
235
+ 5. **本地最优、云端可扩**——本地能解决的绝不上云;本地无解时沿显式授权路径扩展,产物规则不变。
236
+
237
+ ## 规范文档
238
+
239
+ `docs/spec/` 下 00-11 是权威说明;`models/*.v0.1.json` 是机器可读 Schema(normative,冲突时以 Schema 为准)。
240
+
241
+ 做到哪了、接着做什么,见 [`docs/roadmap.md`](docs/roadmap.md)(含开发环境与几个已知的坑)。
242
+
243
+ 架构决策记录在 `docs/adr/`——**读这个项目(人或 AI)应先看这三份,它们解释了「为什么是这样」**:
244
+
245
+ | ADR | 决定了什么 |
246
+ |---|---|
247
+ | [0001 契约权威与写入所有权](docs/adr/0001-contract-authority-and-write-ownership.md) | 谁拥有哪个事实的定稿权;Schema / spec / README 冲突时以谁为准;同一输出目录单写者 |
248
+ | [0002 资料利用率作为一等目标](docs/adr/0002-utilization-as-first-class-goal.md) | 完整性之外并列利用率;降级链(or)之外增加增益轨(and)。**设计已定稿,实现未开始** |
249
+ | [0003 分发形态与目标运行环境](docs/adr/0003-distribution-and-target-runtime.md) | 面向开发机上的编码 Agent,走 pip / uv tool 分发;冻结打包已实测否决;venv 落 `~/.adg`;不做 Agent 自动发现入口 |
250
+ | [0004 利用率不是一个可计算的比值](docs/adr/0004-utilization-is-not-a-ratio.md) | 撤销利用率度量:分子需要 ground truth,有 ground truth 就不需要这些工具。改输出「探测到什么 + 跑过什么」两组事实,不做除法、不评判结果好坏 |
251
+ | [0005 工作流由 profile 选择](docs/adr/0005-workflow-selection-by-profile.md) | 机制与策略分离(Linux "mechanism, not policy"):ADG 提供识别/路由/执行/记录,跑几条链与哪个结果可用由调用方经 `--profile` 决定。取代 ADR 0002 的「信号缺口驱动」,不新增名词、不加第四种 action |
252
+
253
+ ## 迭代日志
254
+
255
+ > **自动同步约定**:每次迭代(功能新增、缺陷修复、验证结果)完成后,由 Claude 自动在本节追加条目并推送。条目格式:`日期 | 版本 | 类型 | 要点`。历史详情见 `CHANGELOG.md`。
256
+
257
+ | 日期 | 版本 | 类型 | 要点 |
258
+ |------|------|------|------|
259
+ | 2026-08-05 | v0.1.0 | 初始发布 | 编排器核心 + Legal Pack + 14 worker 适配器 + 10 份 spec + 验证矩阵 |
260
+ | 2026-08-05 | v0.1.0 | 修复 | 真实混合数据包健壮性测试后:①单文件包 scan+parse 路径还原(P1-1)②dwgbmp 位置参数与无缩略图提示(P1-2)③降级链失败原因逐级聚合输出(P2-1)④PSD 魔数识别 ⑤detected_type/mtime 落盘(渲染物类型显示)⑥scan 阶段状态与 exit code 语义对齐 ⑦verify L3 alignment 路径修正 ⑧产物路径 scrub 覆盖 /private/tmp 与 /var/folders(隐私回归) |
261
+ | 2026-08-05 | v0.1.0 | 验证 | `adg verify` 17/19 → 20/21(含新增回归用例:单文件包、失败链聚合);input 混合包未解决项 5→4,PSD 从"类型无法识别"转为"已解析 pass" |
262
+ | 2026-08-22 | v0.2.0 | 安全/一致性修复 | Worker 协议与产物路径严格录取;Manifest/Evidence Schema+哈希+身份读取校验;单写者锁、陈旧写入检测与孤儿 rendition 恢复;locator、图片 fitness、force 刷新、质量缓存、derived_from 和 wheel Worker 打包修复;源码 87 项测试、真实材料包与独立安装验证通过 |
263
+ | 2026-08-23 | v0.2.0 | 缺陷/校准 | officecli 适配器实测校准:补 `--json`、按 `{success,data.results}` 解析、正文改段落级锚点、批注/修订经 anchoredTo 挂回段落;**查询失败不再退化成「0 条」而是显性失败**。同时修正 docx fixture 为合规 OOXML(此前缺 `document.xml.rels` 与 Content_Types 声明,Word 与任何规范实现都读不到那条批注,验证矩阵在测一个假场景)。L3 跨 parser 对齐首次真实通过:916 元素配对 score=1.0 |
264
+ | 2026-08-23 | v0.2.0 | 能力/缺陷 | DWG 改为 dwgread 直读(dwg2dxf 中转的 DXF 结构性损坏,ezdxf.recover 亦拒绝加载),真实图纸提出 9777 条文字并带图层/句柄锚点;修复所有 adapter 用 UTF-8 硬解子进程输出(中文工具输出 GBK 一个字节即崩)。覆盖率 95.1%→**97.6%**,仅剩 CAJ 一项 |
265
+ | 2026-08-23 | v0.2.0 | 设计决策 | 增益轨的触发方式改为 profile 驱动(ADR 0005 取代 ADR 0002 决策 2 的缺口驱动):`parse` 从「跑一条链到成功」扩展为「按 `--profile fast\|balanced\|quality` 跑 N 条链」,链内仍 `or`、链间可选 `and`,各自产出独立 rendition。不新增「工作流」名词(链本身就是),不加第四种 action,去掉「信号↔能力」映射——净变化是减少。机制与策略分离:ADG 不拥有「哪个结果更好」,链的优先级来自开发期离线评估,运行时不评判 |
266
+ | 2026-08-23 | v0.2.0 | 设计修正 | 撤销「资料利用率」作为比值度量(ADR 0004 修订 ADR 0002 决策 1):分子「已成功提取的信号数」需要 ground truth,而有 ground truth 就不必调用这些解析工具——原理上不可知,实现到接分子时暴露。改为输出「探测到哪些信号(三态)+ 实际跑过哪些工具」两组并列事实,不做除法、不合成评分,哪个结果好由调用方判断。增益轨方向不变,被推翻的只是给它打分的尺子 |
267
+ | 2026-08-23 | v0.2.0 | 设计决策 | 确立分发形态与目标运行环境:调用者是开发机上的编码 Agent,分发走 `pip`/`uv tool`,不做 `.app`/图形界面/代码签名。PyInstaller 冻结**实测否决**——能打出 20MB 单文件并发现 36 个 worker,但冻结二进制无 `venv`/`ensurepip` 装不了三方包,且 onefile 每次解包到新临时目录、装了下次即失。worker venv 落点随之移出 `site-packages`,改由 `ADG_HOME`(默认 `~/.adg`)承载。ADR 0003 |
268
+ | 2026-08-22 | v0.2.0 | 能力/缺陷 | 加密 PDF 先试空用户口令(多数只是所有者限制,此前一律谎报"需密码");扫描 PDF 新增 pdf_render 本地位图链(无需 Docker/GPU);接入 anydoc(Rust/MIT)补齐 RTF/EPUB/ODS/ODP 等格式;CAJ 从"类型无法识别"升级为带建议的显性未解决;修复"内容经派生物提取却报没读到"的核心误报。真实包覆盖率 88.6%→95.1% |
269
+ | 2026-08-22 | v0.2.0 | 设计决策 | 确立「资料利用率」为一等目标:降级链(or 语义)之外增加增益轨(and 语义),多视角并行提取;分母靠廉价信号探测而非估计;多轨分歧只记录不裁决;成本靠探测门控/页级增益/身份缓存/条件升级/预算调度五机制,`--profile fast\|balanced\|quality` 是其上的界面。ADR 0002 + spec 11,实现未开始 |
270
+ | 2026-08-22 | v0.2.0 | Agent 接口(P5) | 元素级检索索引(SQLite/FTS5,中文逐字切分,新鲜度指纹增量复用)+ `adg index/search/anchor/get`:命中带来源锚点、`quotable` 与未读全提示;查询逻辑单一权威(`gateway.agent_api`);`adg verify` 20/22 → 25/27;新增 24 项测试 |
271
+ | 2026-08-22 | v0.2.0 | 安装体验 | `adg setup` 支持 `--index-url`/`ADG_PIP_INDEX_URL` 国内镜像(不污染全局 pip 配置);whisper 模型 ModelScope 国内路径指引 + `--worker-option model=` 本地注入;`.gitignore` 忽略 worker 本地模型权重;真实材料包补装 5 个 worker 后覆盖率 34.3%→88.6% |
272
+
273
+ ## 许可证
274
+
275
+ Apache-2.0。注意:部分 worker 适配器调用的工具是 GPL/AGPL(extract-msg、LibreDWG、MinerU)——它们隔离为独立进程调用,不链入编排器,详见各 `workers/*/worker.json` 的 `license` 字段。