* Add CLAUDE.md with repo guidance for coding agents Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * CLAUDE.md: match AI disclosure rule to CONTRIBUTING.md Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Revert "CLAUDE.md: match AI disclosure rule to CONTRIBUTING.md" This reverts commit403acce0b. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * CONTRIBUTING.md: only require a human-written PR motivation Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * Add guideline to avoid using matches! macro --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com> (cherry picked from commit0441071b38)
5.3 KiB
Qdrant
Vector search engine written in Rust. Cargo workspace: the server binary is in src/,
the library crates are in lib/*. User docs: https://qdrant.tech/documentation/.
REST API spec: docs/redoc/master/openapi.json. gRPC API: lib/api/src/grpc/proto/.
Code map
A request goes through the layers top to bottom:
src/actix/api/(REST),src/tonic/api/(gRPC): handlers, auth, request conversion.src/settings.rsreads the config (defaults inconfig/config.yaml), andsrc/consensus.rsruns the Raft loop.lib/storage: cluster-wide state.dispatcher.rssends metadata operations through consensus.content_manager/toc/(TableOfContent) owns all collections.content_manager/consensus/is Raft.content_manager/snapshots/handles collection snapshots.rbac/is JWT access control.lib/collection: one collection.operations/has the request and operation types.hash_ring.rsroutes points to shards,shards/shard_holder/holds the shards,shards/replica_set/handles replication, andshards/transfer/pluswal_delta.rshandle shard transfers.update_handler.rsandupdate_workers/run the WAL and optimizers. Built on top of search:grouping/,lookup/,recommendations.rs,discovery.rs.lib/shard: one local shard.segment_holder/holds its segments.optimizers/has merge, indexing, vacuum, and config-mismatch.proxy_segment/takes writes while a segment is being optimized.query/runs universal queries.wal.rsis the shard WAL.lib/segment: one segment, the unit of storage and indexing.types.rshas the core config and filter types.entry/has the segment traits (SegmentEntryand its supertraits).segment_constructor/builds segments, andspaces/has the distance metrics with SIMD. Alsopayload_storage/,json_path/,index/sparse_index/,index/plain_vector_index/, andindex/query_optimization/(filter planning).- Supporting crates:
sparse,bm25,posting_list,wal,gpu(GPU HNSW build),api(REST/gRPC types). lib/edge(Qdrant Edge): an embeddable single shard built onlib/shardandlib/segment, with no server or consensus. The public API is whateverlib.rsre-exports; everything else is internal.config/hasEdgeConfig. Shard variants for serverless setups are behind theserverlessfeature. The published crateqdrant-edgeis assembled from these sources bypublish/amalgamate.py.
Build, lint, test
- Format:
cargo +nightly fmt --all(needs nightly). - Lint:
cargo clippy --workspace --all-targets -- -D warnings. When editing code behind#[cfg(feature = ...)], add that feature, e.g.--features staging. Avoid--all-featureslocally: it builds the GPU backend, which is slow to compile. - Avoid
--releaselocally: fat LTO makes it very slow to build. For benchmarks and profiling use--profile perf, which is release without LTO. - CI also enforces ast-grep rules:
sg scan --config tools/ast-grep/sgconfig.yml. - Rust tests:
cargo test -p <crate>is much faster than--workspace. - Python tests need
uv, and most need a running server:uv --project tests run pytest tests/openapi,tests/consensus_tests(spawns its own cluster). - More detail (Docker, profiling, benchmarks):
docs/DEVELOPMENT.md.
API changes
REST needs all four steps, and CI checks that they agree:
- Endpoints and models in Rust.
- Specs in
openapi/*ytt.yaml. - Schema definitions in
src/schema_generator.rs. - Run
./tools/generate_openapi_models.sh. Never editopenapi.jsonby hand.
gRPC: edit lib/api/src/grpc/proto/*.proto, then cargo build -p api regenerates the code.
Qdrant Edge has its own API. If it exposes the feature you're changing, update all three
interfaces: Rust (lib/edge/src), Python (lib/edge/python), and FFI (lib/edge/ffi).
Update the examples too: lib/edge/publish/examples (Rust) and lib/edge/python/examples.
lib/edge/publish/qdrant-edge is generated; don't edit it.
A new endpoint must also be added in the same PR to: EXPECTED_NUMBER_OF_APIS in
tests/openapi_consistency_check.sh, the ACTION_ACCESS table in
tests/consensus_tests/auth_tests/test_jwt_access.py, and REST_ENDPOINT_WHITELIST /
GRPC_ENDPOINT_WHITELIST in src/common/metrics/requests.rs.
Contributing
- PRs target
dev.masteris release-only. - AI-assisted PRs follow
docs/CONTRIBUTING.md#contributing-with-ai. Mark each commit[AI]or[manual]in the PR description, and include the original prompt. External contributors must write the motivation for the PR themselves. The rest of the description can be AI-generated.
Code conventions
Full rules with examples: .github/review-rules.md. Tests and benchmarks are exempt.
- Program defensively, so the compiler catches broken assumptions:
- Don't fill structs with
..Default::default(). Set every field so new fields don't get defaults silently. - If a conversion can fail, implement
TryFrom, not aFromthat falls back to a default. - Use enums instead of
boolparameters. - Mark results that must not be ignored with
#[must_use]. - Prefer
SomeType::from(x)overx.into(). - Match enums exhaustively instead of using a
_arm. - Ignore struct fields explicitly (
field: _) instead of using... - Avoid
matches!for the same reason.
- Don't fill structs with
- Don't use the
transmute_*helpers in new code; usebytemuckorzerocopy.