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

# User Analysis Memory

> Learn about users and build comprehensive profiles

## Overview

User Analysis Memory extracts user traits from conversations and builds persistent profiles. This enables personalization across sessions and adaptive agent behavior.

## Save vs Load

| Flag                        | Purpose                                                                                 |
| --------------------------- | --------------------------------------------------------------------------------------- |
| `user_analysis_memory`      | **Save**: Analyze conversations and persist user profiles                               |
| `load_user_analysis_memory` | **Load**: Inject user profile into subsequent runs (defaults to `user_analysis_memory`) |

## Basic Usage

```python theme={null}
from upsonic import Agent, Task
from upsonic.storage.memory import Memory
from upsonic.storage.sqlite import SqliteStorage

storage = SqliteStorage(db_file="users.db")

memory = Memory(
    storage=storage,
    session_id="session_001",
    user_id="user_abc",
    user_analysis_memory=True,
    model="anthropic/claude-sonnet-4-5"
)

agent = Agent("anthropic/claude-sonnet-4-5", memory=memory)

result1 = agent.do(Task("I'm a data scientist with 5 years of ML experience"))
result2 = agent.do(Task("What do you know about me?"))
print(result2)  # "You're a data scientist with 5 years of ML experience"
```

## Standalone Usage

User analysis memory works without full session memory. The agent saves and loads
user profiles independently:

```python theme={null}
from upsonic import Agent, Task
from upsonic.storage.memory import Memory
from upsonic.storage.sqlite import SqliteStorage

storage = SqliteStorage(db_file="profiles.db")

memory = Memory(
    storage=storage,
    session_id="session_001",
    user_id="user_abc",
    full_session_memory=False,     # No raw history
    user_analysis_memory=True,     # Save user profile
    model="anthropic/claude-sonnet-4-5"
)

agent = Agent("anthropic/claude-sonnet-4-5", memory=memory)

result1 = agent.do(Task("I'm Alice, a Python developer who prefers dark mode"))
result2 = agent.do(Task("What do you know about me?"))
print(result2)  # Recalls user profile without raw history
```

## Custom Profile Schema

Define specific fields to track:

```python theme={null}
from pydantic import BaseModel, Field
from typing import Optional, List
from upsonic import Agent, Task
from upsonic.storage.memory import Memory
from upsonic.storage.sqlite import SqliteStorage

class DeveloperProfile(BaseModel):
    name: Optional[str] = Field(None, description="Developer name")
    languages: Optional[List[str]] = Field(None, description="Programming languages")
    experience_years: Optional[int] = Field(None, description="Years of experience")
    preferred_editor: Optional[str] = Field(None, description="Preferred code editor")

storage = SqliteStorage(db_file="developers.db")

memory = Memory(
    storage=storage,
    session_id="session_001",
    user_id="dev_123",
    user_analysis_memory=True,
    user_profile_schema=DeveloperProfile,
    model="anthropic/claude-sonnet-4-5"
)

agent = Agent("anthropic/claude-sonnet-4-5", memory=memory)

result = agent.do(Task("I'm Alice, I use Python and Go, been coding for 8 years, love VS Code"))
print(result)
```

## Dynamic Profile Generation

Let the agent discover and create custom fields:

```python theme={null}
from upsonic import Agent, Task
from upsonic.storage.memory import Memory
from upsonic.storage.sqlite import SqliteStorage

storage = SqliteStorage(db_file="dynamic.db")

memory = Memory(
    storage=storage,
    session_id="session_001",
    user_id="user_456",
    user_analysis_memory=True,
    dynamic_user_profile=True,  # Agent creates custom fields
    model="anthropic/claude-sonnet-4-5"
)

agent = Agent("anthropic/claude-sonnet-4-5", memory=memory)

result = agent.do(Task("I prefer concise answers, work night shifts, and love hiking"))
print(result)  # Agent adapts to learned preferences
```

## Cross-Session Persistence

User profiles persist across sessions:

```python theme={null}
from upsonic import Agent, Task
from upsonic.storage.memory import Memory
from upsonic.storage.sqlite import SqliteStorage

storage = SqliteStorage(db_file="profiles.db")

# Session 1: Learn about user
memory1 = Memory(
    storage=storage,
    session_id="session_001",
    user_id="customer_789",
    user_analysis_memory=True,
    model="anthropic/claude-sonnet-4-5"
)
agent1 = Agent("anthropic/claude-sonnet-4-5", memory=memory1)
agent1.do(Task("I'm John, I run a small bakery in Seattle"))

# Session 2: New session, same user - profile is loaded
memory2 = Memory(
    storage=storage,
    session_id="session_002",  # Different session
    user_id="customer_789",     # Same user
    user_analysis_memory=True,
    model="anthropic/claude-sonnet-4-5"
)
agent2 = Agent("anthropic/claude-sonnet-4-5", memory=memory2)
result = agent2.do(Task("Remind me what you know about me"))
print(result)  # "You're John, you run a bakery in Seattle"
```

## Save-Only Mode

Save profiles for analytics without injecting them into the agent's context:

```python theme={null}
from upsonic import Agent, Task
from upsonic.storage.memory import Memory
from upsonic.storage.sqlite import SqliteStorage

storage = SqliteStorage(db_file="analytics.db")

memory = Memory(
    storage=storage,
    session_id="session_001",
    user_id="user_789",
    user_analysis_memory=True,          # Save profiles
    load_user_analysis_memory=False,    # Don't inject into context
    model="anthropic/claude-sonnet-4-5"
)

agent = Agent("anthropic/claude-sonnet-4-5", memory=memory)
result = agent.do(Task("I also speak Spanish and French"))
print(result)
```

## Update Modes

| Mode        | Behavior                                         |
| ----------- | ------------------------------------------------ |
| `'update'`  | Merge new traits with existing profile (default) |
| `'replace'` | Replace entire profile with new traits           |

```python theme={null}
from upsonic import Agent, Task
from upsonic.storage.memory import Memory
from upsonic.storage.sqlite import SqliteStorage

storage = SqliteStorage(db_file="modes.db")

memory = Memory(
    storage=storage,
    session_id="session_001",
    user_id="user_123",
    user_analysis_memory=True,
    user_memory_mode='update',
    model="anthropic/claude-sonnet-4-5"
)

agent = Agent("anthropic/claude-sonnet-4-5", memory=memory)
result = agent.do(Task("I also speak Spanish and French"))
print(result)
```

## Parameters

| Parameter                   | Type                           | Default        | Description                                                    |
| --------------------------- | ------------------------------ | -------------- | -------------------------------------------------------------- |
| `user_analysis_memory`      | `bool`                         | `False`        | Save user profiles                                             |
| `load_user_analysis_memory` | `bool \| None`                 | `None`         | Inject profiles into runs (defaults to `user_analysis_memory`) |
| `user_id`                   | `str`                          | auto-generated | User identifier                                                |
| `model`                     | `str \| Model`                 | (required)     | Model for trait extraction                                     |
| `user_profile_schema`       | `BaseModel \| None`            | `None`         | Custom profile schema                                          |
| `dynamic_user_profile`      | `bool`                         | `False`        | Auto-generate profile fields                                   |
| `user_memory_mode`          | `Literal['update', 'replace']` | `'update'`     | Profile update strategy                                        |
