Expand description
Tool and skill retrieval for AI agents — the Rust core of the Ratel context engineering platform.
Agents degrade when every tool definition is stuffed into the context window. This crate keeps the full catalog outside the context and retrieves only the entries relevant to the task at hand: register tools and skills once, then search them per turn. The engine runs in-process; BM25 and local dense retrieval need no server, while dense retrieval may instead use a configured OpenAI-compatible embedding endpoint.
§Mental model
Three registries hold the corpus, one per capability kind:
ToolRegistryindexesTools — callable endpoints ranked by name plus description and JSON schema tokens, or by a searchable-description override that replaces both.SkillRegistryindexesSkills — reusable instruction playbooks whose body is dispatched on demand (a pull).FactRegistryindexesFacts — constant grounding content whose body the higher layers push into the context, always-on or retrieval-gated perPinMode.
All rank a query with one of three engines, selected by SearchMethod:
SearchMethod::Bm25(default) — lexical BM25. Needs no model and never fails;ToolRegistry::searchandSkillRegistry::searchuse it unconditionally.SearchMethod::Semantic— cosine similarity over dense embeddings from a configurable in-process HuggingFace/local model (defaultbge-small-en-v1.5) or OpenAI-compatible endpoint (ADR-0011/ADR-0012).SearchMethod::Hybrid— the BM25 and dense rankings fused with Reciprocal Rank Fusion.
Semantic and hybrid searches rank against an embedding cache built by
ToolRegistry::build_embeddings / SkillRegistry::build_embeddings;
a search itself never embeds the corpus and never downloads the model.
Every register and search also emits a TraceEvent on the registry’s
TraceSink — the local trace stream behind the inspector and usage
reporting (ADR-0007). The default sink is NoopSink (discard);
MemorySink buffers for tests and introspection, JsonlSink appends
to a local file, and FnSink hands each line to a closure for hosts
whose destination this crate cannot own.
§Example: register and search (BM25)
use ratel_ai_core::{Tool, ToolRegistry};
let mut registry = ToolRegistry::new();
registry.register(Tool {
id: "read_file".into(),
name: "read_file".into(),
description: "Read a file from disk".into(),
experimental_searchable_description: None,
input_schema: serde_json::json!({
"properties": {
"path": { "type": "string", "description": "absolute path" }
}
}),
output_schema: serde_json::json!({}),
});
registry.register(Tool {
id: "send_email".into(),
name: "send_email".into(),
description: "Send an email to a recipient".into(),
experimental_searchable_description: None,
input_schema: serde_json::json!({}),
output_schema: serde_json::json!({}),
});
let hits = registry.search("read a file", 5);
assert_eq!(hits[0].tool_id, "read_file");The language SDKs (@ratel-ai/sdk on npm, ratel-ai on PyPI) bundle this
crate and surface the same model; the agent-facing capability tools
(search_capabilities / invoke_tool / get_skill_content) sit on top
of them. Design rationale lives in the repo’s docs/adr/.
Structs§
- Embedding
Spec - Normalized, cross-SDK embedding config as forwarded by the native bindings.
Exactly one primary source must be set: either
spec(the raw string shortcut) or one ofhuggingface/local/ollama/url. The rest are modifiers. - Fact
- A fact registered for grounding — constant, declarative context an agent
needs to have on hand (a barbershop’s address and hours, a brand’s voice).
The push-path analog of a
crate::Skill: where a skill is a playbook the agent pulls and runs on demand, a fact is content the grounding layer pushes into the context so the model is never missing it. - FactHit
- One ranked match from a
FactRegistrysearch, best-first in the returnedVec— the fact-side twin ofcrate::SkillHit. - Fact
HitTrace - One ranked fact hit inside a
TraceEvent::FactSearchevent — the fact-side twin ofSkillHitTrace. - Fact
Registry - Retrieval index over
Facts — the push-path analog ofcrate::SkillRegistry. Same selectable BM25/semantic/hybrid engines; a parallel type keeps the skill path untouched and lets fact telemetry (fact_search/fact_churn/fact_inject) stand on its own. - Fanout
Sink - A sink that wraps each event once, then asynchronously dispatches the same envelope to any number of bounded subscribers.
- Fanout
Subscription - A handle to one
FanoutSinksubscriber. - FnSink
- A sink that hands each enveloped event to a closure, for hosts whose trace destination this crate cannot own — a process-per-request server writing to a database, a language binding forwarding to its runtime, anything distributed enough that a local file is the wrong answer.
- Intent
- One cluster: the queries it covers and the capabilities invoked after them.
- Intent
Graph - The usage-ranking read model — a set of query clusters with capability edges.
- Jsonl
Sink - A sink that appends events to a JSONL file, one
TraceEnvelopeper line — local persistence for the offline inspector and reporting (ADR-0007; the consuming shells bucket files under~/.ratel/telemetry/, but the sink accepts any path). Writes are best-effort: a serialization or I/O failure drops the event rather than disturb the agent loop. - Memory
Sink - A sink that buffers enveloped events in memory, for tests and in-process
introspection: record, then assert on
Self::snapshotorSelf::drain. The buffer is unbounded, so drain it periodically if the producer is long-lived. - Noop
Sink - A sink that discards every event — the default of a registry built with
crate::ToolRegistry::new/crate::SkillRegistry::new, and the right choice when tracing is off. - Observation
Policy - How a
UsageLearnerturns a trace stream into observations. - Parse
OnArtifact Miss Error - Rejected
OnArtifactMissstring from the SDK binding. - Parse
PinMode Error - The identifier did not name a known pin mode.
- Parse
Search Method Error - The identifier did not name a known method.
- Replace
Outcome - What a whole-corpus
SkillRegistry::replace_allactually changed, counted by id.updatedcovers any field edit (including a body-only rewrite);unchangedids are byte-identical and keep their cached embedding. A reload that changed nothing reports zeros acrossadded/removed/updated— the cheap case a periodic source hits most of the time. - Search
Hit - One ranked match from a
ToolRegistrysearch, best-first in the returnedVec. - Search
HitTrace - One ranked tool hit inside a
TraceEvent::Searchevent. - Search
Stage - Timing and top score of one engine stage of a search. BM25 searches emit
one
bm25stage, semantic searches onedensestage; hybrid emitsbm25,dense, andrrf, in that order. Semantic and hybrid searches that short-circuit on an empty corpus ortop_k == 0emit no stages. - Skill
- A skill registered for retrieval — the on-demand analog of a
crate::Tool. - Skill
Hit - One ranked match from a
SkillRegistrysearch, best-first in the returnedVec— the skill-side twin ofcrate::SearchHit. - Skill
HitTrace - One ranked skill hit inside a
TraceEvent::SkillSearchevent — the skill-side twin ofSearchHitTrace. - Skill
Registry - Retrieval index over
Skills — the on-demand analog ofcrate::ToolRegistry. Same selectable BM25/semantic/hybrid engines; a parallel type keeps the tool path untouched and lets skill telemetry stand on its own. - Tool
- A tool registered for retrieval — one entry in a
crate::ToolRegistrycorpus. - Tool
Registry - Retrieval index over
Tools — the registry behind the SDKs’ tool catalogs. - Trace
Envelope - The versioned wrapper a sink writes around each
TraceEvent: schema version, stable identity, timestamp, and correlation fields. On the wire the event is flattened (#[serde(flatten)]), so itstypetag and fields sit besidev/ts/session_idin one JSON object. - Trace
Event Context - Per-event correlation fields supplied by the emitting integration.
- Usage
Learner - A
TraceSinkdecorator that grows anIntentGraphfrom the events passing through it, then forwards them unchanged.
Enums§
- Adaptive
Ranking Status - Whether adaptive usage ranking is currently contributing to a registry’s results — the SDK-facing view of the model-compatibility check (ADR-0014).
- Artifact
Error - Failure building or loading a binary embedding artifact.
- Artifact
Warm Error - Failure of
crate::ToolRegistry::warm_embeddings_from_artifact/crate::SkillRegistry::warm_embeddings_from_artifact. - Catalog
Kind - Catalog entry type carried by
TraceEvent::CatalogDefinition. - Churn
Kind - How a registry corpus changed — carried by
TraceEvent::IndexChurn(tools),TraceEvent::SkillChurn(skills), andTraceEvent::FactChurn(facts). - Embedder
Error - A recoverable embedder failure. Returned instead of panicking so a load or
inference problem surfaces to the SDK as a catchable error (with a
remediation hint in
Display) rather than aborting the host process. - Embedder
Load Status - Outcome of the one-time embedding-model load.
Slowflags a machine that may be underpowered for the model;Faileda load that errored (network, cache, corrupt weights). - Embedding
Model - The embedding model backing a catalog’s semantic/hybrid engines.
- Fact
Inject Reason - Why a fact’s body was (re-)injected into the context, carried by
TraceEvent::FactInject. The grounding layer decides this by scanning the transcript for the fact’s own body text (content presence); it is the observable half of the re-injection freshness gate. - Intent
Graph Error - A graph that could not be adopted.
- OnArtifact
Miss - What to do when some corpus ids are not covered by the artifact.
- Origin
- Where a search came from. Trace consumers separate the paths: rerankers train on agent calls, the inspector shows all of them, and offline graph construction reads only the baseline ones.
- Origin
Filter - Which searches may open an observation window.
- PinMode
- Whether a
Factis always injected or only surfaced when a query retrieves it — the one bit that splits the always-on tier from the retrieval-gated tier. - Pooling
- How a BERT model’s per-token outputs are collapsed into one sentence vector.
A model is trained with one mode — using the other silently degrades ranking
— so it is auto-detected from the repo’s
1_Pooling/config.json, with this as an explicit override. - Provenance
- Whether observations are recorded as seeded evidence.
- Search
Method - Which ranking engine a search uses.
- Trace
Event - Every event produced by any layer of Ratel. New variants are additive; renames or removals are breaking — see ADR-0007.
- Warm
Error - Failure loading or applying an embedding artifact into the dense cache.
Traits§
- Trace
Sink - A best-effort sink for trace events. Implementations must be cheap on the hot path — see ADR-0007 for the query-log reliability profile (lossy on backpressure is fine, blocking the agent loop is not).
Functions§
- merge_
embedding_ artifacts - Merge valid RAT1 parts into one artifact. Empty parts are skipped; nonempty
parts must share format/projection version, fingerprint, and dim. Duplicate
(kind, id)→ArtifactError::IncompatibleMerge.