Skip to content

The Language of Agents Decoding Messages in LangChain & LangGraph

Ever wondered how apps get AI to chat, follow instructions, or even use tools? A lot of the magic comes down to "messages." Think of them as the notes passed between you, the AI, and any other services involved. LangChain and LangGraph are awesome tools that help manage these messages, making it easier to build cool AI-powered stuff. Let's break down how it works, keeping it simple!

The Main Players: Core Message Types

LangChain uses a few key message types to keep conversations organized. These are the building blocks for almost any chat interaction.

SystemMessage: Setting the Scene

This message sets the stage. It tells the AI how to behave – its personality, its job, or any ground rules. Think of it as whispering to the AI, "You're a super helpful assistant who loves pirate jokes." You usually send this one first. LangChain figures out how to pass this instruction to different AI models, even if they have their own quirks for system prompts.

HumanMessage: What You Say

Simple enough – this is your input. When you ask a question or give a command, LangChain wraps it up as a HumanMessage. It can be plain text or even include images if the AI supports it. If you just send a string to a chat model, LangChain often handily turns it into a HumanMessage for you.

AIMessage: The AI's Response

This is what the AI says back. It's not just text, though! An AIMessage can also include requests for the AI to use "tools" (like searching the web or running some code) and other useful bits like how many tokens it used. If the AI is streaming its response, you'll see AIMessageChunks that build up the full reply.

ToolMessage: Reporting Back from a Mission

If the AI (via an AIMessage) asks to use a tool, your app will run that tool and then send the results back using a ToolMessage. This message needs a special tool_call_id to link it to the AI's original request, which is super important if the AI wants to use multiple tools at once. This is the modern way, an upgrade from the older FunctionMessage.

Going Off-Script: ChatMessage and Custom Roles

What if you need a role that's not "system," "user," "assistant," or "tool"? LangChain offers ChatMessage for that. It lets you set any role label you want.

But here's the catch: most big AI models (like OpenAI's GPTs) only understand the standard roles. If you send a ChatMessage with a role like "developer_instructions," they'll likely ignore it or throw an error. So, only use ChatMessage with custom roles if you know your specific AI model supports them. For example, some Ollama models use a "control" role for special commands, and ChatMessage is how you'd send that.

Who Said That? The name Attribute

In a busy chat with multiple users or AI agents, how do you know who said what? All LangChain message classes (HumanMessage, AIMessage, etc.) have an optional name attribute. Its job is to distinguish between different speakers who might share the same role – for instance, to tell "Alice's" HumanMessage from "Bob's."

Provider support for this name field varies. OpenAI’s Chat API (and therefore Azure OpenAI) allows you to set a name on user or assistant messages, so the model can keep track of different participants. However, many other models might ignore or drop the name; LangChain will usually just omit it when sending the request to such models.

In multi-agent setups with LangGraph, this name field is super handy for tagging which agent sent a message, like AIMessage(content="Here’s what I found.", name="ResearchBot"). Even if the underlying AI model doesn't use the name, it's still useful metadata for your application's logic.

Team Chat: Messages in LangGraph Multi-Agent Systems

LangGraph helps you build apps where multiple AI agents work together. Their coordination hinges on a shared message history, typically managed within a component like MessagesState. This acts as a central ledger of the conversation.

Think of it like a meticulously recorded group project chat where everyone sees all messages in the order they were sent. When it's an agent's turn to contribute:

  1. Reads the History: It first accesses the entire current chat history from MessagesState. This gives it full context of everything that has transpired across all participating agents.

  2. Performs its Task: The agent then does its designated job, which might involve thinking, calling an LLM, or using a tool.

  3. Writes Back: Finally, it appends its own messages (e.g., an AIMessage detailing its findings or actions) to the shared MessagesState, thus adding to the ongoing conversation.

This cycle ensures that if Agent A contributes, and then Agent B takes over, Agent B has visibility into the initial request and Agent A's input. This shared, incrementally built history is fundamental.

Maintaining Order and Clarity in Shared History:

For this system to work without confusion, two things are crucial: messages must be in the correct order, and it must be clear who (or what) sent each message.

  • Chronological Order: MessagesState inherently maintains messages in the order they are added. Each new message is appended, preserving a chronological flow. Furthermore, LangGraph's graph structure itself dictates the sequence of which agent or tool operates next. This controlled execution ensures that contributions are added to the history in a predictable and understandable order.

  • Role and Sender Identification: Knowing "who said what" is vital. While the next section, "Tagging Agents in the Flow," dives deeper into specific techniques like the name attribute and agent-specific SystemMessages, the core idea is that each message carries information about its origin and purpose. The message type itself (e.g., HumanMessage, AIMessage, ToolMessage) provides an initial layer of role definition.

LangGraph leverages this ordered and attributed message history to enable complex interactions. While you can design custom mechanisms to pass specific pieces of information between agents directly, the default and foundational approach is this transparent, shared history that all agents can access and contribute to sequentially.

Tagging Agents in the Flow:

How do you know which agent said what in this shared history?

  • name attribute: As mentioned, AIMessage(content="...", name="FlightBot").

  • System Prompts: Give each agent its own SystemMessage like, "You are HotelBot, specializing in booking accommodations."

  • LangGraph State: You can even add a field to your graph's state to track the last_active_agent.

The safest bet is often to give each agent a clear system instruction about its identity and also log which agent produced each message.

Quick Tips for Message Mastery

  • Order Matters (Usually): A common pattern is SystemMessage first (if you need one), then a HumanMessage from the user, followed by an AIMessage from the model, and then back and forth between Human and AI messages. If tools are involved, ToolMessages follow the AIMessage that requested the tool.

  • Full Context is King: Unless you're specifically managing memory (like trimming old messages), feed the AI the whole accumulated list of messages each time. This gives it the best context. In LangGraph, MessagesState often handles this by injecting the up-to-date history into each agent node.

  • LangChain Simplifies: If you pass a plain string to a chat model, LangChain usually wraps it in a HumanMessage for you.

  • Let LangChain Do the Heavy Lifting: Write your code with LangChain's standard messages. It'll handle the translation to whatever format the specific AI model needs. This makes your code cleaner and easier to switch between different AIs.

  • Mind the Memory: Long chat histories can get too big for an AI's context window (and cost more!). LangGraph and LangChain offer ways to trim or summarize old messages to keep things manageable.

Wrapping Up

Messages are the lifeblood of your LangChain and LangGraph applications. Understanding these basic types, how the name field helps with identity, and how messages flow in multi-agent systems will help you build more powerful and reliable AI tools. Stick to the standards when you can, use custom options wisely, and let LangChain handle the provider-specific details. By following these conventions, you'll ensure clear message sequences and effective agent collaboration. Happy building!