> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cognee.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Recall

> Query Cognee memory with auto-routing and session-aware retrieval.

## What is the recall operation

The `.recall` operation is the main retrieval entry point in Cognee v1.0. It searches memory using the best available source for the request.

* **Auto-routing by default**: when you do not specify a search type, `recall()` classifies the query and picks the best retrieval strategy automatically.
* **Session-aware**: with `session_id`, it can search session cache entries first and fall through to the permanent graph if needed.
* **Graph-backed by default**: for permanent memory, `recall()` runs graph retrieval — not plain embedding similarity. `GRAPH_COMPLETION` is the fallback when auto-routing does not choose a more specific strategy.
* **Source tagging**: each recall result includes a `source` field (`"graph"`, `"session"`, `"trace"`, `"session_context"`, ...) so you can tell where it came from — see the [full source table](/python-api/recall#return-value).

## Where recall fits

* Use `recall()` as the default way to ask questions over memory in v1.0.
* Use it after [Remember](/core-concepts/main-operations/remember) has created either permanent or session memory.
* Use explicit `query_type` only when you want to force a specific retrieval mode.
* Use datasets to scope results to a specific knowledge base.

## What happens under the hood

1. **Check session scope**
   * If you pass `session_id` without `datasets` and without `query_type`, Cognee first searches the session cache directly.
   * Session search is keyword-based over stored question, context, and answer fields.

2. **Choose the retrieval strategy**
   * If `query_type` is provided, Cognee uses it directly.
   * Otherwise, if `auto_route=True`, a rule-based router picks the best strategy based on your query. See [Auto-routing behavior](#auto-routing-behavior) below for the kinds of patterns it recognizes.
   * If `auto_route=False`, Cognee falls back to `GRAPH_COMPLETION`.

3. **Run graph retrieval when needed**
   * If session search finds nothing, or if graph retrieval is requested, `recall()` queries the permanent knowledge graph.
   * The retrieval strategy selected in step 2 determines how that graph query is executed.

## After recall finishes

* **Session-only recall**: you get matching session entries when cache hits exist, each tagged with `source="session"`.
* **Graph-backed recall**: you get normalized graph result objects tagged with `source="graph"`.
* **Hybrid behavior**: with `session_id` plus graph-scoping inputs like `datasets` or `query_type`, recall uses the permanent graph path rather than session-only lookup.

## Examples and details

<Accordion title="Prerequisites before calling recall">
  `recall()` only reads from memory — it never initializes anything itself. Populate memory first with [`remember()`](/core-concepts/main-operations/remember) (or the legacy [`add()`](/core-concepts/main-operations/legacy-operations/add) + [`cognify()`](/core-concepts/main-operations/legacy-operations/cognify) sequence). The first ingestion run creates the relational, vector, and graph databases and the default user.

  ```python theme={null}
  import cognee

  await cognee.remember("Einstein was born in Ulm.")  # creates databases + ingests
  results = await cognee.recall("Where was Einstein born?")
  ```

  If you call `recall()` before any data exists, it raises `RecallPreconditionError` (HTTP 422), triggered by the underlying `DatabaseNotCreatedError` (*"The database has not been created yet. Please call `await setup()` first."*) or `UserNotFoundError`. The fix is to run `remember()` (or `add()` + `cognify()`) first.

  `recall()` can also fail when the configured LLM provider (or LiteLLM proxy) reports that its token budget is exhausted. In that case it raises `LLMPaymentRequiredError`, which the API surfaces as **HTTP 402 (Payment Required)** with body `{"detail": "LLM provider requires payment or token budget is exhausted. [LLMPaymentRequiredError]"}`. This error is **terminal** — Cognee does not retry budget-exhaustion failures — so treat a `402` as final for the request and prompt the user to top up their token budget rather than reissuing the call.

  `recall()` also accepts only its documented parameters — there is no catch-all `**kwargs`. Passing an unsupported keyword such as `node_type` raises a `TypeError`. Use `node_name` to scope retrieval to specific nodes or node sets; `node_type` belongs to the legacy [`search()`](/core-concepts/main-operations/legacy-operations/search) API. See the [`recall()` API reference](/python-api/recall) for the full parameter list.
</Accordion>

<Accordion title="Recall while indexing is still running">
  `recall()` can run while another dataset is still being ingested or indexed in the background.

  * There is no global lock that blocks retrieval while `remember()` is processing.
  * `recall()` only sees data that has already made it through indexing.
  * If a dataset is mid-run, results may be incomplete until that run reaches completion.

  If you need to confirm a dataset is fully ready before querying it, check its status with [`cognee.datasets.get_status()`](/python-api/datasets#datasetsget_status) or the indexing-status guidance on [Remember](/core-concepts/main-operations/remember#checking-indexing-status).
</Accordion>

<Accordion title="Auto-routing behavior">
  Auto-routing is on by default, and it is **rule-based, not LLM-based**. `recall()` decides the search type in one of these ways:

  | How you call it                                  | What decides the search type                                                                         | LLM call to decide |
  | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------- | ------------------ |
  | `recall(q)` — default, `auto_route=True`         | Rule-based query router: regex cues with weighted scores                                             | No                 |
  | `recall(q, auto_route=False)`                    | Always `GRAPH_COMPLETION`                                                                            | No                 |
  | `recall(q, query_type=...)`                      | Your value — it always wins                                                                          | No                 |
  | `recall(q, query_type=SearchType.FEELING_LUCKY)` | Separate LLM-based selector (falls back to `RAG_COMPLETION` if the model returns an unusable answer) | Yes                |

  **What the router recognizes**

  | Cue in the query                                                                                                                                                              | Routed search type                   | What you get back                         |
  | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | ----------------------------------------- |
  | `summarize`, `summary`, `overview`, `outline`, `tl;dr`, `gist`, `main points`, `key takeaways`, `high-level`                                                                  | `GRAPH_SUMMARY_COMPLETION`           | Generated answer                          |
  | `why`, `explain`, `reasoning`, `step by step`, `chain of thought` (weaker: `because`, `therefore`, `consequently`)                                                            | `GRAPH_COMPLETION_COT`               | Generated answer                          |
  | `how is/are X related/connected/linked`, `what connects/links/ties`, `path between`, `degree of separation` (weaker: `connection`, `relationship`, `related to`, `linked to`) | `GRAPH_COMPLETION_CONTEXT_EXTENSION` | Generated answer                          |
  | `when`, `before`, `after`, `during`, `since`, `until`, `timeline`, `chronolog…`, `era`, `decade`, `century`, a 4-digit year, `between 1990 and 2000`                          | `TEMPORAL`                           | Generated answer                          |
  | The whole query is one quoted phrase (`"exact wording"`), or it contains `exact`, `verbatim`, `literal`, `word for word`                                                      | `CHUNKS_LEXICAL`                     | Raw chunk payloads — no generated answer  |
  | `coding rules`, `code review`, `best practice`, `lint`/`linting`/`linter`, `refactor`/`refactoring`                                                                           | `CODING_RULES`                       | Structured payloads — no generated answer |
  | Query starts with `MATCH `, `RETURN `, `CREATE `, or `MERGE ` (uppercase), or contains `--(` / `)--`                                                                          | `CYPHER`                             | Raw graph rows — no generated answer      |
  | **No cue matched**                                                                                                                                                            | `GRAPH_COMPLETION`                   | Generated answer                          |

  The router **never** selects `SUMMARIES`, `CHUNKS`, `RAG_COMPLETION`, `HYBRID_COMPLETION`, `TRIPLET_COMPLETION`, `GRAPH_COMPLETION_DECOMPOSITION`, `NATURAL_LANGUAGE`, or `AGENTIC_COMPLETION`. Only `FEELING_LUCKY`'s LLM selector can land on retrieval-only types such as `SUMMARIES` or `CHUNKS`, which return payloads instead of an answer — if you want an answer every time, do not use `FEELING_LUCKY`. For the full answer-vs-payload breakdown per type, see [SearchType](/python-api/search-type#values) and [What recall returns](#what-recall-returns).

  Cues are weighted and accumulate; the highest total wins, and anything unmatched falls back to `GRAPH_COMPLETION`. A cue is ignored when a negation (`not`, `n't`, `no`, `never`, `without`, `lack`) appears within 20 characters before it, so "topics **not related to** billing" does not route to context extension.

  Incidental code tokens — a stray `def `, `return `, `async `, `await `, `import `, `class X(`, `.py`, or `function x(` inside an otherwise natural-language question — are a deliberately weak signal. On their own they are not enough to select coding-rules retrieval, so a query like "Where is `def recover()` mentioned in the incident notes?" falls back to `GRAPH_COMPLETION` rather than routing to coding rules. They are also outranked whenever the same query carries a stronger cue, such as a summary, relationship, year-range, or fully quoted phrase. Explicit coding vocabulary still routes to coding-rules retrieval even when it appears alongside a code token, as in "What coding rules apply to `gate.py`?".

  **Confirming what the router chose**

  The router logs its decision at `INFO` level under the `query_router` logger (see [Logging](/setup-configuration/logging)):

  ```text theme={null}
  query_router: routed=TEMPORAL score=3.0 query='What happened before the outage?' scores={'TEMPORAL': 3.0}
  query_router: no patterns matched, default=GRAPH_COMPLETION query='Who won Nobel Prizes?'
  ```

  `query_router: no patterns matched` is **not** an error — it is the normal line for a plain factual question, and it means recall ran `GRAPH_COMPLETION`. You can also read the type that actually ran off each result's `search_type` field.

  If you pass `query_type` while `auto_route` is still `True`, the router still runs and logs its own decision, and when that decision differs from your choice it also logs `Router override recorded: routed=…, user_chose=…`. It costs no LLM call and your explicit `query_type` is what executes.

  **When to override `query_type`**

  * You want raw payloads rather than a generated answer — pass `CHUNKS` or `SUMMARIES`.
  * A cue word routes somewhere you did not intend: "Why did the migration fail?" routes to the slower `GRAPH_COMPLETION_COT`, and "What changed in 2024?" routes to `TEMPORAL`. Pass `query_type=SearchType.GRAPH_COMPLETION` to keep the fast default.
  * Your query needs a mode it carries no cue for — a time-scoped question phrased without a time word, or a multi-part question that suits `GRAPH_COMPLETION_DECOMPOSITION`.
  * You need a type outside the router's set (`RAG_COMPLETION`, `HYBRID_COMPLETION`, `TRIPLET_COMPLETION`, `NATURAL_LANGUAGE`, `AGENTIC_COMPLETION`, …).
  * You want predictable latency and cost across calls — pinning `query_type` makes every call use the same retriever. `auto_route=False` pins it to `GRAPH_COMPLETION`.

  <Warning>
    A query that begins with `MATCH `, `RETURN `, `CREATE `, or `MERGE ` routes to `CYPHER`. If `ALLOW_CYPHER_QUERY=false`, that raises `UnsupportedSearchTypeError` ("Cypher query search types are disabled."). Rephrase the query or pass an explicit `query_type`.
  </Warning>
</Accordion>

<Accordion title="How recall relates to retrievers">
  Most users should think in terms of **asking memory a question**, not selecting a retriever manually.

  Under the hood, retrieval strategies — graph completion, summary, temporal, lexical, coding-rules — do the actual work. `recall()` is intentionally one layer above them:

  * you call `recall()`
  * Cognee chooses or accepts a `query_type`
  * the matching retriever runs underneath
  * the result comes back through the recall API

  If you want to understand or control the lower-level retrieval behavior directly, see the [lower-level search reference](/core-concepts/main-operations/legacy-operations/search).
</Accordion>

<Accordion title="What recall returns">
  * Session-only recall returns matching session cache entries.
  * Graph-backed recall returns the output of the underlying retrieval mode selected by the router or `query_type`.
  * Depending on the retrieval path, each graph result object's `text` can contain a plain answer, retrieved context, chunk text, or rendered structured output.
  * Each recall result is tagged with `source` so callers can distinguish session, graph, trace, and graph-context results.
  * `only_context=True` skips the final LLM answer-generation step and returns retrieved context instead.
  * `verbose=True` exposes extra retrieval details from the lower-level graph search path.

  <Tabs>
    <Tab title="Session Results">
      When `recall()` returns session cache hits, the result is a list of `ResponseQAEntry` objects tagged with `source="session"`.

      These entries follow the session QA shape documented in [Sessions and Caching](/core-concepts/sessions-and-caching#session-data-structure), with fields such as:

      * `time`
      * `qa_id`
      * `question`
      * `context`
      * `answer`
      * `feedback_text`
      * `feedback_score`
      * `source`
    </Tab>

    <Tab title="Graph Results">
      When `recall()` falls through to graph retrieval, it returns normalized `ResponseGraphEntry` objects tagged with `source="graph"`. Each entry includes `text`, `kind`, `search_type`, optional `dataset_id` and `dataset_name`, `metadata`, `raw`, and `structured`.

      * `kind` is the normalized result shape and can be more precise than `search_type`. Graph-completion variants — including `AGENTIC_COMPLETION` — collapse to `kind="graph_completion"`, while retrieval-only types map to structural kinds (`chunk`, `summary`, `cypher`, `temporal`, `coding_rule`, `natural_language`). `RAG_COMPLETION` and `TRIPLET_COMPLETION` keep their own `rag_completion`/`triplet_completion` kinds.
      * `structured` is populated only when you pass a Pydantic model — either through the first-class [`response_model`](/python-api/recall#structured-output-with-response_model) parameter or the equivalent `retriever_specific_config={"response_model": ...}` dict key — and parsing succeeds; it holds the parsed model as a dict (mirrored in `raw`), and `kind` is set to `structured`. For plain-text answers it is `null`, so text-only renderers can keep reading `text` unchanged. Over HTTP (and from the SDK in remote mode) the model travels as a JSON Schema, which reconstructs structure but not custom validators or value constraints — re-validate with `MyModel.model_validate(result.structured)` when you need those to run.
      * With `FEELING_LUCKY`, the router resolves an effective search type before retrieval runs, so `kind` and `search_type` reflect the retriever that actually ran (for example `CHUNKS` → `kind="chunk"`), not the `FEELING_LUCKY` placeholder.

      For chunk and summary results (`CHUNKS`, `CHUNKS_LEXICAL`, `SUMMARIES`), `metadata` carries stable source identifiers — `data_id` (the ingested `Data` item's id), `chunk_id` (the chunk's own node id), `chunk_index`, and `document_name` — so you can map a result back to what you ingested and inspect the exact cited chunk. Only keys present in the underlying payload are included; completion-style results carry an empty `metadata` dict. For `GRAPH_COMPLETION` (and other completion) answers, the same `data_id`/`chunk_id` are instead surfaced inline in the `Evidence:` bullets (`- chunk N of document NAME (data_id: …, chunk_id: …): "snippet"`) when `include_references=True`. This is additive — no DB migration is required.

      The `text` field is derived from the underlying retrieval mode selected by the router or `query_type`:

      | Search type(s)                                                                                                                                                                                              | What `text` represents                | Notes                                                                                                                                                 |
      | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
      | `GRAPH_COMPLETION`, `RAG_COMPLETION`, `HYBRID_COMPLETION`, `TRIPLET_COMPLETION`, `GRAPH_COMPLETION_DECOMPOSITION`, `GRAPH_SUMMARY_COMPLETION`, `GRAPH_COMPLETION_COT`, `GRAPH_COMPLETION_CONTEXT_EXTENSION` | Natural-language answer               | With `only_context=True`, `text` contains the formatted context string instead.                                                                       |
      | `TEMPORAL`                                                                                                                                                                                                  | Time-aware answer text                | `only_context=True` returns retrieved temporal context instead of an answer.                                                                          |
      | `AGENTIC_COMPLETION`                                                                                                                                                                                        | Agentic answer text                   | Normalized to `kind="graph_completion"`. Requires the resolved graph scope to contain exactly one dataset.                                            |
      | `CHUNKS`                                                                                                                                                                                                    | Chunk text                            | `raw` preserves the normalized chunk payload.                                                                                                         |
      | `CHUNKS_LEXICAL`                                                                                                                                                                                            | Ranked chunk text                     | `raw` may include scores and chunk metadata.                                                                                                          |
      | `SUMMARIES`                                                                                                                                                                                                 | Summary text                          | `raw` preserves the normalized summary payload.                                                                                                       |
      | `CYPHER`, `NATURAL_LANGUAGE`, `CODING_RULES`                                                                                                                                                                | Rendered structured row/object output | `raw` preserves the normalized structured payload. `CYPHER` and `NATURAL_LANGUAGE` are disabled when `ALLOW_CYPHER_QUERY=false`.                      |
      | `FEELING_LUCKY`                                                                                                                                                                                             | Varies                                | The router resolves an effective search type before retrieval, so `kind` and `search_type` report the resolved retriever rather than `FEELING_LUCKY`. |

      <Note>
        Read recall results with attribute access (`result.text`, `result.raw`, `result.source`), not `result.get(...)`. The `text_result`, `context_result`, and `objects_result` keys belong to the legacy [`search(verbose=True)`](/python-api/search) API, which returns plain dicts. See [recall() — Return value](/python-api/recall#return-value) for the full per-`source` field list.
      </Note>
    </Tab>
  </Tabs>
</Accordion>

<Accordion title="Using only_context">
  Set `only_context=True` when you want the retrieved context without asking Cognee to produce a final answer.

  When `only_context=True`, Cognee stops after retrieval formatting:

  * the LLM answer is **not** generated
  * the final completion step is skipped
  * the returned value is the retrieved context rather than a synthesized answer

  ```python theme={null}
  results = await cognee.recall(
      query_text="Tell me about NLP",
      only_context=True,
  )
  ```

  This is useful when you want to:

  * inspect what was retrieved before answer generation
  * feed the retrieved context into your own prompt or downstream logic
  * debug retrieval quality separately from answer quality

  In other words, `only_context=True` keeps recall focused on **retrieval output** instead of answer generation.
</Accordion>

<Accordion title="Session cache reads and writes during recall">
  `session_id` makes recall session-aware, but the exact behavior depends on the recall mode.

  **Session reads:**

  * With `session_id` and no explicit `query_type`, `recall()` searches session-cache QA entries by keyword and returns matches tagged with `source="session"`.
  * If `session_id` is used with `datasets` or `dataset_ids`, recall can combine session lookup with graph retrieval.
  * If you pass an explicit `query_type`, the default path is graph-backed retrieval. Session history can still be used during the LLM completion step, but session-cache QA lookup is not part of the default source set unless you pass `scope`.

  **Graph-backed completion with session history:**

  When graph-backed recall runs with `session_id` and the LLM completion step is enabled, Cognee loads prior session conversation history and prepends it to the completion prompt. If [`improve()`](/core-concepts/main-operations/improve) has built the [global context index](/core-concepts/further-concepts/global-context-index) and the retriever is configured with `include_global_context_index`, a background-knowledge prelude — the dataset's root summary plus the top matching bucket summaries — is also prepended. That prelude comes from the index, not from a per-session snapshot.

  **Session writes:**

  When the LLM completion step runs through session-enabled graph retrieval, Cognee appends a new QA entry to the session cache with the `question`, stored `context`, and generated `answer`. The next compatible recall on the same `session_id` can see that entry.

  **Using `only_context=True`:**

  Pass `only_context=True` to skip the final LLM completion. Because the QA write happens during completion, `only_context=True` also avoids adding a new QA entry to the session cache.

  ```python theme={null}
  # Session-aware recall with answer generation can write a new QA entry
  answer = await cognee.recall(
      query_text="What did we decide about pricing?",
      session_id="chat-42",
  )

  # Returns retrieved context only; skips final LLM completion and QA write
  context = await cognee.recall(
      query_text="What did we decide about pricing?",
      session_id="chat-42",
      only_context=True,
  )
  ```

  Use `only_context=True` when you want retrieval output without LLM summarization and without growing the session cache.
</Accordion>

<Accordion title="Dataset scoping">
  ```python theme={null}
  answers = await cognee.recall(
      query_text="Give me an overview of this dataset.",
      datasets=["product_docs"],
  )
  ```

  * **Scoping is exclusive.** When you pass `datasets` (or `dataset_ids`), retrieval runs against **only** those datasets — Cognee does not pull from any other dataset, even ones the current user can read.
  * **When you omit both**, recall searches across **all** datasets the current user has read access to. Supply a dataset to narrow that down to a single knowledge base.
  * `datasets` limits graph retrieval to named datasets. With backend access control enabled, names are resolved only against datasets owned by the current user.
  * `dataset_ids` scopes retrieval by dataset UUID instead of name. Use this for shared datasets that the current user can access but did not create. When supplied, it takes precedence over `datasets` and the name-to-UUID resolution step is skipped.
  * With `session_id` plus either `datasets` or `dataset_ids`, recall becomes hybrid: session context is available, but graph retrieval is scoped to the selected dataset or dataset UUIDs.

  <Warning>
    If you set `query_type=SearchType.AGENTIC_COMPLETION`, the resolved graph scope must contain exactly one dataset. Passing multiple dataset names or UUIDs, or leaving scope broad enough to match multiple readable datasets, can raise `422 InvalidAgenticDatasetScope`.
  </Warning>

  <Warning>
    If Alice created `shared_dataset` and Bob only has permission to use it, Bob should query it with `dataset_ids=[shared_id]`, not `datasets=["shared_dataset"]`. Name-based lookup can fail for non-owners even when they have read access.
  </Warning>
</Accordion>

<Accordion title="Parameters">
  <Tabs>
    <Tab title="Basic Parameters">
      | Option                                 | What it does                                                                                                                                                  |
      | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
      | `query_text`                           | The natural-language query to answer.                                                                                                                         |
      | `query_type`                           | Forces a specific underlying search type instead of using auto-routing.                                                                                       |
      | `datasets`                             | Restricts graph retrieval to specific dataset names. Names are resolved only against datasets owned by the current user.                                      |
      | `dataset_ids`                          | Restricts graph retrieval by dataset UUIDs. Use this for shared datasets the current user did not create. Takes precedence over `datasets` when both are set. |
      | `top_k`                                | Limits the number of returned results. Defaults to `15`.                                                                                                      |
      | `auto_route`                           | Enables the rule-based query router. Defaults to `True`.                                                                                                      |
      | `session_id`                           | Enables session-aware retrieval and session-cache lookup.                                                                                                     |
      | `only_context`                         | Returns retrieved context only. The final LLM answer is not generated.                                                                                        |
      | `system_prompt` / `system_prompt_path` | Customizes the generation prompt.                                                                                                                             |
    </Tab>

    <Tab title="Advanced Parameters">
      | Option                                    | What it does                                                                                                                                                                                                                                                              |
      | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
      | `node_name` / `node_name_filter_operator` | Restricts graph retrieval to matching node names or node sets.                                                                                                                                                                                                            |
      | `wide_search_top_k`                       | Expands the initial candidate set used by graph-completion retrieval before ranking.                                                                                                                                                                                      |
      | `triplet_distance_penalty`                | Adjusts scoring for triplet-based retrieval paths.                                                                                                                                                                                                                        |
      | `feedback_influence`                      | Applies stored feedback weights during ranking where supported.                                                                                                                                                                                                           |
      | `verbose`                                 | Returns extra retrieval details from the lower-level graph search path.                                                                                                                                                                                                   |
      | `retriever_specific_config`               | Passes advanced configuration directly to the selected retriever.                                                                                                                                                                                                         |
      | `response_model`                          | A Pydantic model class for structured completion output. The validated payload lands in each result's `structured` field. Shorthand for `retriever_specific_config={"response_model": ...}` — passing two different models across the two raises `CogneeValidationError`. |
      | `user`                                    | Runs recall under a specific user context, affecting dataset access and session-cache lookup.                                                                                                                                                                             |
    </Tab>
  </Tabs>
</Accordion>

<Accordion title="Under the hood — legacy operations">
  `recall()` runs [Search](/core-concepts/main-operations/legacy-operations/search) under the hood for graph-backed retrieval.

  Use legacy Search directly when you need to select a specific retriever, inspect retrieval internals, or use advanced parameters not exposed by `recall()`. See also [Search Basics](/guides/search-basics) for the full set of retrieval options.
</Accordion>

<Accordion title="recall() vs search(): when to use each">
  |                           | `recall()`                                                                           | `search()` (legacy)                                                                                 |
  | ------------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------- |
  | **Recommended for**       | Most v1.0 use cases                                                                  | Advanced retriever control                                                                          |
  | **Search type selection** | Auto-routes by default; pass `query_type` to override                                | Always explicit; defaults to `GRAPH_COMPLETION`                                                     |
  | **Session behavior**      | Searches session-cache QA entries by keyword; falls through to graph on miss         | `session_id` writes/reads conversation history only — no cache lookup                               |
  | **Source tagging**        | Results carry `source` (`"graph"`, `"session"`, `"trace"`, `"session_context"`, ...) | No source tagging                                                                                   |
  | **Parameter surface**     | Compact; explicit keyword options documented in the API reference                    | Full surface — `neighborhood_depth`, `node_type`, `triplet_distance_penalty` with explicit defaults |

  **Use `recall()`** when you want to ask a question and get an answer. It handles routing, session lookup, and source attribution automatically.

  **Use `search()` directly** when you need a specific retriever, lower-level parameters such as `neighborhood_depth` or `node_type`, or when building custom pipelines.
</Accordion>

<Columns cols={3}>
  <Card title="Remember" icon="brain" href="/core-concepts/main-operations/remember">
    Create permanent or session memory
  </Card>

  <Card title="Improve" icon="sparkles" href="/core-concepts/main-operations/improve">
    Enrich the graph for better future recall
  </Card>

  <Card title="Understand Recall with RAG Completion" icon="search" href="/guides/rag-recall">
    Hands-on guide to recall() and RAG\_COMPLETION
  </Card>
</Columns>
