---
title: 'Guided Tutorial'
description: 'Step-by-step tutorial for building with Honcho'
icon: 'graduation-cap'
---

This comprehensive tutorial will walk you through building a complete AI application with Honcho, from basic setup to advanced features.

## What We'll Build

By the end of this tutorial, you'll have created a personal AI assistant that:
- Learns about users through conversation and remembers facts across sessions
- Automatically formats conversation context for any LLM (OpenAI, Anthropic, etc.)
- Answers questions about what it knows using natural language queries
- Handles multi-party conversations with theory-of-mind modeling

## Prerequisites

- Python 3.8 or higher
- Basic understanding of Python
- OpenAI API key (or another LLM provider)

## Part 1: Basic Setup

### Install Dependencies

<CodeGroup>
```bash pip
pip install honcho-ai openai python-dotenv
```

```bash poetry
poetry add honcho-ai openai python-dotenv
```
</CodeGroup>

### Environment Setup

Create a `.env` file in your project directory:

```bash
OPENAI_API_KEY=your_openai_api_key_here
HONCHO_API_KEY=your_honcho_api_key_here
```

### Initialize Honcho

```python
import os
from dotenv import load_dotenv
from honcho import Honcho
import openai

# Load environment variables
load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")

# Initialize Honcho with your app workspace
honcho = Honcho(workspace_id="personal-assistant-tutorial")
```

## Part 2: Peer Management

### Create and Manage Peers

```python
def get_user_peer(username):
    """Get or create a peer representing a user"""
    # Peers are created lazily - no API call until used
    user_peer = honcho.peer(f"user-{username}")
    print(f"Created peer for user: {username}")
    return user_peer

def get_assistant_peer():
    """Get or create the assistant peer"""
    assistant_peer = honcho.peer("assistant")
    print("Created assistant peer")
    return assistant_peer

# Create peers for our conversation
alice = get_user_peer("alice")
assistant = get_assistant_peer()

print(f"User peer ID: {alice.id}")
print(f"Assistant peer ID: {assistant.id}")
```

## Part 3: Session Management

### Create Conversation Sessions

```python
def start_new_session(session_name=None):
    """Start a new conversation session"""
    # Create session with descriptive ID
    session_id = session_name or f"chat-{int(time.time())}"
    session = honcho.session(session_id)

    # Add both peers to the session
    session.add_peers([alice, assistant])

    print(f"Started new session: {session.id}")
    return session

import time
# Start a session
session = start_new_session("daily-checkin")
```

### Message Handling

```python
def add_conversation_turn(session, user_message, assistant_response=None):
    """Add a conversation turn to the session"""
    messages_to_add = [alice.message(user_message)]

    if assistant_response:
        messages_to_add.append(assistant.message(assistant_response))

    session.add_messages(messages_to_add)
    print(f"Added {len(messages_to_add)} messages to session")

# Add user message
add_conversation_turn(session, "Hi! I'm working on a Python project today.")
```

## Part 4: LLM Integration with Context

### Store Information in Peer Representations

```python
def teach_assistant_about_user(assistant_peer, user_peer, facts):
    """Add facts about the user to the assistant's knowledge"""
    # Format facts as messages to build the assistant's representation
    fact_messages = []
    for fact in facts:
        fact_messages.append(assistant_peer.message(f"I learned that {user_peer.id} {fact}"))

    # Add these to the assistant's global knowledge
    assistant_peer.add_messages(fact_messages)
    print(f"Taught assistant {len(facts)} facts about {user_peer.id}")

def extract_facts_from_message(user_message):
    """Extract facts about the user from their message using LLM"""
    prompt = f"""
    Extract discrete facts about the user from this message:
    "{user_message}"

    Return only factual statements about the user, no inferences.
    Format as a simple list of facts starting with action verbs or descriptors.
    If no facts can be extracted, return an empty list.
    Example: "is working on a Python project", "likes morning coffee"
    """

    response = openai.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.1
    )

    facts_text = response.choices[0].message.content.strip()

    # Parse facts (simple line-by-line approach)
    facts = [fact.strip("- ").strip() for fact in facts_text.split('\n') if fact.strip()]
    return [fact for fact in facts if fact and len(fact) > 5]

# Extract and store facts
user_input = "Hi! I'm working on a Python project today."
facts = extract_facts_from_message(user_input)
print(f"Extracted facts: {facts}")

# Teach the assistant these facts
if facts:
    teach_assistant_about_user(assistant, alice, facts)
```

## Part 5: LLM Integration with Context

### Generate Responses Using Built-in Context

```python
def generate_response_with_context(session, assistant_peer, user_message):
    """Generate AI response using Honcho's built-in context management"""

    # Get formatted conversation context - Honcho handles the complexity!
    context = session.get_context(tokens=2000)
    messages = context.to_openai(assistant=assistant_peer)

    # Add the current user message
    messages.append({"role": "user", "content": user_message})

    # Call your LLM with the properly formatted context
    response = openai.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=messages,
        temperature=0.7
    )

    return response.choices[0].message.content

# Generate response using built-in context
user_input = "How's my project going?"
ai_response = generate_response_with_context(session, assistant, user_input)

print(f"AI Response: {ai_response}")

# Add the complete conversation turn to the session
add_conversation_turn(session, user_input, ai_response)
```

### Query Peer Knowledge Directly

