# How Hermes Agent Implements Memory and User Modeling Using Honcho

> Learn how Hermes Agent uses Honcho to build AI-native sessions, manage long-term memory, prefetch user context, and dynamically retrieve user information for enhanced conversations.

- Repository: [Nous Research/hermes-agent](https://github.com/NousResearch/hermes-agent)
- Tags: deep-dive
- Published: 2026-03-09

---

**Hermes Agent implements memory and user modeling using Honcho by creating AI-native sessions per chat, synchronizing conversation history to a long-term memory service, prefetching distilled user representations into system prompts, and exposing a `query_user_context` tool for dynamic retrieval.**

The NousResearch/hermes-agent repository augments its built-in SQLite session store with Honcho, an AI-native long-term memory service. When configured, Hermes Agent automatically manages memory synchronization, user modeling, and contextual retrieval through three core modules: [`honcho_integration/session.py`](https://github.com/NousResearch/hermes-agent/blob/main/honcho_integration/session.py), [`tools/honcho_tools.py`](https://github.com/NousResearch/hermes-agent/blob/main/tools/honcho_tools.py), and [`run_agent.py`](https://github.com/NousResearch/hermes-agent/blob/main/run_agent.py).

## Honcho Session Architecture and Initialization

### Session Creation and Peer Configuration

When Hermes Agent receives a new channel-chat identifier, the `HonchoSessionManager.get_or_create()` method in [`honcho_integration/session.py`](https://github.com/NousResearch/hermes-agent/blob/main/honcho_integration/session.py) initializes a local wrapper and corresponding Honcho session. The system creates distinct peers for the user and assistant:

```python

# From honcho_integration/session.py

user_peer_id = self._sanitize_id(self._config.peer_name or f"user-{channel}-{chat_id}")
assistant_peer_id = self._config.ai_peer if self._config else "hermes-assistant"
honcho_session_id = self._sanitize_id(key)

user_peer = self._get_or_create_peer(user_peer_id)
assistant_peer = self._get_or_create_peer(assistant_peer_id)

honcho_session, existing_messages = self._get_or_create_honcho_session(
    honcho_session_id, user_peer, assistant_peer)

```

### ID Sanitization and Peer Setup

The `_sanitize_id()` function ensures all identifiers conform to Honcho's requirements (`^[a-zA-Z0-9_-]+$`). The SDK call `session.add_peers()` configures observation rules where the user peer observes both itself and the assistant, while the assistant only observes the user. This dialectic setup enables Honcho to build a semantic user model through peer interactions.

## Synchronizing Conversation History to Honcho

### Message Sync Implementation

The `HonchoSessionManager.save()` method handles bidirectional synchronization. It extracts unsynced messages from the local cache and pushes them to Honcho:

```python

# From honcho_integration/session.py

new_messages = [m for m in session.messages if not m.get("_synced")]
honcho_messages = [
    (user_peer if msg["role"] == "user" else assistant_peer).message(msg["content"])
    for msg in new_messages
]
honcho_session.add_messages(honcho_messages)

```

### Idempotent Sync Guarantees

After successful upload, each message receives a `"_synced": True` flag. This ensures **idempotent synchronization**—running the save operation multiple times will not create duplicate entries in Honcho's long-term memory store.

## Prefetching User Context for System Prompts

### Semantic User Representation

The `get_prefetch_context()` method in [`honcho_integration/session.py`](https://github.com/NousResearch/hermes-agent/blob/main/honcho_integration/session.py) performs a single Honcho `context()` call with semantic search against the user's message. It returns two critical components:

- **Representation**: A concise textual summary of the user's persona and goals.
- **Card**: A structured list of salient facts from the peer card.

```python

# From honcho_integration/session.py

ctx = honcho_session.context(
    summary=False,
    tokens=self._context_tokens,
    peer_target=session.user_peer_id,
    search_query=user_message,
)
return {"representation": ctx.peer_representation or "", "card": "\n".join(ctx.peer_card or [])}

```

### Context Injection in run_agent.py

In [`run_agent.py`](https://github.com/NousResearch/hermes-agent/blob/main/run_agent.py), the `_honcho_prefetch()` method retrieves this context and injects it into the system prompt:

```python

# From run_agent.py

def _honcho_prefetch(self, user_message: str) -> str:
    if not self._honcho or not self._honcho_session_key:
        return ""
    ctx = self._honcho.get_prefetch_context(self._honcho_session_key, user_message)
    parts = [ctx.get("representation", ""), ctx.get("card", "")]
    return "# Honcho User Context\n" + "\n\n".join(p for p in parts if p)

```

This ensures the LLM receives up-to-date user context at the start of every turn.

## Dynamic User Modeling with query_user_context

### Tool Registration and Schema

The [`tools/honcho_tools.py`](https://github.com/NousResearch/hermes-agent/blob/main/tools/honcho_tools.py) file registers the `query_user_context` tool, making it available to the LLM for dynamic retrieval:

```python

# From tools/honcho_tools.py

registry.register(
    name="query_user_context",
    toolset="honcho",
    schema=HONCHO_TOOL_SCHEMA,
    handler=_handle_query_user_context,
    check_fn=_check_honcho_available,
)

```

The tool schema accepts a single parameter: `query` (a natural-language question about the user).

### Dialectic Retrieval via User Peer

When invoked, the handler calls `HonchoSessionManager.get_user_context()`:

```python

# From honcho_integration/session.py

def get_user_context(self, session_key: str, query: str) -> str:
    session = self._sessions.get(session_key)
    if not session:
        return "No active Honcho session found."
    user_peer = self._get_or_create_peer(session.user_peer_id)
    return user_peer.chat(query)

```

This executes a **dialectic chat query** against the Honcho user peer, allowing the model to ask specific questions like "What are the user's top three interests?" and receive synthesized answers based on the accumulated memory.

## Migrating Legacy Memory Files

When Honcho is enabled mid-conversation, [`honcho_integration/session.py`](https://github.com/NousResearch/hermes-agent/blob/main/honcho_integration/session.py) provides `migrate_local_history()` and `migrate_memory_files()` to preserve existing context. These methods upload prior transcripts as [`prior_history.txt`](https://github.com/NousResearch/hermes-agent/blob/main/prior_history.txt) and migrate local [`MEMORY.md`](https://github.com/NousResearch/hermes-agent/blob/main/MEMORY.md) and [`USER.md`](https://github.com/NousResearch/hermes-agent/blob/main/USER.md) files into Honcho's long-term store, ensuring **zero knowledge loss** during the transition.

## Summary

- **Hermes Agent** integrates Honcho through [`honcho_integration/session.py`](https://github.com/NousResearch/hermes-agent/blob/main/honcho_integration/session.py), [`tools/honcho_tools.py`](https://github.com/NousResearch/hermes-agent/blob/main/tools/honcho_tools.py), and hooks in [`run_agent.py`](https://github.com/NousResearch/hermes-agent/blob/main/run_agent.py).
- **Session management** creates AI-native Honcho sessions with sanitized IDs and configured peer observation rules.
- **Synchronization** pushes local messages to Honcho after every turn using idempotent sync with `_synced` flags.
- **Prefetching** retrieves semantic user representations and peer cards to inject into system prompts automatically.
- **Dynamic queries** expose the `query_user_context` tool, allowing the LLM to perform dialectic retrieval against the user peer.
- **Migration** utilities preserve legacy local memory when upgrading to Honcho.

## Frequently Asked Questions

### How does Hermes Agent handle Honcho session IDs?

Hermes Agent sanitizes all session identifiers using the `_sanitize_id()` method in [`honcho_integration/session.py`](https://github.com/NousResearch/hermes-agent/blob/main/honcho_integration/session.py), ensuring they match Honcho's required pattern of alphanumeric characters, underscores, and hyphens (`^[a-zA-Z0-9_-]+$`). This prevents validation errors when creating sessions with complex channel identifiers like `telegram:123456`.

### What is the difference between prefetch context and query_user_context?

**Prefetch context** operates automatically at the start of each turn via `_honcho_prefetch()` in [`run_agent.py`](https://github.com/NousResearch/hermes-agent/blob/main/run_agent.py), retrieving a semantic summary and peer card to inject into the system prompt. **query_user_context** is a dynamic tool registered in [`tools/honcho_tools.py`](https://github.com/NousResearch/hermes-agent/blob/main/tools/honcho_tools.py) that the LLM can explicitly invoke mid-conversation to ask specific questions about the user, triggering a dialectic chat query against the Honcho user peer.

### How does the agent ensure no duplicate messages are synced to Honcho?

The `HonchoSessionManager.save()` method in [`honcho_integration/session.py`](https://github.com/NousResearch/hermes-agent/blob/main/honcho_integration/session.py) filters messages using the `_synced` flag, only selecting entries where `not m.get("_synced")`. After successfully uploading to Honcho via `honcho_session.add_messages()`, it marks each message with `"_synced": True`, making subsequent save operations idempotent and preventing duplicate entries in the long-term memory store.

### Can I use Hermes Agent memory features without Honcho?

Yes, Hermes Agent maintains a **fallback architecture** using SQLite-based session stores and file-based memory ([`MEMORY.md`](https://github.com/NousResearch/hermes-agent/blob/main/MEMORY.md), [`USER.md`](https://github.com/NousResearch/hermes-agent/blob/main/USER.md)) when Honcho is not configured. However, enabling Honcho in `~/.honcho/config.json` upgrades the system to AI-native long-term memory with semantic search, dialectic user modeling, and automatic context prefetching, providing significantly richer user modeling capabilities than the local file-based approach.