semantic-tool-registry 7.0.1__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.
@@ -0,0 +1,27 @@
1
+ # Python 字节码缓存
2
+ __pycache__/
3
+ *.py[cod]
4
+
5
+ # 虚拟环境
6
+ .venv/
7
+
8
+ # 构建产物
9
+ dist/
10
+ build/
11
+ *.egg-info/
12
+
13
+ # 运行时数据(可再生成:模型下载 / ONNX 导出 / 索引重建)
14
+ data/
15
+
16
+ # 评测输出与临时数据
17
+ eval_results/
18
+ eval_results_large/
19
+ eval_data_*/
20
+ _large_data_*/
21
+
22
+ # 生成的测试数据(gen_test_data.py 产物,按需生成)
23
+ scripts/large_test_data.py
24
+
25
+ # 日志与临时文件
26
+ *.log
27
+ *.bak
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 cc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,403 @@
1
+ Metadata-Version: 2.5
2
+ Name: semantic-tool-registry
3
+ Version: 7.0.1
4
+ Summary: 语义注册表基底 + 领域子类(工具域 / 文档域):向量与全文双检索、R1/R2 精准锚定、录入去重、CRUD、领域存储扩展(指定数据库 / 指定表 / 扩展字段,初始化期定型,注册查询自动适配)
5
+ Author-email: cc <3204624858@qq.com>
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Keywords: document-registry,embedding,full-text-search,llm-tools,rag,reranker,retrieval,semantic-registry,tool-registry,vector-search
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Natural Language :: Chinese (Simplified)
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Classifier: Topic :: Text Processing :: Indexing
16
+ Requires-Python: <3.13,>=3.12
17
+ Requires-Dist: jieba>=0.42.1
18
+ Requires-Dist: numpy>=1.23
19
+ Requires-Dist: sentence-transformers>=5.6.1
20
+ Requires-Dist: torch>=2.0.0
21
+ Requires-Dist: transformers<5.0.0,>=4.50.0
22
+ Requires-Dist: zvec>=0.6.0
23
+ Provides-Extra: dev
24
+ Requires-Dist: black>=23.0.0; extra == 'dev'
25
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
26
+ Provides-Extra: download-cn
27
+ Requires-Dist: modelscope>=1.15.0; extra == 'download-cn'
28
+ Provides-Extra: onnx
29
+ Requires-Dist: onnxruntime>=1.17.0; extra == 'onnx'
30
+ Provides-Extra: onnx-export
31
+ Requires-Dist: onnx>=1.16.0; extra == 'onnx-export'
32
+ Requires-Dist: onnxscript>=0.7.0; extra == 'onnx-export'
33
+ Provides-Extra: onnx-gpu
34
+ Requires-Dist: onnxruntime-gpu>=1.17.0; extra == 'onnx-gpu'
35
+ Provides-Extra: yaml
36
+ Requires-Dist: pyyaml>=6.0; extra == 'yaml'
37
+ Description-Content-Type: text/markdown
38
+
39
+ # semantic-tool-registry
40
+
41
+ 面向 LLM / Agent 的**语义注册表**:把「工具」和「文档」登记成可被自然语言精准检索的条目。
42
+
43
+ 同一个引擎提供两个开箱即用的领域:
44
+
45
+ | 领域 | 用途 | 领域词汇 |
46
+ |---|---|---|
47
+ | 工具域 `ToolAgent` | 工具 / 函数 / API 的能力注册与检索(含函数路径) | `register_tool` / `search_tools` / … |
48
+ | 文档域 `DocumentAgent` | 说明文档的登记、检索与全文取回 | `register_documents` / `search_documents` / … |
49
+
50
+ ---
51
+
52
+ ## 特性
53
+
54
+ - **双路混合检索**:向量(语义)+ 全文(FTS)双路召回,RRF 融合后再经交叉编码器精排。
55
+ - **R1 / R2 精准锚定**:注册与查询都走机械校验;查询携带唯一判别 token 时确定性置顶。
56
+ - **录入去重**:语义近同(余弦)与功能级(文本判定)双重判重,避免重复登记。
57
+ - **完整 CRUD**:注册 / 查询 / 更新 / 删除,工具域与文档域各自语义对齐,文档全文联动。
58
+ - **可派生领域**:继承基底并指定「数据库 + 表名 + 扩展字段」,即得一个新领域注册表。
59
+ - **全局单实例**:同进程多线程恰好一个实例;跨进程用 HTTP 服务端共享同一实例。
60
+ - **三种调用方式**:Python 导入、命令行、HTTP(任意语言可接)。
61
+
62
+ ---
63
+
64
+ ## 安装
65
+
66
+ 要求 **Python 3.12**。
67
+
68
+ ```bash
69
+ # pip
70
+ pip install semantic-tool-registry
71
+
72
+ # uv(新项目先 uv init,已有项目直接 add)
73
+ uv add semantic-tool-registry
74
+ uv run semantic-tool-registry --help
75
+ ```
76
+
77
+ 安装可选能力:
78
+
79
+ | extra | 作用 |
80
+ |---|---|
81
+ | `onnx` | ONNX 运行时(CPU 包,与 torch 零冲突)—— CPU 上启用 ONNX 后端 |
82
+ | `onnx-gpu` | ONNX 运行时 GPU 版(`CUDAExecutionProvider`) |
83
+ | `onnx-export` | ONNX 导出工具所需依赖 |
84
+ | `download-cn` | 模型自动下载优先走 ModelScope,国内更快 |
85
+ | `yaml` | `register_any` 接受 YAML 字符串输入 |
86
+
87
+ ```bash
88
+ pip install "semantic-tool-registry[onnx,download-cn]"
89
+ uv add "semantic-tool-registry[onnx,download-cn]"
90
+ ```
91
+
92
+ > **GPU / CUDA**:`torch` 是唯一与硬件强绑定的依赖,默认安装的是通用版本。
93
+ > 需要 CUDA 版时,先按 [pytorch.org](https://pytorch.org/get-started/locally/) 的
94
+ > 官方索引装对应 CUDA 的 torch,再安装本包即可;本包不会覆盖已装好的 torch。
95
+ > 仓库内的 `install.ps1`(Windows)可按硬件自动完成这一步。
96
+
97
+ > **首次运行**:嵌入模型与精排模型会在第一次创建 Agent 时自动下载到
98
+ > `./data/models`,请预留几百 MB 磁盘与相应下载时间。
99
+
100
+ ---
101
+
102
+ ## 快速上手
103
+
104
+ ### Python
105
+
106
+ ```python
107
+ from semantic_tool_registry import (
108
+ tool_register, tool_query, tool_update, tool_delete,
109
+ doc_register, doc_query, doc_fulltext,
110
+ )
111
+
112
+ # —— 工具域 ——
113
+ uids = tool_register([
114
+ {"name": "weather_beijing_tool",
115
+ "description": "获取北京实时天气:温度、湿度、风速。标识:weather_beijing_tool"},
116
+ "把人民币金额按实时汇率换算为美元输出。", # 裸文本也可以
117
+ ])
118
+
119
+ hits = tool_query(["北京", "天气"], top_k=1) # 关键词式:直接检索
120
+ tool_update(name="weather_beijing_tool",
121
+ description="获取北京七日天气与生活指数。标识:weather_beijing_tool")
122
+ tool_delete(name="weather_beijing_tool")
123
+
124
+ # —— 文档域 ——
125
+ uids = doc_register([
126
+ {"title": "Nginx 502 排障指南",
127
+ "content": "502 Bad Gateway 通常由上游超时或连接池耗尽引起。排查顺序:…"},
128
+ ])
129
+ hits = doc_query(["Nginx", "502"], top_k=1)
130
+ full_text = doc_fulltext(uids[0]) # 取全文
131
+ ```
132
+
133
+ ### 命令行
134
+
135
+ ```bash
136
+ semantic-tool-registry tool register --file tools.json
137
+ semantic-tool-registry tool query weather_beijing_tool
138
+ semantic-tool-registry doc query Nginx 502
139
+ ```
140
+
141
+ ### HTTP
142
+
143
+ ```bash
144
+ semantic-tool-registry serve --port 8600
145
+ ```
146
+
147
+ ```bash
148
+ curl -s http://127.0.0.1:8600/tool/register \
149
+ -H "Content-Type: application/json" \
150
+ -d '[{"name":"weather_beijing_tool","description":"获取北京实时天气。标识:weather_beijing_tool"}]'
151
+
152
+ curl -s http://127.0.0.1:8600/tool/query \
153
+ -d '{"keywords": ["weather_beijing_tool"], "top_k": 1}'
154
+ ```
155
+
156
+ ---
157
+
158
+ ## Python API
159
+
160
+ ### 便捷函数(推荐起步)
161
+
162
+ 经全局单实例直接调用,无需自己管理实例。
163
+
164
+ | 函数 | 说明 |
165
+ |---|---|
166
+ | `tool_register(items, **kw)` / `doc_register(docs, **kw)` | 注册,返回与输入逐位对齐的 uid 列表(`None` = 被拒或去重) |
167
+ | `tool_query(keywords, top_k=1)` / `doc_query(keywords, top_k=1)` | 查询;`keywords` 为列表 = 关键词式,为字符串 = 整句式(见下) |
168
+ | `tool_update(...)` / `doc_update(...)` | 更新;`name`/`uid` 定位,`new_name` 改名,`description`/`content` 改内容 |
169
+ | `tool_delete(...)` / `doc_delete(...)` | 删除单个(`uid` 或 `name`) |
170
+ | `tool_delete_batch(items)` | 批量删除,逐位返回 `bool` |
171
+ | `doc_fulltext(uid)` | 取单篇文档全文 |
172
+
173
+ **关键词式 vs 整句式**
174
+
175
+ - `tool_query(["北京", "天气"])` —— 关键词式:直接走向量 + 全文混合检索,任何情况下都返回结果。
176
+ - `tool_query("北京今天天气怎么样")` —— 整句式:先做查询规格校验(R2),
177
+ 若句中已含唯一判别 token 则确定性置顶;若不能唯一定位,则在**配置了 LLM** 时
178
+ 由 LLM 规范化成检索锚点后复验。两者都不满足时**不猜测检索**,而是返回一份
179
+ *要求文档*(告诉你缺什么、该怎么改写查询)。
180
+
181
+ 配置 LLM:
182
+
183
+ ```python
184
+ from semantic_tool_registry import configure_tool_agent
185
+
186
+ configure_tool_agent(
187
+ llm_base_url="https://api.example.com/v1",
188
+ llm_api_key="sk-...",
189
+ llm_model="your-model",
190
+ )
191
+ ```
192
+
193
+ ### 配置与单实例
194
+
195
+ 配置必须在首次获取实例**之前**给出,之后再次传配置会被忽略并告警。
196
+
197
+ ```python
198
+ from semantic_tool_registry import configure_tool_agent, get_tool_agent
199
+
200
+ configure_tool_agent(mode="speed", device="gpu", data_path="./mydata")
201
+ ag = get_tool_agent() # 首次调用才真正创建(加载模型)
202
+ ag2 = get_tool_agent() # 同一个对象
203
+ assert ag is ag2
204
+ ```
205
+
206
+ ### 完整能力
207
+
208
+ ```python
209
+ ag = get_tool_agent() # ToolAgent
210
+ da = get_document_agent() # DocumentAgent
211
+
212
+ ag.register_any(...) # 任意格式:dict / 函数 / 类 / JSON / XML / CSV / YAML / 混合列表
213
+ ag.search_tools_batch(...) # 批量查询,与输入逐位对齐
214
+ ag.auto_search(...) # 规范化查询(R2 校验 + LLM 增强)
215
+ ag.validate_storage_consistency(repair=True) # 一致性体检与修复
216
+
217
+ da.search_documents_batch(...) / da.auto_search_documents(...)
218
+ da.get_full_text(uid) / da.get_full_texts(uids)
219
+ da.delete_documents([uid, "标题"]) # 批删,全文联动
220
+ ```
221
+
222
+ 注册真实可调用对象(函数 / 类 / 方法)时,会自动写入「函数路径」扩展字段
223
+ (`实现文件绝对路径.限定名`),查询结果一并带出。
224
+
225
+ ### 派生新领域
226
+
227
+ 继承基底并在初始化时定型「数据库 + 表名 + 扩展字段」,注册 / 查询 / 更新 / 删除
228
+ 全自动适配该领域。完整说明(含示例与默认表对照)随源码分发包一同提供,见
229
+ `docs/base_agent.md`、`docs/tool_agent.md`、`docs/document_agent.md`。
230
+
231
+ ---
232
+
233
+ ## 命令行
234
+
235
+ ```bash
236
+ semantic-tool-registry --help
237
+ ```
238
+
239
+ 注册,三种输入方式任选:
240
+
241
+ ```bash
242
+ # JSON 数组文件(推荐)
243
+ semantic-tool-registry tool register --file tools.json
244
+ # 内联 JSON
245
+ semantic-tool-registry tool register --json '[{"name":"fx_tool","description":"…标识:fx_tool"}]'
246
+ # 位置参数:每行一条裸文本
247
+ semantic-tool-registry tool register "把人民币金额按实时汇率换算为美元输出。"
248
+ ```
249
+
250
+ `tools.json` 示例:
251
+
252
+ ```json
253
+ [
254
+ {"name": "weather_beijing_tool",
255
+ "description": "获取北京实时天气:温度、湿度、风速、降水概率。标识:weather_beijing_tool"},
256
+ {"name": "fx_usd_cny_tool",
257
+ "description": "人民币与美元实时汇率换算,支持双向报价。标识:fx_usd_cny_tool"}
258
+ ]
259
+ ```
260
+
261
+ 查询 / 更新 / 删除:
262
+
263
+ ```bash
264
+ semantic-tool-registry tool query weather_beijing_tool
265
+ semantic-tool-registry tool query 北京 天气 # 多词 = 关键词式(精准)
266
+ semantic-tool-registry tool query --raw "北京今天天气怎么样" # 强制关键词式
267
+ semantic-tool-registry doc query Nginx 502
268
+
269
+ semantic-tool-registry tool update --name weather_beijing_tool --description "七日天气…标识:weather_beijing_tool"
270
+ semantic-tool-registry tool delete --name fx_usd_cny_tool
271
+ semantic-tool-registry doc delete --name "Nginx 502 排障指南"
272
+ ```
273
+
274
+ 全局参数(写在子命令之前):
275
+
276
+ ```bash
277
+ semantic-tool-registry --data-path D:\mydata tool query weather_beijing_tool
278
+ semantic-tool-registry --mode speed doc query "网关 502"
279
+ semantic-tool-registry --zvec-lock-wait 120 tool register --file tools.json
280
+ ```
281
+
282
+ 等价的模块调用:`python -m semantic_tool_registry …`。
283
+
284
+ ---
285
+
286
+ ## HTTP 服务
287
+
288
+ ```bash
289
+ semantic-tool-registry serve --port 8600 --data-path ./data
290
+ semantic-tool-registry serve --no-preload # 启动更快,首个请求稍慢
291
+ ```
292
+
293
+ | 方法 | 路径 | 请求体 | 返回 |
294
+ |---|---|---|---|
295
+ | GET | `/health` | — | 健康状态与实例情况 |
296
+ | POST | `/tool/register` | `{"items": [...]}` 或裸数组 | `{"uids": [...]}` |
297
+ | POST | `/tool/query` | `{"keywords": [...], "top_k": 1}` | `{"results": [...]}` |
298
+ | POST | `/tool/update` | `{"uid"/"name", "new_name", "description"}` | `{"uid": "..."}` |
299
+ | POST | `/tool/delete` | `{"uid"/"name"}` 或 `{"items": [...]}` | `{"deleted": true}` / `{"results": [...]}` |
300
+ | POST | `/doc/register` | `{"items": [{"title","content"}, ...]}` | `{"uids": [...]}` |
301
+ | POST | `/doc/query` | `{"keywords": [...], "top_k": 1}` | `{"results": [...]}` |
302
+ | GET / POST | `/doc/fulltext` | `?uid=...` 或 `{"uid": ...}` | `{"content": "..."}` |
303
+ | POST | `/doc/update` / `/doc/delete` | 同工具域语义 | 同工具域 |
304
+
305
+ ```bash
306
+ curl -s http://127.0.0.1:8600/doc/register \
307
+ -d '[{"title":"Nginx 502 排障指南","content":"502 通常由上游超时…"}]'
308
+ curl -s http://127.0.0.1:8600/doc/query -d '{"keywords":["Nginx","502"]}'
309
+ curl -s "http://127.0.0.1:8600/doc/fulltext?uid=<uid>"
310
+ ```
311
+
312
+ ### Python 跨进程客户端
313
+
314
+ 服务进程独占向量库,其余进程做瘦客户端 —— 多进程共用一个实例,零并发写冲突。
315
+
316
+ ```python
317
+ # 进程 1(唯一持有向量库的进程):
318
+ # semantic-tool-registry serve --port 8600
319
+ # 进程 2、3、…(任意多个,可跨机器):
320
+ from semantic_tool_registry import HttpClient
321
+
322
+ c = HttpClient("http://127.0.0.1:8600") # 或 remote("http://…")
323
+ c.tool_register([{"name": "shared_tool", "description": "…标识:shared_tool"}])
324
+ hits = c.tool_query(["shared_tool"]) # 读到任何进程写入的数据
325
+ c.doc_register([{"title": "…", "content": "…"}])
326
+ c.health()
327
+ ```
328
+
329
+ 方法名与本地便捷函数一致,本地直连 ↔ 远程调用切换零成本;纯标准库实现。
330
+
331
+ ---
332
+
333
+ ## 数据与配置
334
+
335
+ ### 目录
336
+
337
+ 默认根目录为当前工作目录下的 `./data`:
338
+
339
+ | 路径 | 内容 |
340
+ |---|---|
341
+ | `./data/entry_registry/` | 工具域向量库 |
342
+ | `./data/entry_registry/entry_metadata.db` | 工具域元数据(SQLite) |
343
+ | `./data/document_registry/` | 文档域向量库与元数据 |
344
+ | `./data/models/` | 下载的嵌入 / 精排模型缓存 |
345
+ | `./data/onnx_models/` | ONNX 导出产物(仅在 ONNX 后端下使用) |
346
+
347
+ ### 环境变量
348
+
349
+ | 变量 | 作用 |
350
+ |---|---|
351
+ | `AI_TOOLS_MODE` | `precision` / `speed`,默认按硬件自动选型 |
352
+ | `AI_TOOLS_DEVICE` | `gpu` / `cpu`(或 `auto`) |
353
+ | `AI_TOOLS_DATA` | 存储根目录 |
354
+ | `AI_TOOLS_ZVEC_WAIT` | 向量库被占用时的排队等待秒数 |
355
+ | `HF_ENDPOINT` | Hugging Face 镜像地址(模型下载用),如 `https://hf-mirror.com` |
356
+
357
+ 命令行同名参数优先于环境变量。
358
+
359
+ ### 三种用法的单实例保证
360
+
361
+ | 用法 | 保证 |
362
+ |---|---|
363
+ | Python 导入 | 进程内恰好一个(多线程共享) |
364
+ | 命令行 | 每次调用恰好一个;进程退出即释放向量库锁 |
365
+ | HTTP | 全系统恰好一个:服务进程持有实例,N 个客户端零实例 |
366
+
367
+ ---
368
+
369
+ ## 常见问题
370
+
371
+ **同一数据目录被多个进程同时占用**
372
+
373
+ 向量库是独占的。三种解法:
374
+
375
+ 1. **服务模式(推荐)**:一个进程 `serve`,其余进程用 `HttpClient` 远程调用。
376
+ 2. **排队模式**:`--zvec-lock-wait 120`(或构造实例时 `zvec_lock_wait=120`),
377
+ 等持有进程退出后自动接管。
378
+ 3. **各自独立目录**:不同进程用不同 `--data-path`。
379
+
380
+ **模型下载慢或需要离线**
381
+
382
+ ```bash
383
+ export HF_ENDPOINT=https://hf-mirror.com # Windows: set HF_ENDPOINT=...
384
+ pip install "semantic-tool-registry[download-cn]" # 优先走 ModelScope
385
+ ```
386
+
387
+ 已有的本地模型目录可经构造参数 `cache_dir` 指定,ONNX 产物目录用 `onnx_root`。
388
+
389
+ **整句查询返回了一份「要求文档」而不是结果**
390
+
391
+ 这是设计行为:查询无法唯一定位时不会猜测检索。按返回文档给出的提示改写为
392
+ 关键词式(如多词查询),或按上文配置 LLM 后重试。
393
+
394
+ **速度与精度怎么选**
395
+
396
+ `--mode speed` 用小模型换速度,`--mode precision` 换取更好的排序质量;
397
+ 不指定时按硬件自动选型。CPU 上会自动优先使用 ONNX 后端(需安装 `[onnx]`)。
398
+
399
+ ---
400
+
401
+ ## 许可
402
+
403
+ MIT