> ## 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.

# Agent Memory Quickstart

> Minimal end-to-end example showing session memory and graph memory with cognee.agent_memory

A minimal comparison of two agent-memory patterns: one agent that remembers the active session and one agent that only reads from the persistent knowledge graph.

**Before you start:**

* Complete [Quickstart](/getting-started/quickstart) or have Cognee installed and configured
* Ensure you have [LLM Providers](/setup-configuration/llm-providers) configured
* Be familiar with the `remember()` workflow
* Keep caching enabled — it is on by default, and the session options used below require it:

```dotenv theme={null}
CACHING=true
```

<Warning>
  `with_session_memory`, `save_session_traces`, and `persist_session_trace_after` all read and write the [session cache](/core-concepts/sessions-and-caching). With `CACHING=false`, the decorator raises a validation error as soon as it is applied — not when the function is called. The `with_memory` (graph retrieval) path works without caching.
</Warning>

## Shared Setup

Both agents use the same `LLMGateway` helper. The updated example starts clean with `forget(everything=True)`, stores one baseline fact with `remember()`, and then compares session memory against graph memory.

`LLMGateway.acreate_structured_output()` automatically picks up whatever memory the decorator retrieved and prepends it to the text input. In this flow, `save_session_traces=True` records each of the support agent's turns into the session cache, and `persist_session_trace_after=3` is what bridges those traces into the knowledge graph.

```python theme={null}
import asyncio
import os
import warnings

os.environ["LOG_LEVEL"] = "ERROR"
os.environ["COGNEE_LOG_FILE"] = "false"
warnings.filterwarnings("ignore")

import cognee  # noqa: E402
from cognee.infrastructure.llm.LLMGateway import LLMGateway  # noqa: E402

SESSION_ID = "ticket_001"
BUG = "Login fails with error XQ-99."
FIX = "Set XQ_TOKEN=1 in the .env file."
NO_INFO = "NO INFO AVAILABLE"


async def setup() -> None:
    await cognee.forget(everything=True)
    await cognee.remember(
        ["Our app is a web service. Users log in to access their account."], self_improvement=False
    )


async def ask_llm(question: str, system_prompt: str) -> str:
    return await LLMGateway.acreate_structured_output(
        text_input=question,
        system_prompt=system_prompt,
        response_model=str,
    )
```

## Compare the Agents

<Tabs>
  <Tab title="Support Agent">
    ```python theme={null}
    @cognee.agent_memory(
        with_memory=False,
        with_session_memory=True,
        save_session_traces=True,
        session_id=SESSION_ID,
        session_memory_last_n=2,
        persist_session_trace_after=3,
    )
    async def support_agent(question: str, system_prompt: str) -> str:
        return await ask_llm(question, system_prompt)
    ```

    This agent relies on session memory instead of graph retrieval. It can remember the recent conversation, and after enough turns its saved traces are persisted into the knowledge graph.
  </Tab>

  <Tab title="FAQ Bot">
    ```python theme={null}
    @cognee.agent_memory(
        with_memory=True,
        with_session_memory=False,
        save_session_traces=False,
        memory_query_from_method="question",
    )
    async def faq_bot(question: str, system_prompt: str) -> str:
        return await ask_llm(question, system_prompt)
    ```

    This agent does the opposite: it skips session memory and reads only from the persistent knowledge graph. It learns only after the support agent's saved traces have been persisted.
  </Tab>
</Tabs>

## From Session Traces to the Permanent Graph

The two agents above read from different places, so it helps to know which store each parameter touches:

| Parameter                       | Store                                                | Effect                                                                                  |
| ------------------------------- | ---------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `with_memory=True`              | Permanent graph                                      | Searches `dataset_name` (default `main_dataset`) before the call and injects the result |
| `with_session_memory=True`      | [Session cache](/core-concepts/sessions-and-caching) | Injects the last `session_memory_last_n` trace summaries for `(user, session_id)`       |
| `save_session_traces=True`      | Session cache                                        | Writes one trace step per call — inputs, output, and retrieved memory                   |
| `persist_session_trace_after=N` | Permanent graph                                      | Every `N`th trace, memifies the recent traces into the graph                            |

`save_session_traces=True` alone keeps traces in the session cache, where only `with_session_memory` can see them. Adding `persist_session_trace_after=N` is what bridges them into the [permanent graph](/core-concepts/main-operations/remember): after every `N`th trace step in the session, Cognee runs a [memify](/core-concepts/main-operations/legacy-operations/memify) pass that writes the trace summaries into `dataset_name` under the `agent_trace_feedbacks` node set. That is why `faq_bot` — which reads only the graph — answers correctly only after `support_agent` has taken three turns.

