xists 0.7.0__py3-none-any.whl
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.
- .env.example +54 -0
- LICENSE +21 -0
- README.md +238 -0
- README.zh-CN.md +218 -0
- docs/demo.md +160 -0
- docs/performance.md +76 -0
- docs/record-schema.md +430 -0
- docs/release.md +127 -0
- docs/scale-2k-diagnosis.md +82 -0
- docs/scaling-experiment.md +156 -0
- docs/usage.md +663 -0
- docs/v0.6.0-completion.md +32 -0
- examples/ci-smoke/eval-cases.json +19 -0
- examples/ci-smoke/repos.txt +2 -0
- examples/eval-cases-extended.json +1532 -0
- examples/eval-cases-smoke.json +182 -0
- examples/eval-cases.json +1377 -0
- pyproject.toml +56 -0
- repos.txt +200 -0
- scripts/bench_search.py +85 -0
- scripts/check_eval_report.py +173 -0
- scripts/diagnose_retrieval_candidates.py +142 -0
- scripts/generate_stratified_eval.py +423 -0
- scripts/generate_synthetic_index.py +143 -0
- scripts/smoke_check.py +115 -0
- tests/test_api.py +120 -0
- tests/test_check_eval_report.py +153 -0
- tests/test_cli.py +2970 -0
- tests/test_diagnose_retrieval_candidates.py +46 -0
- tests/test_eval.py +821 -0
- tests/test_examples.py +75 -0
- tests/test_generate_stratified_eval.py +101 -0
- tests/test_generate_synthetic_index.py +64 -0
- tests/test_github_ingest.py +536 -0
- tests/test_llm_profile.py +281 -0
- tests/test_package.py +12 -0
- tests/test_packaging.py +38 -0
- tests/test_performance_smoke.py +44 -0
- tests/test_query_transform.py +97 -0
- tests/test_rerank.py +128 -0
- tests/test_search.py +961 -0
- xists/__init__.py +3 -0
- xists/api.py +70 -0
- xists/cli.py +2438 -0
- xists/eval/__init__.py +1 -0
- xists/eval/inspect.py +239 -0
- xists/eval/judge.py +187 -0
- xists/eval/run.py +355 -0
- xists/eval/schema.py +131 -0
- xists/ingest/__init__.py +1 -0
- xists/ingest/github.py +690 -0
- xists/profile/__init__.py +1 -0
- xists/profile/llm.py +289 -0
- xists/records.py +229 -0
- xists/search/__init__.py +1 -0
- xists/search/confidence.py +99 -0
- xists/search/embed.py +322 -0
- xists/search/index.py +167 -0
- xists/search/query.py +865 -0
- xists/search/rerank.py +176 -0
- xists/search/transform.py +126 -0
- xists-0.7.0.dist-info/METADATA +263 -0
- xists-0.7.0.dist-info/RECORD +66 -0
- xists-0.7.0.dist-info/WHEEL +4 -0
- xists-0.7.0.dist-info/entry_points.txt +2 -0
- xists-0.7.0.dist-info/licenses/LICENSE +21 -0
.env.example
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# GitHub ingestion
|
|
2
|
+
# Single token:
|
|
3
|
+
GITHUB_TOKEN=your_github_token_here
|
|
4
|
+
# Multiple tokens (comma-separated, for higher rate limits):
|
|
5
|
+
# GITHUB_TOKENS=tok1,tok2,tok3
|
|
6
|
+
|
|
7
|
+
# LLM profile generation (OpenAI-compatible chat completions endpoint)
|
|
8
|
+
# Used only during ingest to turn collected repo evidence into a structured profile.
|
|
9
|
+
# Works with OpenAI, vLLM, Ollama, Together, DeepSeek, Moonshot, etc.
|
|
10
|
+
LLM_API_KEY=your_llm_api_key_here
|
|
11
|
+
LLM_BASE_URL=https://api.deepseek.com
|
|
12
|
+
LLM_MODEL=deepseek-v4-pro
|
|
13
|
+
|
|
14
|
+
# Optional query canonicalization (OpenAI-compatible chat completions endpoint)
|
|
15
|
+
# Used only with `xists search` or `xists eval run` plus --query-transform-mode.
|
|
16
|
+
# It can convert queries into an English retrieval expression for an
|
|
17
|
+
# English-dominant corpus while xists keeps the local index and ranking.
|
|
18
|
+
QUERY_TRANSFORM_API_KEY=your_query_transform_api_key_here
|
|
19
|
+
QUERY_TRANSFORM_BASE_URL=https://api.example.com/v1
|
|
20
|
+
QUERY_TRANSFORM_MODEL=your_chat_model
|
|
21
|
+
|
|
22
|
+
# Embedding vector calculation (OpenAI-compatible embeddings endpoint)
|
|
23
|
+
# Used to compute vectors for:
|
|
24
|
+
# 1. records during `xists index build`
|
|
25
|
+
# 2. the query text during `xists search` / `xists eval run`
|
|
26
|
+
# The endpoint does NOT store your index and does NOT perform vector search.
|
|
27
|
+
# xists keeps vectors in local index.json and does ranking/query locally.
|
|
28
|
+
#
|
|
29
|
+
# IMPORTANT:
|
|
30
|
+
# This single embedding config is shared by:
|
|
31
|
+
# - `xists index build` to embed repository records
|
|
32
|
+
# - `xists search` / `xists eval run` to embed query text
|
|
33
|
+
# The query embedding model must match the model used to build index.json.
|
|
34
|
+
# Do not change EMBEDDING_MODEL after building an index unless you rebuild it:
|
|
35
|
+
# xists index build --force
|
|
36
|
+
#
|
|
37
|
+
# Recommended local CUDA example: BAAI/bge-m3 via TEI on localhost:6597
|
|
38
|
+
# docker-served endpoint: http://localhost:6597/v1 or http://localhost:6597
|
|
39
|
+
# EMBEDDING_API_KEY can be any non-empty placeholder if the local server has no auth.
|
|
40
|
+
EMBEDDING_API_KEY=local
|
|
41
|
+
EMBEDDING_BASE_URL=http://localhost:6597/v1
|
|
42
|
+
EMBEDDING_MODEL=BAAI/bge-m3
|
|
43
|
+
|
|
44
|
+
# Remote embedding APIs can also be used as calculate-only endpoints.
|
|
45
|
+
# They compute vectors, while xists still searches the local index.
|
|
46
|
+
# Example:
|
|
47
|
+
# EMBEDDING_API_KEY=your_remote_embedding_api_key_here
|
|
48
|
+
# EMBEDDING_BASE_URL=https://api.openai.com/v1
|
|
49
|
+
# EMBEDDING_MODEL=text-embedding-3-small
|
|
50
|
+
#
|
|
51
|
+
# For a dual-encoder retrieval service that requires a request role field,
|
|
52
|
+
# enable it explicitly. xists then sends `passage` for index builds and
|
|
53
|
+
# `query` for search/evaluation. Leave unset for ordinary embedding APIs.
|
|
54
|
+
# EMBEDDING_INPUT_TYPE_FIELD=input_type
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 UsonTong
|
|
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.
|
README.md
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
<div align="center"><a name="readme-top"></a>
|
|
2
|
+
|
|
3
|
+
# xists
|
|
4
|
+
|
|
5
|
+
Find first. Build later.
|
|
6
|
+
|
|
7
|
+
`xists` is a local semantic search engine for selected lists of GitHub repositories. Check if a similar project already exists before you build it.
|
|
8
|
+
|
|
9
|
+
**English** · [简体中文](./README.zh-CN.md)
|
|
10
|
+
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Why xists?
|
|
16
|
+
|
|
17
|
+
Global GitHub search is often noisy, and traditional keyword matching lacks semantic understanding. `xists` solves this by narrowing the search space: you provide a curated repository list, and `xists` builds a local index for semantic search.
|
|
18
|
+
|
|
19
|
+
- **Before you build**: check if a similar project or existing solution already exists.
|
|
20
|
+
- **Tech decisions**: compare candidates from a curated set using semantic search.
|
|
21
|
+
- **Fast lookups**: quickly find what you need without manually opening dozens of READMEs.
|
|
22
|
+
|
|
23
|
+
## How it works
|
|
24
|
+
|
|
25
|
+
```mermaid
|
|
26
|
+
flowchart LR
|
|
27
|
+
A[Repo List] --> B[Ingest Metadata]
|
|
28
|
+
B --> C[Generate LLM Summaries]
|
|
29
|
+
C --> D[Build Local Index]
|
|
30
|
+
D --> E[Search]
|
|
31
|
+
D -. optional .-> F[Evaluate Ranking]
|
|
32
|
+
F -.-> G[Inspect Misses]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
1. **Ingest**: Provide a list of GitHub repos. `xists` fetches their metadata and READMEs.
|
|
36
|
+
2. **Profile**: It uses an LLM to generate compact, search-optimized summaries for better matching.
|
|
37
|
+
3. **Index**: It builds a local JSON embedding index.
|
|
38
|
+
4. **Search**: You query the index using semantic search.
|
|
39
|
+
|
|
40
|
+
## Local-first index, explicit model endpoints
|
|
41
|
+
|
|
42
|
+
`xists` keeps everything transparent and local:
|
|
43
|
+
- `records.json`: Raw metadata, structure signals, and LLM-generated profiles.
|
|
44
|
+
- `index.json`: The embedding index.
|
|
45
|
+
- `eval-report.json`: Search quality test results.
|
|
46
|
+
|
|
47
|
+
You need a GitHub token for the initial data fetch, plus model endpoints for summaries and embeddings. The records, index, ranking, and evaluation report stay on your machine. An embedding endpoint calculates vectors; xists stores them in local JSON and compares them locally.
|
|
48
|
+
|
|
49
|
+
## Install and first search
|
|
50
|
+
|
|
51
|
+
Requires Python 3.11+. PyPI publication is prepared for v0.7.0 but has not
|
|
52
|
+
yet been authorized; until then, install directly from a checked-out source
|
|
53
|
+
tree:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
python -m pip install -e ".[dev]"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
After v0.7.0 is published, the equivalent package installation will be:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
python -m pip install xists
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Then create a local configuration file and build an index from repositories
|
|
66
|
+
you control:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
cp .env.example .env
|
|
70
|
+
# Set the required GitHub, LLM, and embedding variables in .env.
|
|
71
|
+
|
|
72
|
+
xists ingest github --repos repos.txt --output records.json --report report.json
|
|
73
|
+
xists index build --records records.json --output index.json
|
|
74
|
+
xists search "open source firebase alternative" --index index.json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
See [the demo walkthrough](docs/demo.md) for endpoint checks, concurrency,
|
|
78
|
+
evaluation, and troubleshooting. No current-schema demo records/index download
|
|
79
|
+
is published yet; the first Release asset will be created only after it passes
|
|
80
|
+
`records validate` and `index verify`.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Quickstart
|
|
85
|
+
|
|
86
|
+
Requires Python 3.11+.
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Install
|
|
90
|
+
python -m pip install -e ".[dev]"
|
|
91
|
+
|
|
92
|
+
# Set up config
|
|
93
|
+
cp .env.example .env
|
|
94
|
+
# Edit .env with your GitHub token, LLM model, and embedding model
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Run the pipeline:**
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
# 1. Fetch data & generate summaries
|
|
101
|
+
xists ingest github \
|
|
102
|
+
--repos repos.txt \
|
|
103
|
+
--output demo-records.json \
|
|
104
|
+
--report demo-report.json \
|
|
105
|
+
--github-api graphql
|
|
106
|
+
|
|
107
|
+
# 2. Build the local index
|
|
108
|
+
xists index build \
|
|
109
|
+
--records demo-records.json \
|
|
110
|
+
--output demo-index.json
|
|
111
|
+
|
|
112
|
+
# 3. Search!
|
|
113
|
+
xists search "open source firebase alternative" --index demo-index.json
|
|
114
|
+
xists search "open source firebase alternative" --index demo-index.json --format json
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The commands above generate local files and may call the endpoints configured
|
|
118
|
+
in `.env`; use `records.json` / `index.json` instead if you do not want files
|
|
119
|
+
named as demo artifacts.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## Python API
|
|
124
|
+
|
|
125
|
+
Use the stable API when another Python program needs the same search behavior
|
|
126
|
+
as the CLI. Configuration is always explicit; importing `xists.api` does not
|
|
127
|
+
read `.env` or send network requests.
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from xists.api import load_index, search
|
|
131
|
+
from xists.search.embed import EmbeddingConfig
|
|
132
|
+
|
|
133
|
+
index = load_index("index.json")
|
|
134
|
+
config = EmbeddingConfig(
|
|
135
|
+
api_key="your-key",
|
|
136
|
+
base_url="https://your-embedding-endpoint/v1",
|
|
137
|
+
model="your-embedding-model",
|
|
138
|
+
)
|
|
139
|
+
result = search("open source firebase alternative", index, embedding_config=config, top_k=5)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`search()` may call the endpoint in `config` to embed the query. It raises
|
|
143
|
+
actionable Python exceptions for invalid indexes, incompatible embedding models,
|
|
144
|
+
and endpoint failures instead of printing or terminating the process.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Data, security, and privacy
|
|
149
|
+
|
|
150
|
+
- `.env` and token files are read only from your local machine; xists does not
|
|
151
|
+
commit, print, telemetry-report, or upload their secret values.
|
|
152
|
+
- `ingest github` sends your GitHub token only to GitHub. `profile refresh` and
|
|
153
|
+
ingest-time profile generation send repository text to the configured LLM
|
|
154
|
+
endpoint. `index build` sends embeddable repository text to the configured
|
|
155
|
+
embedding endpoint; `search` and `eval run` send query text to that endpoint.
|
|
156
|
+
- A local endpoint keeps those requests on your machine or network. A remote
|
|
157
|
+
endpoint receives the corresponding text under that provider's terms; choose
|
|
158
|
+
it only when you are permitted to send the material. xists does not host the
|
|
159
|
+
endpoint, upload your index, or perform vector search remotely.
|
|
160
|
+
- If you share records or indexes, you are responsible for checking repository
|
|
161
|
+
licenses, source content, generated profiles, and any personal or sensitive
|
|
162
|
+
information before distribution.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Search Result Example
|
|
167
|
+
|
|
168
|
+
When you run a search, `xists` returns a compact text view by default for terminal review. Add `--format json` for scripts and agent integrations. v0.2.0 keeps ranking simple: exact repo/name/alias matches are pinned first, then semantic similarity is adjusted by a few explainable metadata signals.
|
|
169
|
+
|
|
170
|
+
Default text output looks like this:
|
|
171
|
+
|
|
172
|
+
```text
|
|
173
|
+
query: hermes ai agent
|
|
174
|
+
intent: functional
|
|
175
|
+
abstained: False
|
|
176
|
+
results: 1
|
|
177
|
+
1. repo: NousResearch/hermes-agent
|
|
178
|
+
url: https://github.com/NousResearch/hermes-agent
|
|
179
|
+
confidence: high_confidence
|
|
180
|
+
score: 0.680000
|
|
181
|
+
summary: An agent-oriented project for Hermes models.
|
|
182
|
+
why: matched metadata terms: agent
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
The JSON output keeps the same ranking evidence in a machine-readable shape:
|
|
186
|
+
|
|
187
|
+
```json
|
|
188
|
+
{
|
|
189
|
+
"query": "hermes ai agent",
|
|
190
|
+
"results": [
|
|
191
|
+
{
|
|
192
|
+
"repo_id": "NousResearch/hermes-agent",
|
|
193
|
+
"url": "https://github.com/NousResearch/hermes-agent",
|
|
194
|
+
"score": 0.68,
|
|
195
|
+
"semantic_score": 0.63,
|
|
196
|
+
"metadata_score": 0.05,
|
|
197
|
+
"confidence": "high_confidence",
|
|
198
|
+
"why": ["matched metadata terms: agent"]
|
|
199
|
+
}
|
|
200
|
+
]
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
`score` is the final ranking score; higher means a stronger match. Use `--format json` when another program or agent needs the structured payload.
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## Optional Evaluation
|
|
209
|
+
|
|
210
|
+
If you update the repository list, regenerate summaries, or change the search setup, `xists` lets you run fixed test cases to sanity-check whether results changed in a meaningful way.
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
pytest
|
|
214
|
+
xists eval run \
|
|
215
|
+
--cases examples/eval-cases.json \
|
|
216
|
+
--index demo-index.json \
|
|
217
|
+
--output demo-eval-report.json
|
|
218
|
+
|
|
219
|
+
xists eval inspect --report demo-eval-report.json --status serious_mismatch
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
The report groups results into pragmatic categories:
|
|
223
|
+
- **Exact match**: The specific target repo was #1.
|
|
224
|
+
- **Acceptable alternative**: Not the exact target, but a valid substitute (e.g., returning Vue when you asked for a React-like framework).
|
|
225
|
+
- **Serious mismatch**: The top result missed the core intent.
|
|
226
|
+
- **Insufficient evidence**: The indexed data was too thin to judge.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Commands
|
|
231
|
+
|
|
232
|
+
- `xists doctor`: Check config and file status; add `--check-endpoints` or `--strict` to probe the embedding service.
|
|
233
|
+
- `xists ingest github`: Fetch repo metadata and generate summaries.
|
|
234
|
+
- `xists index build`: Build or incrementally update the local index.
|
|
235
|
+
- `xists search "query"`: Query the local index with readable terminal output by default; add `--format json` for scripts and agents.
|
|
236
|
+
- `xists eval cases` / `xists eval run` / `xists eval inspect`: Validate the dataset and run/review ranking tests.
|
|
237
|
+
- `xists records validate` / `xists records stats` / `xists records inspect`: Check record quality without printing huge payloads to your terminal.
|
|
238
|
+
- `xists index stats` / `xists index verify`: Summarize an index and confirm it is in sync with records.
|
README.zh-CN.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
<div align="center"><a name="readme-top"></a>
|
|
2
|
+
|
|
3
|
+
# xists
|
|
4
|
+
|
|
5
|
+
先找,再做。
|
|
6
|
+
|
|
7
|
+
`xists` 是一个面向 GitHub 仓库清单的本地语义搜索工具。造轮子前,先用它查查是否有类似项目或现成方案。
|
|
8
|
+
|
|
9
|
+
[English](./README.md) · **简体中文**
|
|
10
|
+
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 为什么写 xists?
|
|
16
|
+
|
|
17
|
+
GitHub 的全局搜索常常伴随较高的信息噪音,而传统的关键词匹配又受限于字面约束。`xists` 的核心思路是通过缩小搜索域来提升精度:基于用户提供的特定仓库清单构建本地索引,从而实现更高效的语义检索。
|
|
18
|
+
|
|
19
|
+
- **动手之前**:通过语义检索查一下有没有类似项目或现成方案。
|
|
20
|
+
- **技术选型**:在候选项目池里快速比对,不用挨个翻 README。
|
|
21
|
+
- **快速定位**:告别精确关键词,用你脑海里的描述直接搜。
|
|
22
|
+
|
|
23
|
+
## 工作流
|
|
24
|
+
|
|
25
|
+
```mermaid
|
|
26
|
+
flowchart LR
|
|
27
|
+
A[仓库清单] --> B[抓取元数据]
|
|
28
|
+
B --> C[LLM 生成结构化摘要]
|
|
29
|
+
C --> D[构建本地索引]
|
|
30
|
+
D --> E[搜索]
|
|
31
|
+
D -. 可选 .-> F[评测排序质量]
|
|
32
|
+
F -.-> G[检查未命中案例]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
1. **拉取**:提供仓库列表,`xists` 通过 GitHub API 抓取它们的元数据和 README。
|
|
36
|
+
2. **总结**:调用 LLM 为每个仓库生成适合被检索的结构化短语和简介。
|
|
37
|
+
3. **索引**:在本地构建基于 Embedding 的 JSON 向量索引。
|
|
38
|
+
4. **搜索**:直接在本地进行语义检索。
|
|
39
|
+
|
|
40
|
+
## 本地索引,模型接口显式配置
|
|
41
|
+
|
|
42
|
+
`xists` 所有的中间产物和结果都透明且受你掌控:
|
|
43
|
+
- `records.json`:存放仓库的基础信息和 LLM 生成的特征画像。
|
|
44
|
+
- `index.json`:本地的 Embedding 索引。
|
|
45
|
+
- `eval-report.json`:检索质量评测报告。
|
|
46
|
+
|
|
47
|
+
首次采集需要 GitHub token;生成摘要与 embedding 还需要模型接口。records、index、排序和评测报告都保留在本机。embedding 接口只负责计算向量;xists 把向量保存为本地 JSON,并在本地完成相似度计算与排序。
|
|
48
|
+
|
|
49
|
+
## 安装与第一次搜索
|
|
50
|
+
|
|
51
|
+
环境要求:Python 3.11+。v0.7.0 正在准备 PyPI 首发,但尚未获授权发布;在此之前,请从检出的源码目录安装:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
python -m pip install -e ".[dev]"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
v0.7.0 发布后,对应的安装方式会是:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
python -m pip install xists
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
然后创建本地配置,并从你有权处理的仓库清单构建索引:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
cp .env.example .env
|
|
67
|
+
# 在 .env 中填写 GitHub、LLM 和 embedding 配置。
|
|
68
|
+
|
|
69
|
+
xists ingest github --repos repos.txt --output records.json --report report.json
|
|
70
|
+
xists index build --records records.json --output index.json
|
|
71
|
+
xists search "open source firebase alternative" --index index.json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
完整的接口预检、并发、评测和排错说明请看[演示流程](docs/demo.md)。目前尚未发布符合当前 schema 的 demo records/index 下载包;首个 Release asset 必须先通过 `records validate` 与 `index verify` 才会提供。
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 快速开始
|
|
79
|
+
|
|
80
|
+
环境要求:Python 3.11+。
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# 安装
|
|
84
|
+
python -m pip install -e ".[dev]"
|
|
85
|
+
|
|
86
|
+
# 配置
|
|
87
|
+
cp .env.example .env
|
|
88
|
+
# 在 .env 中填入你的 GitHub token、LLM 模型和 embedding 模型配置
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**跑通全流程:**
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# 1. 抓取数据并生成总结
|
|
95
|
+
xists ingest github \
|
|
96
|
+
--repos repos.txt \
|
|
97
|
+
--output demo-records.json \
|
|
98
|
+
--report demo-report.json \
|
|
99
|
+
--github-api graphql
|
|
100
|
+
|
|
101
|
+
# 2. 构建本地向量索引
|
|
102
|
+
xists index build \
|
|
103
|
+
--records demo-records.json \
|
|
104
|
+
--output demo-index.json
|
|
105
|
+
|
|
106
|
+
# 3. 开始搜索!
|
|
107
|
+
xists search "open source firebase alternative" --index demo-index.json
|
|
108
|
+
xists search "open source firebase alternative" --index demo-index.json --format json
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
上面的命令会生成本地文件,并可能调用 `.env` 里配置的接口;若不希望使用 demo 命名,请改用 `records.json` 和 `index.json`。
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Python API
|
|
116
|
+
|
|
117
|
+
其他 Python 程序需要使用和 CLI 相同的搜索逻辑时,可以使用稳定 API。配置必须显式传入;导入 `xists.api` 不会读取 `.env`,也不会发起网络请求。
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from xists.api import load_index, search
|
|
121
|
+
from xists.search.embed import EmbeddingConfig
|
|
122
|
+
|
|
123
|
+
index = load_index("index.json")
|
|
124
|
+
config = EmbeddingConfig(
|
|
125
|
+
api_key="your-key",
|
|
126
|
+
base_url="https://your-embedding-endpoint/v1",
|
|
127
|
+
model="your-embedding-model",
|
|
128
|
+
)
|
|
129
|
+
result = search("open source firebase alternative", index, embedding_config=config, top_k=5)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
`search()` 会按需调用 `config` 指定的接口来计算查询向量。无效 index、embedding 模型不兼容或接口失败会以可捕获的 Python 异常返回,不会打印信息或结束进程。
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## 数据、安全与隐私
|
|
137
|
+
|
|
138
|
+
- `.env` 和 token 文件只在本地读取;xists 不会提交、打印、遥测上报或上传其中的密钥。
|
|
139
|
+
- `ingest github` 只会把 GitHub token 发给 GitHub。`profile refresh` 与 ingest 中生成 profile 的步骤会把仓库文本发送给你配置的 LLM 接口。`index build` 会把可 embedding 的仓库文本发送给 embedding 接口;`search` 和 `eval run` 会把查询文本发送给该接口。
|
|
140
|
+
- 选择本地接口时,请求会留在你的机器或网络中;选择远端接口时,对应文本会发送给该提供商,并受其条款约束。xists 不托管接口、不上传你的 index,也不在远端执行向量搜索。
|
|
141
|
+
- 若你分享 records 或 index,需要自行检查仓库许可证、源内容、生成的 profile,以及其中是否包含个人或敏感信息。
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## 检索结果示例
|
|
146
|
+
|
|
147
|
+
每次搜索,`xists` 默认都会输出适合终端阅读的紧凑文本。脚本和 agent 集成可以加 `--format json` 获取结构化结果。v0.2.0 的排序刻意保持简单:先固定精确 repo/name/alias 命中,再用少量可解释 metadata 信号调整语义相似度。
|
|
148
|
+
|
|
149
|
+
默认文本输出类似这样:
|
|
150
|
+
|
|
151
|
+
```text
|
|
152
|
+
query: hermes ai agent
|
|
153
|
+
intent: functional
|
|
154
|
+
abstained: False
|
|
155
|
+
results: 1
|
|
156
|
+
1. repo: NousResearch/hermes-agent
|
|
157
|
+
url: https://github.com/NousResearch/hermes-agent
|
|
158
|
+
confidence: high_confidence
|
|
159
|
+
score: 0.680000
|
|
160
|
+
summary: An agent-oriented project for Hermes models.
|
|
161
|
+
why: matched metadata terms: agent
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
JSON 输出保留相同的排序证据,适合机器读取:
|
|
165
|
+
|
|
166
|
+
```json
|
|
167
|
+
{
|
|
168
|
+
"query": "hermes ai agent",
|
|
169
|
+
"results": [
|
|
170
|
+
{
|
|
171
|
+
"repo_id": "NousResearch/hermes-agent",
|
|
172
|
+
"url": "https://github.com/NousResearch/hermes-agent",
|
|
173
|
+
"score": 0.68,
|
|
174
|
+
"semantic_score": 0.63,
|
|
175
|
+
"metadata_score": 0.05,
|
|
176
|
+
"confidence": "high_confidence",
|
|
177
|
+
"why": ["matched metadata terms: agent"]
|
|
178
|
+
}
|
|
179
|
+
]
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
`score` 是最终排序分数,越高代表匹配越强。其他程序或 agent 需要结构化 payload 时使用 `--format json`。
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 可选评测
|
|
188
|
+
|
|
189
|
+
如果你更换了仓库清单、重新生成了摘要,或调整了搜索配置,`xists` 内置的评测工具可以用固定测试用例帮你检查结果是否有明显变化:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
pytest
|
|
193
|
+
xists eval run \
|
|
194
|
+
--cases examples/eval-cases.json \
|
|
195
|
+
--index demo-index.json \
|
|
196
|
+
--output demo-eval-report.json
|
|
197
|
+
|
|
198
|
+
# 直接查看错误的 Case
|
|
199
|
+
xists eval inspect --report demo-eval-report.json --status serious_mismatch
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
评测报告会将结果分为以下几种务实的类型:
|
|
203
|
+
- **精确命中**:第一名就是预期中的目标仓库。
|
|
204
|
+
- **可接受替代**:第一名不是指定仓库,但也是个合理的同类竞品(比如你搜 React 相关的,它推了 Vue)。
|
|
205
|
+
- **明显不匹配**:第一名完全不符合搜索意图。
|
|
206
|
+
- **证据不足**:索引的数据太少,没法客观判断。
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 常用命令一览
|
|
211
|
+
|
|
212
|
+
- `xists doctor`:检查本地配置和文件状态;加 `--check-endpoints` 或 `--strict` 可探测 embedding 服务。
|
|
213
|
+
- `xists ingest github`:拉取仓库信息并生成短语摘要。
|
|
214
|
+
- `xists index build`:构建或增量更新本地向量索引。
|
|
215
|
+
- `xists search "query"`:执行搜索,默认输出适合终端阅读;加 `--format json` 可输出给脚本和 agent 使用的结构化结果。
|
|
216
|
+
- `xists eval cases` / `xists eval run` / `xists eval inspect`:校验评测集并运行、检查检索评测。
|
|
217
|
+
- `xists records validate` / `xists records stats` / `xists records inspect`:检查 records 质量,避免终端被长 JSON 刷屏。
|
|
218
|
+
- `xists index stats` / `xists index verify`:概览 index,并确认它和 records 仍然同步。
|
docs/demo.md
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Demo Workflow
|
|
2
|
+
|
|
3
|
+
This guide walks through the smallest end-to-end xists workflow using the committed demo inputs.
|
|
4
|
+
|
|
5
|
+
## Files
|
|
6
|
+
|
|
7
|
+
- `repos.txt`: the current demo repository list in the project root
|
|
8
|
+
- `examples/eval-cases.json`: committed 100-case evaluation baseline
|
|
9
|
+
- `examples/eval-cases-extended.json`: optional 112-case evaluation dataset for broader checking
|
|
10
|
+
|
|
11
|
+
## 1. Install
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
python -m pip install -e ".[dev]"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 2. Configure credentials
|
|
18
|
+
|
|
19
|
+
Create a local `.env` file:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
cp .env.example .env
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Set the required GitHub, LLM, and embedding credentials in `.env`.
|
|
26
|
+
|
|
27
|
+
## 3. Preflight and endpoint checks
|
|
28
|
+
|
|
29
|
+
Before spending GitHub or LLM quota, verify the local files and configuration:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
xists doctor \
|
|
33
|
+
--records demo-records.json \
|
|
34
|
+
--index demo-index.json \
|
|
35
|
+
--cases examples/eval-cases.json
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`doctor` returns JSON. Missing generated files are warnings because the demo may
|
|
39
|
+
not have been generated yet. Missing embedding or LLM variables are errors with
|
|
40
|
+
`next_steps` entries showing what to set in `.env`.
|
|
41
|
+
|
|
42
|
+
When your embedding service is supposed to be running, probe it with a real
|
|
43
|
+
request before building an index, searching, or running eval:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
xists doctor \
|
|
47
|
+
--records demo-records.json \
|
|
48
|
+
--index demo-index.json \
|
|
49
|
+
--cases examples/eval-cases.json \
|
|
50
|
+
--check-endpoints
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Use `--strict` in scripts or CI-style smoke checks when endpoint failures should
|
|
54
|
+
make the command exit non-zero:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
xists doctor \
|
|
58
|
+
--records demo-records.json \
|
|
59
|
+
--index demo-index.json \
|
|
60
|
+
--cases examples/eval-cases.json \
|
|
61
|
+
--check-endpoints \
|
|
62
|
+
--strict
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
If the probe cannot connect, start the embedding server referenced by
|
|
66
|
+
`EMBEDDING_BASE_URL`, confirm the URL is the API root such as
|
|
67
|
+
`http://localhost:6597/v1`, and rerun the strict doctor command before retrying
|
|
68
|
+
`index build`, `search`, or `eval run`.
|
|
69
|
+
|
|
70
|
+
## 4. Ingest example repositories
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
xists ingest github \
|
|
74
|
+
--repos repos.txt \
|
|
75
|
+
--output demo-records.json \
|
|
76
|
+
--report demo-report.json \
|
|
77
|
+
--github-api graphql \
|
|
78
|
+
--github-batch-size 10 \
|
|
79
|
+
--workers 4
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
This fetches GitHub data, generates LLM profiles, and writes checkpoints as records finish:
|
|
83
|
+
|
|
84
|
+
- `demo-records.json`
|
|
85
|
+
- `demo-report.json`
|
|
86
|
+
|
|
87
|
+
The ingest command prints progress to stderr while it runs. If your LLM endpoint is rate-limited, reduce `--workers` to `1` or `2`.
|
|
88
|
+
|
|
89
|
+
## 5. Build the example index
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
xists index build \
|
|
93
|
+
--records demo-records.json \
|
|
94
|
+
--output demo-index.json
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## 6. Run a few searches
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
xists search "frontend ui library" --index demo-index.json
|
|
101
|
+
xists search "python web framework for building apis" --index demo-index.json
|
|
102
|
+
xists search "open source workflow automation platform" --index demo-index.json
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Expected results vary by model and repository data, but the top results should usually come from the same neighborhood as the query.
|
|
106
|
+
|
|
107
|
+
## 7. Optionally evaluate the demo index
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
xists eval cases --cases examples/eval-cases.json
|
|
111
|
+
xists eval run \
|
|
112
|
+
--cases examples/eval-cases.json \
|
|
113
|
+
--index demo-index.json \
|
|
114
|
+
--output demo-eval-report.json
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The report includes:
|
|
118
|
+
|
|
119
|
+
- hard retrieval metrics such as `exact_hit_at_1`, `acceptable_hit_at_k`, and `mrr_exact`
|
|
120
|
+
- a readable `summary_text` block for exact top-1, acceptable top-1, serious mismatches, abstains, and wrong high-confidence cases
|
|
121
|
+
- `top_misses`, a sorted list of the most actionable failures
|
|
122
|
+
- confidence counts for top-1 predictions
|
|
123
|
+
- per-case top-1 outcomes in `results`
|
|
124
|
+
|
|
125
|
+
Inspect the failures that matter most:
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
xists eval inspect --report demo-eval-report.json
|
|
129
|
+
xists eval inspect --report demo-eval-report.json --status serious_mismatch
|
|
130
|
+
xists eval inspect --report demo-eval-report.json --tag ai
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## 8. Inspect misses and iterate
|
|
134
|
+
|
|
135
|
+
After changing the repository list, regenerating summaries, or adjusting search behavior, rerun:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
xists index build --records demo-records.json --output demo-index.json --force
|
|
139
|
+
xists eval cases --cases examples/eval-cases.json
|
|
140
|
+
xists eval run --cases examples/eval-cases.json --index demo-index.json --output demo-eval-report.json
|
|
141
|
+
xists eval inspect --report demo-eval-report.json --status serious_mismatch
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
That gives you a stable way to sanity-check search behavior before moving on to larger repository lists or evaluation datasets.
|
|
145
|
+
|
|
146
|
+
## Common run failures
|
|
147
|
+
|
|
148
|
+
- `Embedding is required ... Missing environment variables`: copy `.env.example`
|
|
149
|
+
to `.env` and set `EMBEDDING_API_KEY`, `EMBEDDING_BASE_URL`, and
|
|
150
|
+
`EMBEDDING_MODEL`.
|
|
151
|
+
- `Embedding request failed for all configured endpoints`: the embedding server
|
|
152
|
+
is not reachable at `EMBEDDING_BASE_URL`, the URL points at the wrong API root,
|
|
153
|
+
or the server exposes only one of the supported OpenAI-compatible `/embeddings`
|
|
154
|
+
or TEI `/embed` shapes. Run `xists doctor --check-endpoints --strict` after
|
|
155
|
+
fixing it.
|
|
156
|
+
- `LLM endpoint is not configured`: set `LLM_API_KEY`, `LLM_BASE_URL`, and
|
|
157
|
+
`LLM_MODEL`; this is required for ingest because profiles are LLM-generated.
|
|
158
|
+
- `GitHub token is not configured`: set `GITHUB_TOKEN`/`GITHUB_TOKENS` or pass
|
|
159
|
+
`--token-file` before ingesting. Existing records, indexes, search, and eval do
|
|
160
|
+
not need a GitHub token.
|