# User Profile: Always Extraction (Deep Dive) (/examples/learning/user-profile/always-extraction)



```python title="always_extraction.py"
"""
User Profile: Always Extraction (Deep Dive)
============================================
Automatic profile extraction from natural conversation.

ALWAYS mode extracts profile information in the background after each response.
The user doesn't see tools - extraction happens invisibly.

This example shows gradual profile building across multiple conversations.

Compare with: 02_agentic_mode.py for explicit tool-based updates.
See also: 01_basics/1a_user_profile_always.py for the basics.
"""

from agno.agent import Agent
from agno.db.postgres import PostgresDb
from agno.learn import LearningMachine, LearningMode, UserProfileConfig
from agno.models.openai import OpenAIResponses

# ---------------------------------------------------------------------------
# Create Agent
# ---------------------------------------------------------------------------

db = PostgresDb(db_url="postgresql+psycopg://ai:ai@localhost:5532/ai")

agent = Agent(
    model=OpenAIResponses(id="gpt-5.5"),
    db=db,
    learning=LearningMachine(
        user_profile=UserProfileConfig(
            mode=LearningMode.ALWAYS,
        ),
    ),
    markdown=True,
)

# ---------------------------------------------------------------------------
# Run: Gradual Profile Building
# ---------------------------------------------------------------------------

if __name__ == "__main__":
    user_id = "marcus@example.com"

    # Conversation 1: Basic introduction
    print("\n" + "=" * 60)
    print("CONVERSATION 1: Basic introduction")
    print("=" * 60 + "\n")

    agent.print_response(
        "Hi! I'm Marcus, nice to meet you.",
        user_id=user_id,
        session_id="conv_1",
        stream=True,
    )
    agent.learning_machine.user_profile_store.print(user_id=user_id)

    # Conversation 2: Share work context
    print("\n" + "=" * 60)
    print("CONVERSATION 2: Work context")
    print("=" * 60 + "\n")

    agent.print_response(
        "I'm a senior engineer at Stripe, focusing on payment systems.",
        user_id=user_id,
        session_id="conv_2",
        stream=True,
    )
    agent.learning_machine.user_profile_store.print(user_id=user_id)

    # Conversation 3: Preferences
    print("\n" + "=" * 60)
    print("CONVERSATION 3: Preferences (implicit extraction)")
    print("=" * 60 + "\n")

    agent.print_response(
        "I prefer code examples over long explanations. "
        "I'm very familiar with Python and Go.",
        user_id=user_id,
        session_id="conv_3",
        stream=True,
    )
    agent.learning_machine.user_profile_store.print(user_id=user_id)

    # Conversation 4: Nickname
    print("\n" + "=" * 60)
    print("CONVERSATION 4: Preferred name update")
    print("=" * 60 + "\n")

    agent.print_response(
        "By the way, most people call me Marc.",
        user_id=user_id,
        session_id="conv_4",
        stream=True,
    )
    agent.learning_machine.user_profile_store.print(user_id=user_id)
```

With `learning=` enabled, ALWAYS extraction starts in parallel before the current model response. The retained source comments that say “after each response” do not describe that timing. Extraction uses the messages available at the start of the run; include conversation history if it needs earlier assistant replies.

The default user profile stores `name` and `preferred_name`. For roles, routines, or communication preferences, define [custom profile fields](/examples/learning/user-profile/custom-schema) or enable [user memory](/examples/learning/basics/a-user-memory-always). The broader profile descriptions in the retained source do not add those fields automatically.

## Run the Example [#run-the-example]

<Steps>
    <Step title="Set up your virtual environment">
      <CodeBlockTabs defaultValue="Mac">
        <CodeBlockTabsList>
          <CodeBlockTabsTrigger value="Mac">
            Mac
          </CodeBlockTabsTrigger>

          <CodeBlockTabsTrigger value="Windows">
            Windows
          </CodeBlockTabsTrigger>
        </CodeBlockTabsList>

        <CodeBlockTab value="Mac">
          ```bash
          uv venv --python 3.12
          source .venv/bin/activate
          ```
        </CodeBlockTab>

        <CodeBlockTab value="Windows">
          ```bash
          uv venv --python 3.12
          .venv\Scripts\activate
          ```
        </CodeBlockTab>
      </CodeBlockTabs>
    </Step>

  <Step title="Install dependencies">
    ```bash
    uv pip install -U agno "psycopg[binary]" openai sqlalchemy
    ```
  </Step>

  <Step title="Export your OpenAI API key">
    <CodeBlockTabs defaultValue="Mac/Linux">
      <CodeBlockTabsList>
        <CodeBlockTabsTrigger value="Mac/Linux">
          Mac/Linux
        </CodeBlockTabsTrigger>

        <CodeBlockTabsTrigger value="Windows">
          Windows
        </CodeBlockTabsTrigger>
      </CodeBlockTabsList>

      <CodeBlockTab value="Mac/Linux">
        ```bash
        export OPENAI_API_KEY="your_openai_api_key_here"
        ```
      </CodeBlockTab>

      <CodeBlockTab value="Windows">
        ```bash
        $Env:OPENAI_API_KEY="your_openai_api_key_here"
        ```
      </CodeBlockTab>
    </CodeBlockTabs>
  </Step>

    <Step title="Run PgVector">
      <CodeBlockTabs defaultValue="macOS / Linux">
        <CodeBlockTabsList>
          <CodeBlockTabsTrigger value="macOS / Linux">
            macOS / Linux
          </CodeBlockTabsTrigger>

          <CodeBlockTabsTrigger value="Windows">
            Windows
          </CodeBlockTabsTrigger>
        </CodeBlockTabsList>

        <CodeBlockTab value="macOS / Linux">
          ```bash
          docker run -d \
            -e POSTGRES_DB=ai \
            -e POSTGRES_USER=ai \
            -e POSTGRES_PASSWORD=ai \
            -e PGDATA=/var/lib/postgresql \
            -v pgvolume:/var/lib/postgresql \
            -p 5532:5432 \
            --name pgvector \
            agnohq/pgvector:18
          ```
        </CodeBlockTab>

        <CodeBlockTab value="Windows">
          ```powershell
          docker run -d `
            -e POSTGRES_DB=ai `
            -e POSTGRES_USER=ai `
            -e POSTGRES_PASSWORD=ai `
            -e PGDATA=/var/lib/postgresql `
            -v pgvolume:/var/lib/postgresql `
            -p 5532:5432 `
            --name pgvector `
            agnohq/pgvector:18
          ```
        </CodeBlockTab>
      </CodeBlockTabs>
    </Step>

  <Step title="Run the example">
    Save the code above as `always_extraction.py`, then run:

    ```bash
    python always_extraction.py
    ```
  </Step>
</Steps>

Full source: [cookbook/08\_learning/02\_user\_profile/01\_always\_extraction.py](https://github.com/agno-agi/agno/blob/8f36eaf2d18e91afa7b327eec66a3cd3685dcb87/cookbook/08_learning/02_user_profile/01_always_extraction.py)
