Chat history is a crucial component that allows your agents to maintain context across multiple interactions, providing a more natural and coherent conversation experience.

Built-in Chat Histories

LarAgent provides several built-in chat history implementations to suit different needs:

Set in your Agent class by the name:

yourAgent.php
// Stores chat history temporarily in memory (lost after request)
protected $history = 'in_memory';  

// Uses Laravel's session storage
protected $history = 'session';    

// Uses Laravel's cache system
protected $history = 'cache';      

// Stores in files (storage/app/chat-histories)
protected $history = 'file';       

// Stores in JSON files (storage/app/chat-histories)
protected $history = 'json';       

Or use it by class:

yourAgent.php
protected $history = \LarAgent\History\SessionChatHistory::class;

Or use it by override method to add custom logic or configuration:

yourAgent.php
  public function createChatHistory($name)
  {
      return new JsonChatHistory($name, ['folder' => __DIR__.'/json_History']);
  }

Chat History Configuration

You can configure how chat history behaves using these properties in your Agent class:

Reinjecting Instructions

/** @var int - Number of messages after which to reinject the agent's instructions */
protected $reinjectInstructionsPer;

Instructions are always injected at the beginning of the chat history. The $reinjectInstructionsPer property defines when to reinject these instructions to ensure the agent stays on track. By default, it’s set to 0 (disabled).

Reinjecting instructions can be useful for long conversations where the agent might drift from its original purpose or forget important constraints.

Managing Context Window Size

/** @var int - Maximum number of tokens to keep in context window */
protected $contextWindowSize;

After the context window is exceeded, the oldest messages are removed until the context window is satisfied or the limit is reached. This helps manage token usage and ensures the conversation stays within the model’s context limits.

How chat history works

The flow of information in the chat history process works as follows:

  1. User to Agent: The user sends a prompt to the agent.
  2. Agent to Chat History: The agent processes and adds the user’s message to the chat history.
  3. Chat History to Agent: The agent retrieves all relevant messages from the chat history.
  4. Agent to LLM: The agent sends these messages as context to the language model.
  5. LLM to Agent: The language model generates a response based on the provided context.
  6. Agent to Chat History: The agent processes and adds the LLM’s response to the chat history.
  7. Agent to User: The agent displays the last message from the chat history to the user.

Throughout this process, the Context Window Management system:

  • Tracks all messages in the conversation
  • Counts tokens to ensure they stay within model limits
  • Prunes older messages when necessary to maintain the context window size

Extensibility

You can implement custom logic for context window management using events and the chat history instance inside your agent. Or create custom chat history implementations by implementing the ChatHistoryInterface.

Using Chat History

Per-User Chat History

One of the most common use cases is maintaining separate chat histories for different users:

// Create a chat history for a specific user
$response = MyAgent::forUser(auth()->user())->respond('Hello, how can you help me?');

// Later, the same user continues the conversation
$response = MyAgent::forUser(auth()->user())->respond('Can you explain more about that?');

Named Chat Histories

You can also create named chat histories for specific contexts or topics:

// Start a conversation about weather
$response = MyAgent::for('weather_chat')->respond('What's the weather like today?');

// Start a separate conversation about recipes
$response = MyAgent::for('recipe_chat')->respond('How do I make pasta carbonara?');

// Continue the weather conversation
$response = MyAgent::for('weather_chat')->respond('Will it rain tomorrow?');

Accessing and Managing Chat History

LarAgent provides several methods to access and manage chat history:

// Get the current chat history instance
$history = $agent->chatHistory();

// Get all messages in the chat history
$messages = $history->getMessages();

// Get the last message (MessageInterface)
$lastMessage = $history->getLastMessage();

// Count messages in history
$count = $history->count();

// Get the chat history identifier
$identifier = $history->getIdentifier();

// Convert messages to array
$messagesArray = $history->toArray();

// Convert messages to array with metadata
$messagesWithMeta = $history->toArrayWithMeta();

Creating Custom Chat Histories

You can create your own chat history by implementing the ChatHistoryInterface and extending the LarAgent\Core\Abstractions\ChatHistory abstract class.

Check example implementations in src/History

There are two ways to register your custom chat history into an agent. If you use standard constructor only with $name parameter, you can define it by class in $history property or provider configuration:

Agent Class

protected $history = \App\ChatHistories\CustomChatHistory::class;

Provider Configuration (config/laragent.php)

'chat_history' => \App\ChatHistories\CustomChatHistory::class,

If you need any other configuration other than $name, you can override createChatHistory() method:

public function createChatHistory($name)
{
    return new \App\ChatHistories\CustomChatHistory($name, ['folder' => __DIR__.'/history']);
}

Best Practices

Do choose the appropriate chat history implementation based on your needs (persistence, performance, etc.)

Do set a reasonable context window size to balance coherence and token usage

Do use unique identifiers for chat histories to prevent cross-contamination

Don’t store sensitive information in chat histories without proper encryption

Don’t neglect to clear chat histories when they’re no longer needed