<Note>
  Trace persistence is best-effort: failures are logged and never propagate out of your agent function. See the [decorator parameters](/core-concepts/further-concepts/agent-memory-decorator) for the options that control what gets persisted and where.
</Note>

## Full Example

<Accordion title="Guide">
  ```python theme={null}
  import asyncio
  import os
  import warnings

  os.environ["LOG_LEVEL"] = "ERROR"
  os.environ["COGNEE_LOG_FILE"] = "false"
  warnings.filterwarnings("ignore")

  import cognee  # noqa: E402
  from cognee.infrastructure.llm.LLMGateway import LLMGateway  # noqa: E402

  SESSION_ID = "ticket_001"
  BUG = "Login fails with error XQ-99."
  FIX = "Set XQ_TOKEN=1 in the .env file."
  NO_INFO = "NO INFO AVAILABLE"


  async def setup() -> None:
      await cognee.forget(everything=True)
      await cognee.remember(
          ["Our app is a web service. Users log in to access their account."], self_improvement=False
      )


  async def ask_llm(question: str, system_prompt: str) -> str:
      return await LLMGateway.acreate_structured_output(
          text_input=question,
          system_prompt=system_prompt,
          response_model=str,
      )


  @cognee.agent_memory(
      with_memory=False,
      with_session_memory=True,
      save_session_traces=True,
      session_id=SESSION_ID,
      session_memory_last_n=2,
      persist_session_trace_after=3,
  )
  async def support_agent(question: str, system_prompt: str) -> str:
      return await ask_llm(question, system_prompt)


  @cognee.agent_memory(
      with_memory=True,
      with_session_memory=False,
      save_session_traces=False,
      memory_query_from_method="question",
  )
  async def faq_bot(question: str, system_prompt: str) -> str:
      return await ask_llm(question, system_prompt)


  async def main() -> None:
      print("=== Agent Memory Quickstart ===\n")
      print("support_agent: session memory  — knows what happened in this conversation.")
      print("faq_bot:       knowledge graph — knows only what has been formally filed.\n")

      print("Setting up knowledge graph...")
      await setup()
      print("Ready.\n")

      recall_prompt = f"Answer based on the available context. If it is not available in the context, say exactly: {NO_INFO}"

      support_agent_q1 = f"A user just reported this: {BUG}"
      print(f"support_agent_q: {support_agent_q1}")
      support_agent_a1 = await support_agent(
          support_agent_q1, f"Confirm you received it. Say exactly: {BUG}"
      )
      print(f"support_agent_a: {support_agent_a1}\n")

      faq_bot_q = "How do I fix error XQ-99?"

      support_agent_q2 = "What bug was just reported?"
      print(f"support_agent_q: {support_agent_q2}")
      support_agent_a2 = await support_agent(
          support_agent_q2,
          f"Use your session memory. If you know, say: {BUG} If not, say: {NO_INFO}",
      )
      print(f"support_agent_a: {support_agent_a2}")

      print(f"faq_bot_q:       {faq_bot_q}")
      faq_bot_a_before = await faq_bot(faq_bot_q, recall_prompt)
      print(f"faq_bot_a:       {faq_bot_a_before}")

      print("\n^ support_agent recalled the bug from session. faq_bot had no context yet.\n")

      support_agent_q3 = f"Log this fix for the login crash: {FIX}"
      print(f"support_agent_q: {support_agent_q3}")
      support_agent_a3 = await support_agent(support_agent_q3, f"Confirm the fix. Say exactly: {FIX}")
      print(f"support_agent_a: {support_agent_a3}")
      print("(Session traces are now persisted to the knowledge graph.)\n")

      print(f"faq_bot_q:       {faq_bot_q}")
      faq_bot_a_after = await faq_bot(faq_bot_q, recall_prompt)
      print(f"faq_bot_a:       {faq_bot_a_after}")

      print("\n^ faq_bot now answered correctly — session traces reached the knowledge graph.")


  if __name__ == "__main__":
      asyncio.run(main())
  ```
</Accordion>

<Note>
  The decorator does not create memory by itself. The example works because baseline graph memory is stored first with `remember()`, and the session-aware support agent persists traces only after those conversation turns happen.
</Note>

<Columns cols={2}>
  <Card title="Agent Memory Decorator" icon="bot" href="/core-concepts/further-concepts/agent-memory-decorator">
    Concept overview and parameter reference
  </Card>

  <Card title="Low-Level LLM" icon="cpu" href="/guides/low-level-llm">
    `LLMGateway` for direct model calls
  </Card>

  <Card title="Remember" icon="brain-cog" href="/core-concepts/main-operations/remember">
    Store memory before using the decorator
  </Card>

  <Card title="Sessions" icon="database" href="/guides/sessions">
    Learn how trace-backed session context behaves
  </Card>
</Columns>
