RAG diagnostics
com.tnsai.intelligence.rag.binding.RagDiagnostics is @since 0.15.0 (TnsAI@32e17445, PR #199 / TAN-5888). It ships in 0.15.0 and later — see Installation for the coordinates.
R5's four code items are one sentence: a RAG downgrade is visible.
RagDiagnostics is the pull half of that sentence — you can ask what a
Role's declarations actually resolved to before a bad answer costs a
debugging session.
What it does
The snapshot answers the questions the binding already computed and used to hide:
- which
EmbeddingFunctionis in use, and whether it is the bundled hash fallback - whether a reranker, query expander, or graph-store provider is installed — absence is a reported fact, not an exception
- per source: name, type, detected format, document count, chunk count, and ingest fingerprint
- the effective
@Retrievalconfiguration after resolution
It does not change retrieval behaviour. It is not an annotation, not a log line, and not telemetry. You ask; the framework answers.
How to ask
RagDiagnostics.of(roleType) never ingests. It snapshots a binding
that already exists for that Role class. If nothing has been built yet,
use the explicit flag: RagDiagnostics.of(roleType, true) constructs
the binding (and therefore runs ingest).
report() returns unstable human-readable text. Paste it into an
issue; do not parse it. Typed accessors on the snapshot are the
supported surface for tests and health checks.
package com.example.tnsai.docs;
import com.tnsai.annotations.ActionSpec;
import com.tnsai.annotations.KnowledgeSource;
import com.tnsai.annotations.Retrieval;
import com.tnsai.enums.ActionType;
import com.tnsai.intelligence.rag.binding.RagDiagnostics;
import com.tnsai.models.role.RoleIdentity;
import com.tnsai.roles.Role;
public final class RagDiagnosticsExample {
private RagDiagnosticsExample() {}
@KnowledgeSource(
name = "product-docs",
type = KnowledgeSource.KnowledgeType.FILE,
path = "knowledge/products")
@Retrieval(
strategy = Retrieval.Strategy.SEMANTIC,
sources = "product-docs",
queryParam = "question",
topK = 5)
public static final class FaqRole extends Role {
@Override
public RoleIdentity getIdentity() {
return new RoleIdentity("faq", "FAQ answers", "support");
}
@ActionSpec(
type = ActionType.LLM,
description = "Answer from product documentation")
public String answer(String question) {
return question;
}
}
public static String inspectExistingBinding() {
return RagDiagnostics.of(FaqRole.class).report();
}
public static String inspectByBuilding() {
return RagDiagnostics.of(FaqRole.class, true).report();
}
}inspectExistingBinding() is the cheap question: what did this Role
already become? inspectByBuilding() is the explicit "build it so I
can see it" path. Do not call the two-argument form from a health
endpoint unless you intend to pay ingest.
Four silent downgrades, now visible
These four used to fail as plausible but worse answers. They now surface as a warning, a named exception, a startup configuration error, or a diagnostic you can ask.
Hash embedding fallback
No installed EmbeddingFunction plus a vector-backed @Retrieval
strategy used to rank by token overlap with no log line. Framework
main (TnsAI@89d41d1b,
PR #195 /
TAN-5885)
emits one process-lifetime WARN per Role class when SEMANTIC,
HYBRID, HIERARCHICAL, or TEMPORAL resolve to the bundled hash
embedding. KEYWORD, GRAPH, REASONING, and MULTI_QUERY stay
silent on this path. The fallback still runs — the defect was the
silence.
What you see, what it means, and what to do: Embeddings — hash-embedding fallback.
RagDiagnostics distinguishes the fallback case from an installed
provider without throwing.
Absent expander and reranker messages
TnsAI ships no bundled Reranker and no bundled QueryExpander.
RerankerRegistry already named the cause, the registered providers,
and two remedies. QueryExpanderRegistry used to throw only
"No QueryExpander provider supports mode … and model '…'".
TnsAI 0.15.0 (TnsAI PR #197 /
TAN-5886)
brings the expander message to the same skeleton: registered
providers, that TnsAI ships no built-in expander, and a remedy that
matches the (strategy, queryExpansion) pair — not a copy-pasted
queryExpansion = NONE on every shape.
RagDiagnostics reports installed or absent status for both seams
without throwing. Use that when you want the fact before the first
query; use the exception message when a query already failed.
Eager reranker and expander validation
On Maven Central 0.14.1, a typo in rerankerModel or
queryExpansionModel compiles, starts, and throws on the first query
— inside the span @Retrieval.onFailure guards. CONTINUE can then
emit an ungrounded answer. GRAPH already refused that shape: which
provider can serve the annotation is fixed by the classpath, never by
request data.
TnsAI 0.15.0 (TnsAI@cb14410d,
PR #198 /
TAN-5887)
resolves those two model names when Role.create establishes the
retrieval configuration. An unservable name is a wiring-time
configuration error, above onFailure. Failures a provider raises
while ranking or expanding still follow onFailure.
Roles with no effective @Retrieval, and declarations that do not
ask for rerank or expansion, do not load those provider graphs.
See Annotation runtime status.
Inspectability
The three fixes above announce a problem. RagDiagnostics is the
positive case: everything resolved, here is what you got — including
corpus counts and the ingest fingerprint — plus the fallback bit you
can assert in a test.
Not this page
- A new annotation or automatic dump at startup
- A metrics or time-series surface for ingest
- Maven Central
0.14.1behaviour — this type does not exist there - How to install an
EmbeddingFunctionprovider — see Strategies
Related
- Embeddings — hash-fallback warning and Matryoshka prefixes
- Strategies — declarative embedding provider SPI
- Declarative RAG —
@KnowledgeSource/@Retrievalfields - Annotation runtime status — wiring vs dispatch
Agent-level action RAG
@AgentSpec.knowledge() and @AgentSpec.retrieval() are the annotation counterparts of AgentBuilder.addKnowledgeSource and AgentBuilder.retrieval. Both members are @since 0.14.0 in TnsAI 0.14.0 (TnsAI@c2bb5306). They ship in Maven Central 0.14.1.
Embedding prefixes
EmbeddingFunctions.matryoshka derives a shorter, L2-normalized prefix from any EmbeddingFunction. The helper and EmbeddingDimensionMismatchException are @since 0.14.0 in TnsAI 0.14.0 (TnsAI@c2bb5306). They ship in Maven Central 0.14.1.