Skip to main content
Integrate Honcho with LangGraph to build a conversational AI agent that maintains memory across sessions. This guide shows you how to use Honcho’s memory layer with LangGraph’s orchestration.
The full code is available on GitHub with examples in both Python and TypeScript

What We’re Building

We’ll create a conversational agent that remembers and reasons over past exchanges with the user. Here’s how the pieces fit together:
  • LangGraph orchestrates the conversation flow
  • Honcho stores messages and retrieves relevant context
  • Your LLM generates responses using Honcho’s formatted context
The key benefit: You don’t manually manage conversation history, token limits, or message formatting. Honcho handles memory so you can focus on your agent’s logic.
This tutorial demonstrates a simple linear conversation flow to show how Honcho integrates with LangGraph. For production applications, you’ll likely want to add LangGraph features like conditional routing, tool calling, and multi-agent orchestration.

Setup

Install required packages:
uv add honcho-ai langgraph langchain-core openai python-dotenv
This tutorial uses OpenAI, but Honcho works with any LLM provider. Create a .env file with your API keys:
OPENAI_API_KEY=your_openai_key
This tutorial uses the Honcho demo server at https://demo.honcho.dev which runs a small instance of Honcho on the latest version. For production, get your Honcho API key at app.honcho.dev. For local development, use environment="local".

Initialize Clients

import os
from dotenv import load_dotenv
from typing_extensions import TypedDict
from honcho import Honcho, Peer, Session
from openai import OpenAI
from langgraph.graph import StateGraph, START, END

load_dotenv()

# Initialize Honcho
honcho = Honcho()

# Initialize OpenAI
llm = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))

Define LangGraph State

Define your state schema to pass data through the graph. The state stores Honcho objects directly along with the current user message and assistant response.
Before proceeding, it’s important to understand Honcho’s core concepts (Peers and Sessions). Review the Honcho Architecture to familiarize yourself with these primitives.
class State(TypedDict):
    user_message: str
    assistant_response: str
    user: Peer
    assistant: Peer
    session: Session

Build the LangGraph

Define your chatbot logic, using Honcho to retrieve conversation context. This function demonstrates how Honcho can store messages, retrieve context, and generate responses.
def chatbot(state: State):
    user_message = state["user_message"]

    # Get objects from state
    user = state["user"]
    assistant = state["assistant"]
    session = state["session"]

    # Step 1: Store the user's message in the session
    # This adds it to Honcho's memory for future context retrieval
    session.add_messages([user.message(user_message)])

    # Step 2: Get context in OpenAI format with token limit
    # get_context() retrieves relevant conversation history
    # tokens=2000 limits the context to 2000 tokens to manage costs and fit within model limits
    # to_openai() converts it to the format expected by OpenAI's API
    messages = session.get_context(tokens=2000).to_openai(assistant=assistant)

    # Step 3: Generate response using the context
    response = llm.chat.completions.create(
        model="gpt-5.1",
        messages=messages
    )
    assistant_response = response.choices[0].message.content

    # Step 4: Store assistant response in Honcho for future context
    session.add_messages([assistant.message(assistant_response)])

    return {"assistant_response": assistant_response}
Now let’s build the LangGraph:
graph = StateGraph(State) \
    .add_node("chatbot", chatbot) \
    .add_edge(START, "chatbot") \
    .add_edge("chatbot", END) \
    .compile()

Understanding get_context()

The get_context() method retrieves comprehensive conversation context and formats it for your LLM. It automatically:
  • Manages conversation history - Tracks all messages and determines what’s relevant
  • Respects token limits - Stays within context window constraints without manual counting
  • Handles long conversations - Combines recent detailed messages with summaries of older exchanges
  • Provides peer understanding - Includes theory-of-mind representations and peer cards when requested
The SessionContext object always includes fields for messages, summaries, peer representations, and peer cards. By default, only messages and summary are populated. To populate peer-specific context, pass a peer_target parameter: Using peer_target for Context:
  • Without peer_perspective: Returns Honcho’s omniscient view of peer_target (all observations and context)
  • With peer_perspective: Returns what peer_perspective knows about peer_target (perspective-based observations and context)
That’s it. Call session.get_context().to_openai(assistant) and you get properly formatted context tailored for your assistant.
Adding System Prompts: Since get_context() returns conversation messages, you can easily prepend custom system instructions. Just add your system prompt to the beginning of the messages array before sending it to your LLM: [{"role": "system", "content": "..."}, ...context_messages].
For more details on all available parameters, see get_context() documentation

Chat Loop

Now we’ll create the main conversation function. To simplify logic, we initialize Honcho objects once per conversation and pass them through the LangGraph state. The run_conversation_turn function initializes a Honcho Session and Peer objects, passes them to the LangGraph, and returns the assistant’s response. By calling it repeatedly with the same user_id and in the same session, the chat builds context over time.
Production Usage: Honcho accepts any nanoid-compatible string for user_id and session_id. You can use IDs directly from your authentication system (Auth0, Firebase, Clerk, etc.) and session management without modification.This tutorial uses hardcoded values for simplicity.
def run_conversation_turn(user_id: str, user_input: str, session_id: str | None = None):
    if not session_id:
        session_id = f"session_{user_id}"

    # Initialize Honcho objects
    user = honcho.peer(user_id)
    assistant = honcho.peer("assistant")
    session = honcho.session(session_id)

    result = graph.invoke({
        "user_message": user_input,
        "user": user,
        "assistant": assistant,
        "session": session
    })

    return result["assistant_response"]

if __name__ == "__main__":
  print("Welcome to the AI Assistant! How can I help you today?")
  user_id = "test-user-123"
  while True:
      user_input = input("You: ")
      if user_input.lower() in ['quit', 'exit']:
          break
      response = run_conversation_turn(user_id, user_input)
      print(f"Assistant: {response}\n")

Next Steps

Now that you have a working LangGraph integration with Honcho, you can:
  • Create custom LangChain tools for your agent - to fully utilize Honcho’s memory & context management features
  • Build a multi-agent LangGraph where each agent is a Honcho Peer with its own memory