zleap-sag2 0.1.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.
- zleap_sag2-0.1.0/.env.example +43 -0
- zleap_sag2-0.1.0/.gitignore +10 -0
- zleap_sag2-0.1.0/LICENSE +21 -0
- zleap_sag2-0.1.0/Makefile +26 -0
- zleap_sag2-0.1.0/NOTICE +35 -0
- zleap_sag2-0.1.0/PKG-INFO +227 -0
- zleap_sag2-0.1.0/README.md +175 -0
- zleap_sag2-0.1.0/docs/api-compatibility.md +341 -0
- zleap_sag2-0.1.0/docs/architecture.md +135 -0
- zleap_sag2-0.1.0/docs/benchmarks/musique-2026-10-22.md +111 -0
- zleap_sag2-0.1.0/docs/ported-sag-files.json +45 -0
- zleap_sag2-0.1.0/docs/reference-manifest.json +38 -0
- zleap_sag2-0.1.0/docs/reproduction.md +88 -0
- zleap_sag2-0.1.0/pyproject.toml +67 -0
- zleap_sag2-0.1.0/scripts/check_release.py +56 -0
- zleap_sag2-0.1.0/scripts/freeze_unicode61.py +74 -0
- zleap_sag2-0.1.0/scripts/measure_capacity.py +160 -0
- zleap_sag2-0.1.0/scripts/prepare_reference.py +45 -0
- zleap_sag2-0.1.0/scripts/replay_online.py +118 -0
- zleap_sag2-0.1.0/scripts/response_cache.py +63 -0
- zleap_sag2-0.1.0/scripts/run_benchmark.py +305 -0
- zleap_sag2-0.1.0/scripts/smoke_installed.py +147 -0
- zleap_sag2-0.1.0/scripts/smoke_wheel.sh +15 -0
- zleap_sag2-0.1.0/scripts/verify_reference.py +120 -0
- zleap_sag2-0.1.0/src/zleap/sag2/__about__.py +1 -0
- zleap_sag2-0.1.0/src/zleap/sag2/__init__.py +159 -0
- zleap_sag2-0.1.0/src/zleap/sag2/_algorithm.py +320 -0
- zleap_sag2-0.1.0/src/zleap/sag2/_arithmetic.py +27 -0
- zleap_sag2-0.1.0/src/zleap/sag2/_assets/o200k_base.tiktoken +199998 -0
- zleap_sag2-0.1.0/src/zleap/sag2/_commands.py +361 -0
- zleap_sag2-0.1.0/src/zleap/sag2/_decision_encoding.py +41 -0
- zleap_sag2-0.1.0/src/zleap/sag2/_jev_score.py +109 -0
- zleap_sag2-0.1.0/src/zleap/sag2/_lexical_rules.py +155 -0
- zleap_sag2-0.1.0/src/zleap/sag2/_safe_error.py +18 -0
- zleap_sag2-0.1.0/src/zleap/sag2/_sag1.py +326 -0
- zleap_sag2-0.1.0/src/zleap/sag2/_search_store.py +208 -0
- zleap_sag2-0.1.0/src/zleap/sag2/_unicode61.py +34 -0
- zleap_sag2-0.1.0/src/zleap/sag2/benchmark.py +43 -0
- zleap_sag2-0.1.0/src/zleap/sag2/config.py +246 -0
- zleap_sag2-0.1.0/src/zleap/sag2/engine.py +852 -0
- zleap_sag2-0.1.0/src/zleap/sag2/exceptions.py +263 -0
- zleap_sag2-0.1.0/src/zleap/sag2/jev.py +84 -0
- zleap_sag2-0.1.0/src/zleap/sag2/lexical.py +205 -0
- zleap_sag2-0.1.0/src/zleap/sag2/maintenance.py +29 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/__init__.py +0 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/__init__.py +0 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/__init__.py +65 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/assembler/__init__.py +11 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/assembler/generic.py +330 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/base.py +55 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/chunker/__init__.py +23 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/chunker/base.py +20 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/chunker/code.py +41 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/chunker/formula.py +41 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/chunker/heading.py +51 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/chunker/image.py +43 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/chunker/markdown.py +133 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/chunker/router.py +31 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/chunker/table.py +108 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/chunker/text.py +369 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/parser/__init__.py +11 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/parser/html_table.py +163 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/parser/markdown.py +770 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/pipeline.py +47 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/tabular.py +188 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/tokenizer/README.md +10 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/tokenizer/__init__.py +11 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/tokenizer/assets/tokenizer.json +757480 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/tokenizer/estimator.py +88 -0
- zleap_sag2-0.1.0/src/zleap/sag2/modules/load/chunking/types.py +78 -0
- zleap_sag2-0.1.0/src/zleap/sag2/observability.py +110 -0
- zleap_sag2-0.1.0/src/zleap/sag2/operations.py +227 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/__init__.py +124 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/_utils.py +12 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/chunk.py +588 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/context.py +88 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/contracts.py +588 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/converters/__init__.py +5 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/converters/markitdown.py +88 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/errors.py +89 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/events.py +66 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/index.py +251 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/options.py +74 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/parse.py +635 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/ports.py +19 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/search.py +114 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/spreadsheets/__init__.py +16 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/spreadsheets/alignment.py +97 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/spreadsheets/contracts.py +54 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/spreadsheets/reader.py +239 -0
- zleap_sag2-0.1.0/src/zleap/sag2/pipeline/spreadsheets/structure.py +246 -0
- zleap_sag2-0.1.0/src/zleap/sag2/py.typed +0 -0
- zleap_sag2-0.1.0/src/zleap/sag2/queries.py +42 -0
- zleap_sag2-0.1.0/src/zleap/sag2/records.py +51 -0
- zleap_sag2-0.1.0/src/zleap/sag2/status.py +69 -0
- zleap_sag2-0.1.0/src/zleap/sag2/storage.py +780 -0
- zleap_sag2-0.1.0/src/zleap/sag2/unicode61.json +1 -0
- zleap_sag2-0.1.0/src/zleap/sag2/utils/__init__.py +3 -0
- zleap_sag2-0.1.0/src/zleap/sag2/utils/text.py +30 -0
- zleap_sag2-0.1.0/src/zleap/sag2/validation.py +129 -0
- zleap_sag2-0.1.0/tests/conftest.py +46 -0
- zleap_sag2-0.1.0/tests/fixtures/sag2_reference.json +1249 -0
- zleap_sag2-0.1.0/tests/ported/test_html_table.py +166 -0
- zleap_sag2-0.1.0/tests/ported/test_markdown_code_formula_parser.py +167 -0
- zleap_sag2-0.1.0/tests/ported/test_markdown_image_parser.py +107 -0
- zleap_sag2-0.1.0/tests/ported/test_markdown_table_chunker.py +53 -0
- zleap_sag2-0.1.0/tests/ported/test_markdown_table_parser.py +97 -0
- zleap_sag2-0.1.0/tests/ported/test_markdown_text_protected_spans.py +131 -0
- zleap_sag2-0.1.0/tests/ported/test_spreadsheet_reader.py +116 -0
- zleap_sag2-0.1.0/tests/ported/test_spreadsheet_structure.py +111 -0
- zleap_sag2-0.1.0/tests/ported/test_table_source_chunk_assembler.py +105 -0
- zleap_sag2-0.1.0/tests/test_algorithm.py +46 -0
- zleap_sag2-0.1.0/tests/test_backends.py +29 -0
- zleap_sag2-0.1.0/tests/test_config_env.py +250 -0
- zleap_sag2-0.1.0/tests/test_evaluation_cache.py +46 -0
- zleap_sag2-0.1.0/tests/test_jev.py +146 -0
- zleap_sag2-0.1.0/tests/test_lifecycle.py +258 -0
- zleap_sag2-0.1.0/tests/test_postgres_concurrency.py +212 -0
- zleap_sag2-0.1.0/tests/test_public_api.py +709 -0
- zleap_sag2-0.1.0/tests/test_sag1_storage.py +522 -0
- zleap_sag2-0.1.0/tests/test_search_pages.py +448 -0
- zleap_sag2-0.1.0/tests/test_unicode61.py +26 -0
- zleap_sag2-0.1.0/tests/test_unit_overlap.py +251 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# SAG1 / SAG2 使用相同的关系库配置。
|
|
2
|
+
# EngineConfig.from_env(".env") 显式读取文件;同名进程变量覆盖文件值。
|
|
3
|
+
SAG_RELATIONAL_PROVIDER=sqlite
|
|
4
|
+
SAG_DATA_DIR=./.zleap
|
|
5
|
+
# SQLite 数据文件为 <SAG_DATA_DIR>/sag.db。
|
|
6
|
+
# MySQL / PostgreSQL / OceanBase 使用以下连接配置。
|
|
7
|
+
# SAG_RELATIONAL_HOST=localhost
|
|
8
|
+
# SAG_RELATIONAL_PORT=3306
|
|
9
|
+
# 默认端口:MySQL 3306、PostgreSQL 5432、OceanBase 2881。
|
|
10
|
+
# SAG_RELATIONAL_USER=sag2
|
|
11
|
+
# SAG_RELATIONAL_PASSWORD=sag2
|
|
12
|
+
# SAG_RELATIONAL_DATABASE=sag2
|
|
13
|
+
# SAG_RELATIONAL_POOL_SIZE=5
|
|
14
|
+
# SAG_RELATIONAL_MAX_OVERFLOW=5
|
|
15
|
+
# SAG_RELATIONAL_POOL_RECYCLE=3600
|
|
16
|
+
# SAG_RELATIONAL_POOL_TIMEOUT=30
|
|
17
|
+
# SAG_RELATIONAL_CONNECT_TIMEOUT=10
|
|
18
|
+
# SAG_RELATIONAL_COMMAND_TIMEOUT=30
|
|
19
|
+
|
|
20
|
+
# PostgreSQL TLS:require / verify-ca / verify-full。
|
|
21
|
+
# SAG_RELATIONAL_TLS_MODE=verify-full
|
|
22
|
+
# SAG_RELATIONAL_TLS_CA_FILE=/path/to/ca.pem
|
|
23
|
+
# SAG_RELATIONAL_TLS_CLIENT_CERT_FILE=/path/to/client.pem
|
|
24
|
+
# SAG_RELATIONAL_TLS_CLIENT_KEY_FILE=/path/to/client.key
|
|
25
|
+
|
|
26
|
+
# SAG2 搜索使用独立的决策模型,推荐以下两种:
|
|
27
|
+
# JEV(TypeSafe):https://typesafe.ai/
|
|
28
|
+
# D1-ultra(Liquid AI):https://www.liquid.ai/blog/d1-ultra
|
|
29
|
+
# 模型、接口地址和 API Key 必须对应同一服务;切换模型时一起替换这三项。
|
|
30
|
+
# 以下为 JEV 配置(302.AI 接口;模型 ID 以服务商提供的名称为准)。
|
|
31
|
+
DECISION_ENDPOINT=https://api.302ai.com/typesafeai/v1/systemone
|
|
32
|
+
DECISION_MODEL=typesafe/jev-1.13
|
|
33
|
+
DECISION_API_KEY=
|
|
34
|
+
# 使用 JEV 官方服务时,替换接口、模型并填写 TypeSafe API Key:
|
|
35
|
+
# DECISION_ENDPOINT=https://api.typesafe.ai/v1/systemone
|
|
36
|
+
# DECISION_MODEL=jev-latest
|
|
37
|
+
# 使用 D1-ultra 官方服务时,替换接口、模型并填写 Liquid AI API Key:
|
|
38
|
+
# DECISION_ENDPOINT=https://api.liquid.ai/decisions/v1/systemone
|
|
39
|
+
# DECISION_MODEL=d1-ultra
|
|
40
|
+
# DECISION_MAX_ATTEMPTS=4
|
|
41
|
+
# DECISION_TIMEOUT_SECONDS=180
|
|
42
|
+
# DECISION_BACKOFF_SECONDS=1
|
|
43
|
+
# DECISION_MAX_CONCURRENCY=20
|
zleap_sag2-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Zleap Team
|
|
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,26 @@
|
|
|
1
|
+
# Run here, or use `make -C packages/sag2 verify` from the repository root.
|
|
2
|
+
PYTHON ?= python3
|
|
3
|
+
VENV ?= .venv
|
|
4
|
+
RUN := $(VENV)/bin
|
|
5
|
+
|
|
6
|
+
.PHONY: install lint format test build verify
|
|
7
|
+
install:
|
|
8
|
+
$(PYTHON) -m venv $(VENV)
|
|
9
|
+
$(RUN)/python -m pip install -e ".[dev,tables]"
|
|
10
|
+
|
|
11
|
+
lint:
|
|
12
|
+
$(RUN)/ruff check .
|
|
13
|
+
$(RUN)/ruff format --check .
|
|
14
|
+
|
|
15
|
+
format:
|
|
16
|
+
$(RUN)/ruff format .
|
|
17
|
+
|
|
18
|
+
test:
|
|
19
|
+
$(RUN)/python -m pytest -q -m "not integration and not online"
|
|
20
|
+
|
|
21
|
+
build:
|
|
22
|
+
$(RUN)/python -m build
|
|
23
|
+
$(RUN)/python -m twine check dist/*
|
|
24
|
+
$(RUN)/python scripts/check_release.py dist
|
|
25
|
+
|
|
26
|
+
verify: lint test build
|
zleap_sag2-0.1.0/NOTICE
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
Portable parsing and chunking are derived from zleap-sag 0.15.0,
|
|
2
|
+
Copyright Zleap Team, MIT License (see LICENSE).
|
|
3
|
+
|
|
4
|
+
SAG2 tokenization, expansion, JEV evidence payloads, multi-round retrieval and
|
|
5
|
+
local diversity ordering are derived from SAG-Benchmark, Copyright (c) 2026
|
|
6
|
+
Zleap AI, MIT License. The frozen upstream file hashes are recorded in
|
|
7
|
+
docs/reference-manifest.json in the development workspace.
|
|
8
|
+
|
|
9
|
+
The bundled o200k_base encoding and its construction parameters are derived
|
|
10
|
+
from OpenAI tiktoken 0.14.0 (https://github.com/openai/tiktoken).
|
|
11
|
+
Encoding source:
|
|
12
|
+
https://openaipublic.blob.core.windows.net/encodings/o200k_base.tiktoken
|
|
13
|
+
SHA256: 446a9538cb6c348e3516120d7c08b09f57c36495e2acfffe59a5bf8b0cfb1a2d
|
|
14
|
+
|
|
15
|
+
MIT License
|
|
16
|
+
|
|
17
|
+
Copyright (c) 2022 OpenAI, Shantanu Jain
|
|
18
|
+
|
|
19
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
20
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
21
|
+
in the Software without restriction, including without limitation the rights
|
|
22
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
23
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
24
|
+
furnished to do so, subject to the following conditions:
|
|
25
|
+
|
|
26
|
+
The above copyright notice and this permission notice shall be included in all
|
|
27
|
+
copies or substantial portions of the Software.
|
|
28
|
+
|
|
29
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
30
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
31
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
32
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
33
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
34
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
35
|
+
SOFTWARE.
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: zleap-sag2
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: SAG2 passage retrieval with portable relational storage
|
|
5
|
+
Project-URL: Homepage, https://github.com/Zleap-AI/zleap
|
|
6
|
+
Project-URL: Repository, https://github.com/Zleap-AI/zleap
|
|
7
|
+
Project-URL: Documentation, https://github.com/Zleap-AI/zleap/tree/main/packages/sag2#readme
|
|
8
|
+
Project-URL: Issues, https://github.com/Zleap-AI/zleap/issues
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
License-File: NOTICE
|
|
12
|
+
Requires-Python: >=3.11
|
|
13
|
+
Requires-Dist: aiohttp>=3.14.3
|
|
14
|
+
Requires-Dist: aiosqlite>=0.19
|
|
15
|
+
Requires-Dist: jieba==0.42.1
|
|
16
|
+
Requires-Dist: pydantic-settings>=2.6
|
|
17
|
+
Requires-Dist: pydantic>=2.5
|
|
18
|
+
Requires-Dist: pyuca==1.2
|
|
19
|
+
Requires-Dist: regex>=2026.9.29
|
|
20
|
+
Requires-Dist: sqlalchemy[asyncio]>=2.0
|
|
21
|
+
Requires-Dist: tiktoken>=0.14
|
|
22
|
+
Requires-Dist: tokenizers>=0.22
|
|
23
|
+
Requires-Dist: tzdata
|
|
24
|
+
Provides-Extra: all
|
|
25
|
+
Requires-Dist: aiomysql>=0.2; extra == 'all'
|
|
26
|
+
Requires-Dist: asyncpg>=0.29; extra == 'all'
|
|
27
|
+
Requires-Dist: cryptography>=50; extra == 'all'
|
|
28
|
+
Requires-Dist: markitdown[xlsx]<0.2,>=0.1.5; extra == 'all'
|
|
29
|
+
Requires-Dist: openpyxl<4,>=3.1.5; extra == 'all'
|
|
30
|
+
Requires-Dist: pandas<3,>=2.2; extra == 'all'
|
|
31
|
+
Requires-Dist: xlrd<3,>=2; extra == 'all'
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: build>=1; extra == 'dev'
|
|
34
|
+
Requires-Dist: hatchling>=1.27; extra == 'dev'
|
|
35
|
+
Requires-Dist: httpx>=0.28; extra == 'dev'
|
|
36
|
+
Requires-Dist: packaging>=24; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-asyncio>=1; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
39
|
+
Requires-Dist: ruff==0.16.4; extra == 'dev'
|
|
40
|
+
Requires-Dist: twine>=6; extra == 'dev'
|
|
41
|
+
Provides-Extra: mysql
|
|
42
|
+
Requires-Dist: aiomysql>=0.2; extra == 'mysql'
|
|
43
|
+
Requires-Dist: cryptography>=50; extra == 'mysql'
|
|
44
|
+
Provides-Extra: postgres
|
|
45
|
+
Requires-Dist: asyncpg>=0.29; extra == 'postgres'
|
|
46
|
+
Provides-Extra: tables
|
|
47
|
+
Requires-Dist: markitdown[xlsx]<0.2,>=0.1.5; extra == 'tables'
|
|
48
|
+
Requires-Dist: openpyxl<4,>=3.1.5; extra == 'tables'
|
|
49
|
+
Requires-Dist: pandas<3,>=2.2; extra == 'tables'
|
|
50
|
+
Requires-Dist: xlrd<3,>=2; extra == 'tables'
|
|
51
|
+
Description-Content-Type: text/markdown
|
|
52
|
+
|
|
53
|
+
# zleap-sag2
|
|
54
|
+
|
|
55
|
+
SAG2 原文检索引擎:统一词法召回、多轮 JEV 证据评分和本地多样性排序。
|
|
56
|
+
支持 SQLite、MySQL、PostgreSQL 和 OceanBase。连接已有 SAG1 库时,自动从
|
|
57
|
+
`source_chunk` 读取现有段落;空库使用 SAG2 自有存储。
|
|
58
|
+
|
|
59
|
+
发布到 PyPI 后,可按包名安装:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
pip install zleap-sag2
|
|
63
|
+
# MySQL / OceanBase
|
|
64
|
+
pip install 'zleap-sag2[mysql]'
|
|
65
|
+
# PostgreSQL
|
|
66
|
+
pip install 'zleap-sag2[postgres]'
|
|
67
|
+
# 电子表格转换
|
|
68
|
+
pip install 'zleap-sag2[tables]'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
从源码安装时,先进入包含本文件和 `pyproject.toml` 的包目录,再执行
|
|
72
|
+
`pip install .`;可选依赖使用 `pip install '.[tables]'` 等形式。
|
|
73
|
+
也可通过 `pip install` 指定已下载 wheel 文件的实际路径。
|
|
74
|
+
|
|
75
|
+
### 独立开发
|
|
76
|
+
|
|
77
|
+
可以直接在 IDE 或 Codex 中打开包目录:仓库中的 `packages/sag2`,或解压后的
|
|
78
|
+
源码包根目录。以下命令均在该目录执行。源码、测试、脚本、文档和环境变量模板
|
|
79
|
+
均在本目录内;使用仓库检出时,Git 提交仍属于 `zleap` 根仓库。
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
make install # 本目录 .venv,只安装 SAG2 和开发/表格依赖
|
|
83
|
+
make verify # lint、离线测试、构建、产物元数据检查
|
|
84
|
+
cp .env.example .env # 需要连接模型服务时再填写
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
也可在根目录运行 `make -C packages/sag2 verify`。根目录的 `make verify` 仍检查 SAG。
|
|
88
|
+
本包独立版本为 `src/zleap/sag2/__about__.py`,发布 tag 为 `zleap-sag2/vX.Y.Z`;
|
|
89
|
+
发布配置见仓库的 [RELEASING.md](https://github.com/Zleap-AI/zleap/blob/main/RELEASING.md)。`zleap` 元包暂不依赖 SAG2,
|
|
90
|
+
使用者需单独安装 `zleap-sag2`。
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
import asyncio
|
|
94
|
+
from zleap.sag2 import DataEngine, EngineConfig
|
|
95
|
+
from zleap.sag2 import TextSource, SourceDescriptor, SearchScope, SearchRequest
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
async def main():
|
|
99
|
+
config = EngineConfig.from_env(".env")
|
|
100
|
+
async with DataEngine(config, data_source_id="demo") as engine:
|
|
101
|
+
await engine.ingest(
|
|
102
|
+
TextSource(
|
|
103
|
+
text="# 示例\nAlice 出生在北京。",
|
|
104
|
+
descriptor=SourceDescriptor(
|
|
105
|
+
data_source_id="demo",
|
|
106
|
+
source_id="alice",
|
|
107
|
+
source_type="text",
|
|
108
|
+
),
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
result = await engine.search(
|
|
112
|
+
SearchRequest(query="Alice 出生在哪里?", scope=SearchScope(data_source_ids=("demo",)))
|
|
113
|
+
)
|
|
114
|
+
for hit in result.chunks:
|
|
115
|
+
print(hit.score, hit.content)
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
asyncio.run(main())
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
`parse` 和 `chunk` 可在启动数据库前使用。`index(ChunkSet)` 直接保存已有分块。
|
|
122
|
+
|
|
123
|
+
### 配置
|
|
124
|
+
|
|
125
|
+
关系库环境变量与 SAG1 一致,使用 `EngineConfig.from_env(".env")` 显式读取文件;
|
|
126
|
+
`EngineConfig.from_env()` 只读取进程环境,不自动寻找 `.env`。最小配置:
|
|
127
|
+
|
|
128
|
+
```dotenv
|
|
129
|
+
SAG_RELATIONAL_PROVIDER=sqlite
|
|
130
|
+
SAG_DATA_DIR=./.zleap
|
|
131
|
+
DECISION_ENDPOINT=https://api.typesafe.ai/v1/systemone
|
|
132
|
+
DECISION_MODEL=jev-latest
|
|
133
|
+
DECISION_API_KEY=your-key
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
推荐使用 [JEV(TypeSafe)](https://typesafe.ai/) 或
|
|
137
|
+
[D1-ultra(Liquid AI)](https://www.liquid.ai/blog/d1-ultra) 作为决策模型。
|
|
138
|
+
使用 D1-ultra 时,将接口改为 `https://api.liquid.ai/decisions/v1/systemone`、
|
|
139
|
+
模型改为 `d1-ultra`,并填写 Liquid AI 的 API Key。使用其他服务商时,
|
|
140
|
+
模型 ID 与接口地址以该服务商为准,三项配置需对应同一服务。
|
|
141
|
+
|
|
142
|
+
决策请求的 token 预算使用随包提供的 `o200k_base` 编码资源;首次启动无需下载
|
|
143
|
+
tokenizer 或预置缓存。实际用量仍取决策服务返回的 `usage`。
|
|
144
|
+
|
|
145
|
+
SQLite 使用 `<SAG_DATA_DIR>/sag.db`,默认 `.zleap/sag.db`。服务库使用
|
|
146
|
+
`SAG_RELATIONAL_HOST` / `PORT` / `USER` / `PASSWORD` / `DATABASE`,连接池、超时及
|
|
147
|
+
PostgreSQL TLS 参数同样沿用 `SAG_RELATIONAL_*`。默认端口为 MySQL 3306、
|
|
148
|
+
PostgreSQL 5432、OceanBase 2881。
|
|
149
|
+
|
|
150
|
+
`RELATIONAL_PROVIDER`、`DATA_DIR`、`DB_HOST` / `DB_PORT` / `DB_USER` /
|
|
151
|
+
`DB_PASSWORD` / `DB_NAME`、`DB_POOL_*` / `DB_MAX_OVERFLOW` / `DB_CONNECT_TIMEOUT` /
|
|
152
|
+
`DB_COMMAND_TIMEOUT`、`DB_TLS_*` 也与 SAG1 一致。同名进程变量覆盖文件值;
|
|
153
|
+
同时设置等价名称时,`SAG_*` 优先,空值视为未设置。
|
|
154
|
+
|
|
155
|
+
SAG1 的配置文件可以直接复用,SAG2 不使用其中的 LLM、Embedding、向量库和
|
|
156
|
+
事件配置;搜索需补充 `DECISION_*`。未配置任何决策模型参数时仍可解析、切块、读取与续页,
|
|
157
|
+
部分配置决策模型参数会在加载时明确报错。也可以直接构造 `EngineConfig` 和
|
|
158
|
+
`RelationalConfig`,显式配置不读取环境变量。
|
|
159
|
+
|
|
160
|
+
### 直接搜索 SAG1 已有数据
|
|
161
|
+
|
|
162
|
+
用 `EngineConfig.from_env(".env")` 读取 SAG1 的连接配置,补充决策模型配置后直接调用
|
|
163
|
+
`search()` 或 `search_page()`,无需先调用 `index()`。
|
|
164
|
+
引擎启动时识别 `source_chunk`,沿用原段落 ID,读取 `article` / `chat_conversation`
|
|
165
|
+
补充来源信息,并遵守活动 generation、来源删除和数据源停用状态。normal / lite
|
|
166
|
+
的文本关系表均可读取,不需要安装 `zleap-sag` 或访问原向量库、事件表。
|
|
167
|
+
|
|
168
|
+
此模式支持搜索、分页、`read_chunk()`、`read_outline()` 和 `source_state()`。
|
|
169
|
+
原 SAG1 业务表保持只读,写入、删除和持久处理任务继续由 SAG1 管理;这些调用
|
|
170
|
+
在 SAG2 中会明确报 `sag.read_only_storage`,`capabilities()` 返回实际可用能力。
|
|
171
|
+
启动只补建 `sag2_state` / `sag2_search_sessions` 两张辅助表,需要相应建表权限;
|
|
172
|
+
翻页仍会写会话状态,SAG1/SAG2 的分页结果不会混用。
|
|
173
|
+
|
|
174
|
+
SAG1 的后续写入会使缓存刷新、旧游标过期,包括没有更新 manifest 的普通
|
|
175
|
+
`index()` 写入。为此,当前每次读取与游标校验都会扫描请求数据源的段落并计算
|
|
176
|
+
可见文本指纹,成本随范围内数据量增长。不提供旧 SAG2 数据向 SAG1 的迁移。
|
|
177
|
+
|
|
178
|
+
会话和录音转写支持按完整单元重叠切块。对 `parse()` 返回的会话或录音结果使用:
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
from zleap.sag2 import ChunkOptions
|
|
182
|
+
|
|
183
|
+
chunk_set = await engine.chunk(
|
|
184
|
+
parsed,
|
|
185
|
+
ChunkOptions(strategy="overlap", max_tokens=800, overlap_tokens=100),
|
|
186
|
+
)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
下一块会尽可能携带上一块末尾连续的完整消息或转写单元。重叠部分的 token 数
|
|
190
|
+
不超过 `overlap_tokens`,同时为新单元预留 `max_tokens` 内的空间;计算包含说话人
|
|
191
|
+
标签和换行。单元放不下时减少或取消重叠,不截断消息。单条超长单元仍完整保留,
|
|
192
|
+
因此可能单独超过 `max_tokens`。重叠单元保留原始文本、引用及时间范围。
|
|
193
|
+
`overlap_tokens` 默认是 0,表示不重叠;会话默认的时间窗口和录音默认的 token
|
|
194
|
+
窗口不受影响。
|
|
195
|
+
|
|
196
|
+
`SearchOptions` 配置 SAG2 候选数、扩展词数、追加轮数和输出数量;默认 100/20/2/10。
|
|
197
|
+
搜索失败会抛出异常,JEV 可重试错误最多尝试四次。
|
|
198
|
+
|
|
199
|
+
分页搜索沿用 `zleap-sag` 的调用方式:
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
from zleap.sag2 import SearchPageRequest
|
|
203
|
+
|
|
204
|
+
# request 是包含 query、scope、options 的 SearchRequest。
|
|
205
|
+
page = await engine.search_page(SearchPageRequest(request=request, page_size=20))
|
|
206
|
+
for hit in page.result.chunks:
|
|
207
|
+
print(hit.score, hit.content)
|
|
208
|
+
if page.next_cursor is not None:
|
|
209
|
+
page = await engine.search_page(
|
|
210
|
+
SearchPageRequest(cursor=page.next_cursor, cursor_request=request)
|
|
211
|
+
)
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
首次执行 SAG2 并持久化结果,后续翻页不再调用 JEV,可跨进程与重启使用。
|
|
215
|
+
总数受搜索的 `top_k` 限制;默认每页 50 项、有效期 300 秒。
|
|
216
|
+
问题或范围不匹配、游标篡改会报 `CursorInvalidError`;到期或相关数据源变更会报
|
|
217
|
+
`CursorExpiredError`,调用方应重新搜索。过期会话通过 `maintain()` 有界清理。
|
|
218
|
+
|
|
219
|
+
指定数据库时,向 `EngineConfig(relational=RelationalConfig(...))` 传入提供方与
|
|
220
|
+
对应的异步连接地址。`sqlite` 使用 `sqlite+aiosqlite:///...`,`mysql` 与
|
|
221
|
+
`oceanbase` 使用 `mysql+aiomysql://...`,`postgres` 使用
|
|
222
|
+
`postgresql+asyncpg://...`;凭据由应用配置提供。
|
|
223
|
+
|
|
224
|
+
详细说明见仓库中的[架构文档](https://github.com/Zleap-AI/zleap/blob/main/packages/sag2/docs/architecture.md)、
|
|
225
|
+
[开发与验证](https://github.com/Zleap-AI/zleap/blob/main/packages/sag2/docs/reproduction.md)和
|
|
226
|
+
[接口兼容说明](https://github.com/Zleap-AI/zleap/blob/main/packages/sag2/docs/api-compatibility.md)。
|
|
227
|
+
这些文档也包含在源码包的 `docs/` 目录中。
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# zleap-sag2
|
|
2
|
+
|
|
3
|
+
SAG2 原文检索引擎:统一词法召回、多轮 JEV 证据评分和本地多样性排序。
|
|
4
|
+
支持 SQLite、MySQL、PostgreSQL 和 OceanBase。连接已有 SAG1 库时,自动从
|
|
5
|
+
`source_chunk` 读取现有段落;空库使用 SAG2 自有存储。
|
|
6
|
+
|
|
7
|
+
发布到 PyPI 后,可按包名安装:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
pip install zleap-sag2
|
|
11
|
+
# MySQL / OceanBase
|
|
12
|
+
pip install 'zleap-sag2[mysql]'
|
|
13
|
+
# PostgreSQL
|
|
14
|
+
pip install 'zleap-sag2[postgres]'
|
|
15
|
+
# 电子表格转换
|
|
16
|
+
pip install 'zleap-sag2[tables]'
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
从源码安装时,先进入包含本文件和 `pyproject.toml` 的包目录,再执行
|
|
20
|
+
`pip install .`;可选依赖使用 `pip install '.[tables]'` 等形式。
|
|
21
|
+
也可通过 `pip install` 指定已下载 wheel 文件的实际路径。
|
|
22
|
+
|
|
23
|
+
### 独立开发
|
|
24
|
+
|
|
25
|
+
可以直接在 IDE 或 Codex 中打开包目录:仓库中的 `packages/sag2`,或解压后的
|
|
26
|
+
源码包根目录。以下命令均在该目录执行。源码、测试、脚本、文档和环境变量模板
|
|
27
|
+
均在本目录内;使用仓库检出时,Git 提交仍属于 `zleap` 根仓库。
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
make install # 本目录 .venv,只安装 SAG2 和开发/表格依赖
|
|
31
|
+
make verify # lint、离线测试、构建、产物元数据检查
|
|
32
|
+
cp .env.example .env # 需要连接模型服务时再填写
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
也可在根目录运行 `make -C packages/sag2 verify`。根目录的 `make verify` 仍检查 SAG。
|
|
36
|
+
本包独立版本为 `src/zleap/sag2/__about__.py`,发布 tag 为 `zleap-sag2/vX.Y.Z`;
|
|
37
|
+
发布配置见仓库的 [RELEASING.md](https://github.com/Zleap-AI/zleap/blob/main/RELEASING.md)。`zleap` 元包暂不依赖 SAG2,
|
|
38
|
+
使用者需单独安装 `zleap-sag2`。
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
import asyncio
|
|
42
|
+
from zleap.sag2 import DataEngine, EngineConfig
|
|
43
|
+
from zleap.sag2 import TextSource, SourceDescriptor, SearchScope, SearchRequest
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
async def main():
|
|
47
|
+
config = EngineConfig.from_env(".env")
|
|
48
|
+
async with DataEngine(config, data_source_id="demo") as engine:
|
|
49
|
+
await engine.ingest(
|
|
50
|
+
TextSource(
|
|
51
|
+
text="# 示例\nAlice 出生在北京。",
|
|
52
|
+
descriptor=SourceDescriptor(
|
|
53
|
+
data_source_id="demo",
|
|
54
|
+
source_id="alice",
|
|
55
|
+
source_type="text",
|
|
56
|
+
),
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
result = await engine.search(
|
|
60
|
+
SearchRequest(query="Alice 出生在哪里?", scope=SearchScope(data_source_ids=("demo",)))
|
|
61
|
+
)
|
|
62
|
+
for hit in result.chunks:
|
|
63
|
+
print(hit.score, hit.content)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
asyncio.run(main())
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`parse` 和 `chunk` 可在启动数据库前使用。`index(ChunkSet)` 直接保存已有分块。
|
|
70
|
+
|
|
71
|
+
### 配置
|
|
72
|
+
|
|
73
|
+
关系库环境变量与 SAG1 一致,使用 `EngineConfig.from_env(".env")` 显式读取文件;
|
|
74
|
+
`EngineConfig.from_env()` 只读取进程环境,不自动寻找 `.env`。最小配置:
|
|
75
|
+
|
|
76
|
+
```dotenv
|
|
77
|
+
SAG_RELATIONAL_PROVIDER=sqlite
|
|
78
|
+
SAG_DATA_DIR=./.zleap
|
|
79
|
+
DECISION_ENDPOINT=https://api.typesafe.ai/v1/systemone
|
|
80
|
+
DECISION_MODEL=jev-latest
|
|
81
|
+
DECISION_API_KEY=your-key
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
推荐使用 [JEV(TypeSafe)](https://typesafe.ai/) 或
|
|
85
|
+
[D1-ultra(Liquid AI)](https://www.liquid.ai/blog/d1-ultra) 作为决策模型。
|
|
86
|
+
使用 D1-ultra 时,将接口改为 `https://api.liquid.ai/decisions/v1/systemone`、
|
|
87
|
+
模型改为 `d1-ultra`,并填写 Liquid AI 的 API Key。使用其他服务商时,
|
|
88
|
+
模型 ID 与接口地址以该服务商为准,三项配置需对应同一服务。
|
|
89
|
+
|
|
90
|
+
决策请求的 token 预算使用随包提供的 `o200k_base` 编码资源;首次启动无需下载
|
|
91
|
+
tokenizer 或预置缓存。实际用量仍取决策服务返回的 `usage`。
|
|
92
|
+
|
|
93
|
+
SQLite 使用 `<SAG_DATA_DIR>/sag.db`,默认 `.zleap/sag.db`。服务库使用
|
|
94
|
+
`SAG_RELATIONAL_HOST` / `PORT` / `USER` / `PASSWORD` / `DATABASE`,连接池、超时及
|
|
95
|
+
PostgreSQL TLS 参数同样沿用 `SAG_RELATIONAL_*`。默认端口为 MySQL 3306、
|
|
96
|
+
PostgreSQL 5432、OceanBase 2881。
|
|
97
|
+
|
|
98
|
+
`RELATIONAL_PROVIDER`、`DATA_DIR`、`DB_HOST` / `DB_PORT` / `DB_USER` /
|
|
99
|
+
`DB_PASSWORD` / `DB_NAME`、`DB_POOL_*` / `DB_MAX_OVERFLOW` / `DB_CONNECT_TIMEOUT` /
|
|
100
|
+
`DB_COMMAND_TIMEOUT`、`DB_TLS_*` 也与 SAG1 一致。同名进程变量覆盖文件值;
|
|
101
|
+
同时设置等价名称时,`SAG_*` 优先,空值视为未设置。
|
|
102
|
+
|
|
103
|
+
SAG1 的配置文件可以直接复用,SAG2 不使用其中的 LLM、Embedding、向量库和
|
|
104
|
+
事件配置;搜索需补充 `DECISION_*`。未配置任何决策模型参数时仍可解析、切块、读取与续页,
|
|
105
|
+
部分配置决策模型参数会在加载时明确报错。也可以直接构造 `EngineConfig` 和
|
|
106
|
+
`RelationalConfig`,显式配置不读取环境变量。
|
|
107
|
+
|
|
108
|
+
### 直接搜索 SAG1 已有数据
|
|
109
|
+
|
|
110
|
+
用 `EngineConfig.from_env(".env")` 读取 SAG1 的连接配置,补充决策模型配置后直接调用
|
|
111
|
+
`search()` 或 `search_page()`,无需先调用 `index()`。
|
|
112
|
+
引擎启动时识别 `source_chunk`,沿用原段落 ID,读取 `article` / `chat_conversation`
|
|
113
|
+
补充来源信息,并遵守活动 generation、来源删除和数据源停用状态。normal / lite
|
|
114
|
+
的文本关系表均可读取,不需要安装 `zleap-sag` 或访问原向量库、事件表。
|
|
115
|
+
|
|
116
|
+
此模式支持搜索、分页、`read_chunk()`、`read_outline()` 和 `source_state()`。
|
|
117
|
+
原 SAG1 业务表保持只读,写入、删除和持久处理任务继续由 SAG1 管理;这些调用
|
|
118
|
+
在 SAG2 中会明确报 `sag.read_only_storage`,`capabilities()` 返回实际可用能力。
|
|
119
|
+
启动只补建 `sag2_state` / `sag2_search_sessions` 两张辅助表,需要相应建表权限;
|
|
120
|
+
翻页仍会写会话状态,SAG1/SAG2 的分页结果不会混用。
|
|
121
|
+
|
|
122
|
+
SAG1 的后续写入会使缓存刷新、旧游标过期,包括没有更新 manifest 的普通
|
|
123
|
+
`index()` 写入。为此,当前每次读取与游标校验都会扫描请求数据源的段落并计算
|
|
124
|
+
可见文本指纹,成本随范围内数据量增长。不提供旧 SAG2 数据向 SAG1 的迁移。
|
|
125
|
+
|
|
126
|
+
会话和录音转写支持按完整单元重叠切块。对 `parse()` 返回的会话或录音结果使用:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from zleap.sag2 import ChunkOptions
|
|
130
|
+
|
|
131
|
+
chunk_set = await engine.chunk(
|
|
132
|
+
parsed,
|
|
133
|
+
ChunkOptions(strategy="overlap", max_tokens=800, overlap_tokens=100),
|
|
134
|
+
)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
下一块会尽可能携带上一块末尾连续的完整消息或转写单元。重叠部分的 token 数
|
|
138
|
+
不超过 `overlap_tokens`,同时为新单元预留 `max_tokens` 内的空间;计算包含说话人
|
|
139
|
+
标签和换行。单元放不下时减少或取消重叠,不截断消息。单条超长单元仍完整保留,
|
|
140
|
+
因此可能单独超过 `max_tokens`。重叠单元保留原始文本、引用及时间范围。
|
|
141
|
+
`overlap_tokens` 默认是 0,表示不重叠;会话默认的时间窗口和录音默认的 token
|
|
142
|
+
窗口不受影响。
|
|
143
|
+
|
|
144
|
+
`SearchOptions` 配置 SAG2 候选数、扩展词数、追加轮数和输出数量;默认 100/20/2/10。
|
|
145
|
+
搜索失败会抛出异常,JEV 可重试错误最多尝试四次。
|
|
146
|
+
|
|
147
|
+
分页搜索沿用 `zleap-sag` 的调用方式:
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
from zleap.sag2 import SearchPageRequest
|
|
151
|
+
|
|
152
|
+
# request 是包含 query、scope、options 的 SearchRequest。
|
|
153
|
+
page = await engine.search_page(SearchPageRequest(request=request, page_size=20))
|
|
154
|
+
for hit in page.result.chunks:
|
|
155
|
+
print(hit.score, hit.content)
|
|
156
|
+
if page.next_cursor is not None:
|
|
157
|
+
page = await engine.search_page(
|
|
158
|
+
SearchPageRequest(cursor=page.next_cursor, cursor_request=request)
|
|
159
|
+
)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
首次执行 SAG2 并持久化结果,后续翻页不再调用 JEV,可跨进程与重启使用。
|
|
163
|
+
总数受搜索的 `top_k` 限制;默认每页 50 项、有效期 300 秒。
|
|
164
|
+
问题或范围不匹配、游标篡改会报 `CursorInvalidError`;到期或相关数据源变更会报
|
|
165
|
+
`CursorExpiredError`,调用方应重新搜索。过期会话通过 `maintain()` 有界清理。
|
|
166
|
+
|
|
167
|
+
指定数据库时,向 `EngineConfig(relational=RelationalConfig(...))` 传入提供方与
|
|
168
|
+
对应的异步连接地址。`sqlite` 使用 `sqlite+aiosqlite:///...`,`mysql` 与
|
|
169
|
+
`oceanbase` 使用 `mysql+aiomysql://...`,`postgres` 使用
|
|
170
|
+
`postgresql+asyncpg://...`;凭据由应用配置提供。
|
|
171
|
+
|
|
172
|
+
详细说明见仓库中的[架构文档](https://github.com/Zleap-AI/zleap/blob/main/packages/sag2/docs/architecture.md)、
|
|
173
|
+
[开发与验证](https://github.com/Zleap-AI/zleap/blob/main/packages/sag2/docs/reproduction.md)和
|
|
174
|
+
[接口兼容说明](https://github.com/Zleap-AI/zleap/blob/main/packages/sag2/docs/api-compatibility.md)。
|
|
175
|
+
这些文档也包含在源码包的 `docs/` 目录中。
|