```python
def get_personalized_insight(assistant_peer, user_peer, query):
    """Query what the assistant knows about a specific user"""
    # Honcho's chat handles context retrieval automatically
    response = assistant_peer.chat(
        f"Based on what I know about {user_peer.id}: {query}",
        target=user_peer
    )
    return response

# Get personalized insights without manual context building
insight = get_personalized_insight(
    assistant,
    alice,
    "What programming projects has this user worked on?"
)
print(f"Programming insights: {insight}")
```

## Part 6: Complete Conversation Loop

### Put It All Together

```python
def chat_with_assistant(user_peer, assistant_peer, message_text, session=None):
    """Complete conversation flow with memory and personalization"""

    # Use existing session or create new one
    if not session:
        session = start_new_session()

    # Extract facts from user message and teach assistant
    facts = extract_facts_from_message(message_text)
    if facts:
        teach_assistant_about_user(assistant_peer, user_peer, facts)

    # Generate response using Honcho's built-in context management
    ai_response = generate_response_with_context(session, assistant_peer, message_text)

    # Add the conversation turn to session
    add_conversation_turn(session, message_text, ai_response)

    return ai_response

# Test the complete flow
response = chat_with_assistant(
    alice,
    assistant,
    "I finished the authentication module for my Python project!"
)
print(f"Assistant: {response}")

# Continue the conversation
response2 = chat_with_assistant(
    alice,
    assistant,
    "What should I work on next?",
    session  # Continue in same session
)
print(f"Assistant: {response2}")
```

## Part 7: Advanced Features

### Multi-Session Memory

```python
def query_user_history(assistant_peer, user_peer, query):
    """Query what the assistant knows about the user across all sessions"""
    response = assistant_peer.chat(
        f"Based on everything I know about {user_peer.id}, {query}",
        target=user_peer
    )
    return response

# Query across all conversations
history_query = query_user_history(
    assistant,
    alice,
    "what programming languages and technologies has this user mentioned?"
)
print(f"User's programming history: {history_query}")
```

### Session-Specific Context

```python
def query_session_specific(assistant_peer, session, query):
    """Query what happened in a specific session"""
    response = assistant_peer.chat(
        query,
        session_id=session.id
    )
    return response

# Query about current session
session_summary = query_session_specific(
    assistant,
    session,
    "What did we discuss in this conversation?"
)
print(f"Session summary: {session_summary}")
```

### Working with Multiple Users

```python
def create_group_session(user_peers, assistant_peer):
    """Create a session with multiple users and an assistant"""
    group_session = honcho.session("group-discussion")

    # Add all peers to the session
    all_peers = user_peers + [assistant_peer]
    group_session.add_peers(all_peers)

    return group_session

# Create multiple user peers
bob = honcho.peer("user-bob")
charlie = honcho.peer("user-charlie")

# Create group session
group_session = create_group_session([alice, bob, charlie], assistant)

# Add group conversation
group_session.add_messages([
    alice.message("I think we should use Python for the backend"),
    bob.message("I prefer TypeScript, it's more type-safe"),
    charlie.message("What about performance considerations?"),
    assistant.message("Both are good choices. Let me help you compare them based on your requirements.")
])

# Query different perspectives
alice_view = assistant.chat(
    "What does alice think about the technology discussion?",
    target=alice,
    session_id=group_session.id
)
print(f"Alice's perspective: {alice_view}")
```

## Part 8: Advanced Features

### Direct Knowledge Queries

```python
# Instead of complex manual context building, use peer.chat() directly
response = assistant.chat("What programming languages does alice prefer and why?", target=alice)
print(f"Alice's language preferences: {response}")

# Query session-specific knowledge
session_insights = assistant.chat(
    "What was the main topic of discussion in this session?",
    session_id=session.id
)
print(f"Session insights: {session_insights}")
```

### Alternative LLM Formats

```python
# Honcho supports multiple LLM formats out of the box
def use_anthropic_format(session, assistant_peer, user_message):
    """Example using Anthropic's message format"""
    context = session.get_context(tokens=1500)
    messages = context.to_anthropic(assistant=assistant_peer)

    # Now you can use these messages with Anthropic's API
    # anthropic_response = anthropic.messages.create(...)

    return messages

# Get Anthropic-formatted messages
anthropic_messages = use_anthropic_format(session, assistant, "Hello!")
print(f"Formatted for Anthropic: {len(anthropic_messages)} messages")
```

## Next Steps

Congratulations! You've built a complete personal AI assistant with Honcho that automatically handles memory, context, and LLM integration. Here are some ideas to extend it further:

1. **Web Interface**: Build a web UI using Flask/FastAPI - the SDK makes it easy to integrate
2. **Streaming Responses**: Use `peer.chat(..., stream=True)` for real-time conversations
3. **Multi-Modal Support**: Integrate with vision models while leveraging Honcho's memory
4. **Advanced Theory-of-Mind**: Explore peer modeling with `observe_others=False` configurations
5. **Production Deployment**: Scale with workspaces, metadata, and batch operations

## Troubleshooting

### Common Issues

**"No module named 'honcho'"**
- Make sure you installed the package: `pip install honcho-ai`

**API authentication errors**
- Check your `HONCHO_API_KEY` environment variable
- Verify your API key is valid

**Empty context or knowledge queries**
- Ensure you've added messages to peers before querying
- Check that peers are added to sessions before conversation
- Verify session has messages before getting context

**Rate limiting or timeout issues**
- The SDK handles retries automatically
- Consider adding delays between large batch operations

## Resources

- [SDK Reference](/v2/documentation/platform/sdk)
- [API Reference](/v2/api-reference/introduction)
- [More Examples](/v2/guides/overview)
- [Discord Community](http://discord.gg/plasticlabs)
