Annotation Interface Knowledge
Knowledge is declared in one place — the knowledge member of
AgentSpec or RoleSpec — and used by name:
@RoleSpec(knowledge = {
@Knowledge(name = "product-docs", path = "knowledge/products"),
@Knowledge(name = "handbook", path = "knowledge/handbook.md",
use = Knowledge.Use.DIRECT),
@Knowledge(name = "questions", path = "knowledge/questions.md",
unit = KnowledgeUnit.HEADING, use = Knowledge.Use.SEQUENTIAL)
})
public class SupportRole extends Role {
@ActionSpec(type = ActionType.LLM, description = "Answer a question",
knowledge = {@Knowledge(name = "product-docs"), @Knowledge(name = "handbook")})
public String answer(String question) { ... }
}
Who sees what
- An action sees only the knowledge its
ActionSpec.knowledge()names. Knowledge on an action is valid forActionType.LLM(spliced into the prompt) andActionType.LOCAL(pulled before the body runs); other action types fail at startup. - A chat turn sees the enabled
AgentSpecknowledge whoseuse()isSEARCHorDIRECT; SEQUENTIAL andGRAPHknowledge stay out of it, and only actions that name them see them.
An action's entry names a declared source and may set only
use(), maxTokens() and search(), each replacing
the declared value as a whole, so a search set there drops every
member of the declared Search; setting a source member such as
path() there fails at startup. In one scope every source behaves
by its own use: DIRECT sources enter whole, SEARCH sources run
through one engine, a SEQUENTIAL source contributes its next unit, and the
blocks join in declaration order.
Unset members
use(), maxTokens() and search() are arrays
whose empty default means "not given"; write one value as usual
(use = Knowledge.Use.DIRECT). More than one value fails at startup.
Which types are served
TnsAI bundles loaders for Knowledge.Type.FILE and HTTP/HTTPS
Knowledge.Type.URL. DATABASE is an extension point: the framework
resolves it through the SourceLoader SPI, and an application
supplies the loader as an optional module. Knowledge.Type.MEMORY and
Knowledge.Type.GRAPH load nothing, so no loader serves them.
What a missing loader costs depends on what searches the source. A
Role's action knowledge skips a source whose type has no installed loader
with a warning and binds from whichever sources did load; that binding fails
only when every enabled source is unloadable, so there a missing
loader costs part of the corpus and the warning is the only signal. An
engine a com.tnsai.rag.RetrievalEngineProvider creates fails at
creation on any enabled source whose type has no installed loader, MEMORY
and GRAPH apart since no loader serves them; an agent's chat knowledge
creates its engine at startup, so it fails there.
Retrieval against a remote index — a vector database, a search
API — is deliberately not a knowledge source. Those are queried per request,
whereas a loader runs once and materialises documents, so they cannot be
expressed against this seam at all. They are served by
com.tnsai.rag.RetrievalEngineProvider instead.
- Since:
- 0.18.0
- Author:
- TnsAI Team
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumKinds of corpus a loader can ingest.static enumHow a source's content reaches the model. -
Required Element Summary
Required Elements -
Optional Element Summary
Optional ElementsModifier and TypeOptional ElementDescriptionIngest-time chunk context prepended before embedding and BM25.Model identifier forChunkContext.LLM.Database connection string or reference.booleanWhether this source is ingested at all.String[]Exclude globs for aKnowledge.Type.FILEsource.Content format for a FILE or HTTP/HTTPS URL source.String[]Include globs for aKnowledge.Type.FILEsource.int[]Token budget for aKnowledge.Use.DIRECTsource.Directory or file the corpus is read from.Query template a database source ingests with.Search[]Ranking settings for aKnowledge.Use.SEARCHsource.Part of the source atpath()to read, as astructural pathprefix.Knowledge source type, which selects the loader.How each admitted FILE or HTTP/HTTPS URL source becomes retrieval documents.How this source reaches the model.
-
Element Details
-
name
String nameKnowledge name, unique within the declaring Agent or Role.An action names the knowledge it sees by this name, and the class config file and run-level overrides address the source by it.
- Returns:
- source name
-
type
Knowledge.Type typeKnowledge source type, which selects the loader.Defaults to
Knowledge.Type.FILE, the type TnsAI bundles a loader for. The default is deliberately a type that works: an unserviceable default fails every declaration that omits this element.- Returns:
- source type
- Default:
FILE
-
format
DocumentFormat formatContent format for a FILE or HTTP/HTTPS URL source.DocumentFormat.AUTOis resolved independently for every file in a directory. An explicit format is strict: every regular, non-symbolic-link candidate must use one of that format's registered extensions before ingestion starts.DocumentFormat.TEXTintentionally accepts any file name and performs raw UTF-8 decoding.include()andexclude()narrow candidates before this format check. An excluded file is not an AUTO candidate and cannot trigger an explicit-format mismatch. Unsupported AUTO candidates that survive the selectors are skipped; a directory that contains files but no usable candidate is a configuration error.- Returns:
- declared document format
- Default:
AUTO
-
path
String pathDirectory or file the corpus is read from.Used by
Knowledge.Type.FILEandKnowledge.Type.URL. A relative FILE path resolves against the working directory; one aConfigfile gives resolves against the base directoryClassConfig.useBaseDirectory(java.nio.file.Path)set, when one is set.- Returns:
- path or URL
- Default:
""
-
connection
String connectionDatabase connection string or reference.Used by
Knowledge.Type.DATABASE, whose loader is supplied by an application module.- Returns:
- connection string
- Default:
""
-
query
String queryQuery template a database source ingests with.Used by
Knowledge.Type.DATABASE. Use the${query}placeholder for the search term.- Returns:
- query template
- Default:
""
-
enabled
boolean enabledWhether this source is ingested at all.A disabled source is skipped at binding time, so it contributes no documents and an action cannot name it.
- Returns:
- true if enabled
- Default:
true
-
select
String selectPart of the source atpath()to read, as astructural pathprefix.Each loaded document keeps only the blocks at and below the selector, as in
$.productsfor JSON or/catalog[1]/book[2]for XML; theStructuralPathclass lists the root of every built-in format. Applies toKnowledge.Type.FILEandKnowledge.Type.URLsources.The selector is strict per document: every document of the source must hold the selected part. A document the selector selects nothing from, an empty one included, or a selector that does not start at its format's root, fails when it is loaded. For a directory whose files do not all hold the part, narrow the files with
include()andexclude(). ASourceLoaderthat does not keep structural paths, as a third-party loader may not, refuses a source that sets a selector. Changing the selector re-ingests the source.- Returns:
- selector, empty for the whole source
- See Also:
- Default:
""
-
include
String[] includeInclude globs for aKnowledge.Type.FILEsource.Empty — the default — admits every regular, non-symbolic-link file beneath the configured root. Each pattern matches the entire root-relative path with
/separators.*and?do not cross directories;**matches zero or more path segments. Include is evaluated beforeexclude().- Returns:
- include selectors
- Default:
{}
-
exclude
String[] excludeExclude globs for aKnowledge.Type.FILEsource.Empty — the default — excludes nothing. A path that matches any exclude pattern is dropped even if it also matched
include(). Invalid syntax fails binding, naming this source and the selector.- Returns:
- exclude selectors
- Default:
{}
-
unit
KnowledgeUnit unitHow each admitted FILE or HTTP/HTTPS URL source becomes retrieval documents.This is an ingest-time decision applied once when the source is loaded. It does not change per query, and it does not affect how
search()ranks the resulting documents.KnowledgeUnit.AUTO— the default — is the existing hybrid: a file that fits one chunk stays one document, a larger file is split by the shared chunker. The other values are explicit opt-ins.RECORDis not a value: JSONL and CSV already yield one document per row under their extractors. Non-AUTOunits are therefore rejected for CSV, TSV, and JSONL;LINEadditionally requires a textual format, andHEADINGrequires Markdown.- Returns:
- slicing unit
- Default:
AUTO
-
chunkContext
ChunkContext chunkContextIngest-time chunk context prepended before embedding and BM25.ChunkContext.NONE— the default — omits the extra fingerprint fields.STRUCTURALis free.LLMrequires an installedChunkContextGeneratorandchunkContextModel(). FILE sources only.KnowledgeUnit.LINErejects any non-NONEvalue.- Returns:
- chunk-context mode
- Default:
NONE
-
chunkContextModel
String chunkContextModel- Returns:
- generating model
- Default:
""
-
use
Knowledge.Use[] useHow this source reaches the model.Empty — the default — means
Knowledge.Use.SEARCH. More than one value fails at startup.- Returns:
- one usage mode, or empty for
Knowledge.Use.SEARCH
- Default:
{}
-
maxTokens
int[] maxTokensToken budget for aKnowledge.Use.DIRECTsource.The DIRECT sources of one scope share a budget: the sum of their estimated sizes must fit the budget given here, or a quarter of the model's input window when no source in the scope gives one. An unknown input window with no budget given fails. Only valid with
use = DIRECT; a non-positive value fails at startup.- Returns:
- one positive budget, or empty for the derived budget
- Default:
{}
-
search
Search[] searchRanking settings for aKnowledge.Use.SEARCHsource.Only valid with
use = SEARCH(or unset). SeeSearchfor how several SEARCH sources in one scope merge.- Returns:
- one
Search, or empty for the defaults
- Default:
{}
-