Skip to content

Retrieve

The Retrieve node performs the R of RAG: vector similarity search over an embedded string storage, attaching the top matches to the current interaction as a knowledge component.

It does not modify the prompt directly. Rendering is delegated to the downstream Generate node's Mustache template, which decides where and how the attached components appear in the prompt.

NodeType: Retrieve.

Parameters

The Mutable column indicates whether the parameter can be changed at runtime via ChangeParam.

Key Required Default Mutable Description
embedded_string_storage Yes No Name of the embedded string storage to search. Must be created (via CreateEmbeddedStringStorageRequest) before the agent is created.
embedding_model Yes No Catalog name of the embedding model used to embed the query. Must be in models.json with "purpose": "embedding".
top_k No "2" Yes Maximum number of chunks to return. Parsed as int ≥ 1.
threshold No "inf" Yes Maximum cosine distance; results with distance > threshold are dropped. Parsed as float ≥ 0.
source No (node name) No Label attached to the resulting knowledge component; used as the Mustache variable suffix knowledge_<source>. Defaults to the node's name.

Exit routes

Route Fires when
found At least one chunk survived threshold filtering.
not_found No usable human message, or zero chunks after filtering.

Both routes must be wired in the graph — either to different targets or to the same target. A missing wire is a compilation failure (error 3003).

Side effects

  • Embeds the current user message via the configured embedding model.
  • Queries the storage's HNSW index and applies the threshold filter.
  • Attaches a knowledge block (source + surviving chunks) to the current turn. If nothing survives filtering, an empty block is still attached (the Mustache {{#knowledge_<source>}} section simply renders nothing).

The attached knowledge is rendered into the prompt on the next Generate node, via the template and placement params on that node.

Diagnostics

When enable_diagnostics = true, the node contributes these keys to TurnComplete.debug_info:

Key Meaning
source The source label attached to the component.
query The human message text that was embedded.
top_k Number of chunks requested.
threshold Max cosine distance used for filtering (or "inf" when disabled).
raw_result_count Chunks returned by the index before filtering.
filtered_count Chunks removed by the threshold filter.
result_count Chunks actually attached to the component.
result[NNN].id Chunk id (zero-padded, sorted by rank).
result[NNN].distance Cosine distance (lower = more similar).
result[NNN].text Chunk text that will be rendered into the prompt.

Minimum working example

from tryll_client import GraphDescription, NodeType

RAG_TEMPLATE = (
    "{{#knowledge}}"
    "{{name}}:\n{{#chunks}}- {{text}}\n{{/chunks}}\n"
    "{{/knowledge}}"
)

graph = (
    GraphDescription()
    .add_node("knowledge", NodeType.Retrieve, {
        "embedded_string_storage": "aquarium_kb",
        "embedding_model":         "All-MiniLM-L6-v2 (Q4_K_M)",
        "top_k":                   "3",
        "threshold":               "0.6",
    })
    .add_node("answer", NodeType.Generate, {
        "template":  RAG_TEMPLATE,
        "placement": "before_user_as_system",
    })
    .wire("knowledge", "found",     "answer")
    .wire("knowledge", "not_found", "answer")
    .wire("answer",    "default",   "END")
    .set_start_node("knowledge")
    .set_default_model_name("My Local Model")
)

agent = client.create_agent(graph)
namespace TC = Tryll::Client;

TC::GraphDescription graph;
graph.AddNode("knowledge", TC::NodeType::Retrieve, {
        {"embedded_string_storage", "aquarium_kb"},
        {"embedding_model",         "All-MiniLM-L6-v2 (Q4_K_M)"},
        {"top_k",                   "3"},
        {"threshold",               "0.6"},
     })
     .AddNode("answer", TC::NodeType::Generate, {
         {"template",  "{{#knowledge}}{{name}}:\n{{#chunks}}- {{text}}\n{{/chunks}}\n{{/knowledge}}"},
         {"placement", "before_user_as_system"},
     })
     .Wire("knowledge", "found",     "answer")
     .Wire("knowledge", "not_found", "answer")
     .Wire("answer",    "default",   "END")
     .SetStartNode("knowledge")
     .SetDefaultModelName("My Local Model");

auto agent = client.CreateAgent(graph);
FTryllGraphDescription Graph = FTryllGraphBuilder()
    .AddNode(TEXT("knowledge"), ETryllNodeType::Retrieve, {
        {TEXT("embedded_string_storage"), TEXT("aquarium_kb")},
        {TEXT("embedding_model"),         TEXT("All-MiniLM-L6-v2 (Q4_K_M)")},
        {TEXT("top_k"),                   TEXT("3")},
        {TEXT("threshold"),               TEXT("0.6")},
    })
    .AddNode(TEXT("answer"), ETryllNodeType::Generate, {
        {TEXT("template"),  TEXT("{{#knowledge}}{{name}}:\n{{#chunks}}- {{text}}\n{{/chunks}}\n{{/knowledge}}")},
        {TEXT("placement"), TEXT("before_user_as_system")},
    })
    .Wire(TEXT("knowledge"), TEXT("found"),     TEXT("answer"))
    .Wire(TEXT("knowledge"), TEXT("not_found"), TEXT("answer"))
    .Wire(TEXT("answer"),    TEXT("default"),   TEXT("END"))
    .SetStartNode(TEXT("knowledge"))
    .SetDefaultModelName(TEXT("My Local Model"))
    .Build();

See the full walkthrough in How to create a simple RAG assistant.

Client bindings

  • C++: Tryll::Client::GraphDescription::AddNode(name, NodeType::Retrieve, params)GraphDescription.h
  • Python: tryll_client.GraphDescription.add_node(name, NodeType.Retrieve, params)graph.py
  • Unreal: add an FTryllNodeDesc with Type = Retrieve to FTryllGraphDescription.NodesTryllGraphDescription.h