Build Your First LangChain Application – Part 7: Advanced Features – Memory, Agents, and Tools

Build Your First LangChain Application – Part 7: Advanced Features – Memory, Agents, and Tools

In this part, we’ll implement advanced features including persistent memory, intelligent agents, and custom tools to create sophisticated AI workflows.

Implementing Persistent Memory

// src/services/memoryService.js
import { ConversationSummaryBufferMemory } from "langchain/memory";
import { ChatMessageHistory } from "langchain/stores/message/in_memory";

export class AdvancedMemoryService {
  constructor() {
    this.sessions = new Map();
  }

  createConversationMemory(sessionId, options = {}) {
    const memory = new ConversationSummaryBufferMemory({
      llm: this.summaryLLM,
      maxTokenLimit: 2000,
      returnMessages: true,
      memoryKey: "chat_history",
      chatHistory: new ChatMessageHistory(),
    });

    this.sessions.set(sessionId, {
      memory,
      createdAt: new Date().toISOString(),
      messageCount: 0,
    });

    return memory;
  }

  getMemory(sessionId) {
    const session = this.sessions.get(sessionId);
    if (!session) {
      return this.createConversationMemory(sessionId);
    }
    return session.memory;
  }
}

Building Custom Tools

// src/tools/customTools.js
import { Tool } from "@langchain/core/tools";

export class CalculatorTool extends Tool {
  name = "calculator";
  description = "Useful for performing mathematical calculations.";

  async _call(input) {
    try {
      const result = Function(`"use strict"; return (${input})`)();
      return `The result of ${input} is ${result}`;
    } catch (error) {
      return `Error calculating ${input}: ${error.message}`;
    }
  }
}

export class DocumentSummaryTool extends Tool {
  constructor(documentManager) {
    super();
    this.documentManager = documentManager;
  }

  name = "document_summary";
  description = "Useful for getting summaries of documents in the knowledge base.";

  async _call(input) {
    try {
      const searchResults = await this.documentManager.searchDocuments(input, {
        maxResults: 3,
      });

      if (searchResults.totalResults === 0) {
        return `No documents found matching "${input}"`;
      }

      return `Found ${searchResults.totalResults} relevant documents`;
    } catch (error) {
      return `Error searching documents: ${error.message}`;
    }
  }
}

Creating an Agent

// src/services/agentService.js
import { AgentExecutor, createOpenAIFunctionsAgent } from "langchain/agents";
import { ChatPromptTemplate, MessagesPlaceholder } from "@langchain/core/prompts";
import { CalculatorTool, DocumentSummaryTool } from '../tools/customTools.js';

export class AgentService {
  constructor() {
    this.setupAgent();
  }

  async setupAgent() {
    this.tools = [
      new CalculatorTool(),
      new DocumentSummaryTool(this.documentManager),
    ];

    this.prompt = ChatPromptTemplate.fromMessages([
      ["system", `You are a helpful AI assistant with access to tools:
      - calculator: For mathematical calculations
      - document_summary: For searching documents
      
      Use tools when helpful and explain your reasoning.`],
      new MessagesPlaceholder("chat_history"),
      ["human", "{input}"],
      new MessagesPlaceholder("agent_scratchpad"),
    ]);

    this.agent = await createOpenAIFunctionsAgent({
      llm: llm,
      tools: this.tools,
      prompt: this.prompt,
    });
  }

  async executeAgent(input, sessionId = 'default') {
    try {
      const memory = this.memoryService.getMemory(sessionId);
      
      const agentExecutor = new AgentExecutor({
        agent: this.agent,
        tools: this.tools,
        memory: memory,
        maxIterations: 5,
      });

      const result = await agentExecutor.invoke({ input });

      return {
        response: result.output,
        sessionId,
      };
    } catch (error) {
      throw new Error('Failed to execute agent');
    }
  }
}

Agent API Endpoints

// src/routes/agent.js
import express from 'express';
import { AgentService } from '../services/agentService.js';

const router = express.Router();
const agentService = new AgentService();

router.post('/chat', async (req, res) => {
  try {
    const { message, sessionId = 'default' } = req.body;
    
    if (!message) {
      return res.status(400).json({ error: 'Message is required' });
    }

    const result = await agentService.executeAgent(message, sessionId);
    
    res.json({
      success: true,
      ...result,
    });
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

export default router;

Multi-Agent Coordination

// src/services/multiAgentService.js
export class MultiAgentService {
  constructor() {
    this.agents = new Map();
    this.setupSpecializedAgents();
  }

  async setupSpecializedAgents() {
    this.agents.set('researcher', {
      name: 'Document Researcher',
      tools: ['document_summary'],
      systemPrompt: 'You are a research specialist focused on document analysis.',
    });

    this.agents.set('calculator', {
      name: 'Mathematical Calculator',
      tools: ['calculator'],
      systemPrompt: 'You are a mathematics specialist for calculations.',
    });
  }

  async selectAgent(input) {
    const inputLower = input.toLowerCase();
    
    if (inputLower.includes('calculate') || /\d+/.test(input)) {
      return 'calculator';
    }
    
    if (inputLower.includes('search') || inputLower.includes('find')) {
      return 'researcher';
    }
    
    return 'researcher';
  }
}

Testing Your Agents

# Test calculator
curl -X POST http://localhost:3000/api/agent/chat \
  -H "Content-Type: application/json" \
  -d '{"message": "What is 15 * 7?", "sessionId": "test"}'

# Test document search
curl -X POST http://localhost:3000/api/agent/chat \
  -H "Content-Type: application/json" \
  -d '{"message": "Find information about LangChain", "sessionId": "test"}'

In Part 8, we’ll cover deployment, production considerations, and scaling strategies!

Written by:

191 Posts

View All Posts
Follow Me :
How to whitelist website on AdBlocker?

How to whitelist website on AdBlocker?

  1. 1 Click on the AdBlock Plus icon on the top right corner of your browser
  2. 2 Click on "Enabled on this site" from the AdBlock Plus option
  3. 3 Refresh the page and start browsing the site