Building AI Agents with LangChain and Vector Databases

By Charles LAZIOSI
Published on

The landscape of AI applications has shifted dramatically with the emergence of autonomous agents capable of reasoning, planning, and executing complex tasks. LangChain, combined with vector databases, enables developers to build intelligent systems that can interact with external tools and maintain long-term memory.

What Are AI Agents?

Unlike simple chatbots that respond to queries, AI agents can break down complex problems, make decisions, use tools, and remember context across sessions. They're transforming industries from customer service to data analysis.

Building Your First Agent

Let's create an agent that can search the web and perform calculations:

from langchain.agents import initialize_agent, Tool, AgentType
from langchain.llms import OpenAI
from langchain.utilities import SerpAPIWrapper
from langchain.chains import LLMMathChain

# Initialize the LLM
llm = OpenAI(temperature=0)

# Create tools
search = SerpAPIWrapper()
math_chain = LLMMathChain.from_llm(llm=llm)

tools = [
    Tool(
        name="Search",
        func=search.run,
        description="Useful for finding current information on the internet"
    ),
    Tool(
        name="Calculator",
        func=math_chain.run,
        description="Useful for mathematical calculations"
    )
]

# Initialize the agent
agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION,
    verbose=True
)

# Run a complex query
result = agent.run(
    "What's the population of Tokyo multiplied by the current USD to JPY exchange rate?"
)
print(result)

Adding Memory with Vector Databases

Vector databases enable agents to remember and retrieve relevant information from vast datasets. Here's how to integrate Pinecone for semantic search:

from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Pinecone
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
import pinecone

# Initialize Pinecone
pinecone.init(api_key="your-api-key", environment="your-env")
index_name = "knowledge-base"

# Load and process documents
loader = TextLoader("company_docs.txt")
documents = loader.load()

text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
docs = text_splitter.split_documents(documents)

# Create embeddings and store in Pinecone
embeddings = OpenAIEmbeddings()
vectorstore = Pinecone.from_documents(
    docs, 
    embeddings, 
    index_name=index_name
)

# Query the vector database
query = "What is our refund policy?"
similar_docs = vectorstore.similarity_search(query, k=3)

for doc in similar_docs:
    print(f"Content: {doc.page_content}\n")

Creating a Conversational Agent with Memory

Let's build an agent that maintains conversation history and can access a knowledge base:

from langchain.agents import AgentExecutor, create_openai_tools_agent
from langchain.memory import ConversationBufferMemory
from langchain.prompts import MessagesPlaceholder
from langchain_openai import ChatOpenAI
from langchain.tools.retriever import create_retriever_tool

# Initialize memory
memory = ConversationBufferMemory(
    memory_key="chat_history",
    return_messages=True
)

# Create a retriever tool from your vector database
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
retriever_tool = create_retriever_tool(
    retriever,
    "knowledge_base",
    "Searches the company knowledge base for relevant information"
)

# Set up the agent with memory
llm = ChatOpenAI(model="gpt-4", temperature=0)

tools = [retriever_tool, search, math_chain]

# Create the agent
from langchain.prompts import ChatPromptTemplate

prompt = ChatPromptTemplate.from_messages([
    ("system", "You are a helpful AI assistant with access to tools."),
    MessagesPlaceholder(variable_name="chat_history"),
    ("human", "{input}"),
    MessagesPlaceholder(variable_name="agent_scratchpad")
])

agent = create_openai_tools_agent(llm, tools, prompt)
agent_executor = AgentExecutor(
    agent=agent,
    tools=tools,
    memory=memory,
    verbose=True
)

# Have a conversation
response1 = agent_executor.invoke({"input": "What products do we offer?"})
print(response1["output"])

response2 = agent_executor.invoke({"input": "What's the most expensive one?"})
print(response2["output"])

Advanced Pattern: Multi-Agent Systems

For complex workflows, you can orchestrate multiple specialized agents:

from langchain.agents import Agent

class ResearchAgent:
    def __init__(self):
        self.tools = [search_tool, retriever_tool]
        self.agent = initialize_agent(self.tools, llm, 
                                     agent=AgentType.OPENAI_FUNCTIONS)
    
    def research(self, topic):
        return self.agent.run(f"Research {topic} and summarize key findings")

class WriterAgent:
    def __init__(self):
        self.llm = ChatOpenAI(temperature=0.7)
    
    def write(self, research_data):
        prompt = f"Write an article based on: {research_data}"
        return self.llm.predict(prompt)

# Orchestrate the agents
research_agent = ResearchAgent()
writer_agent = WriterAgent()

topic = "quantum computing breakthroughs in 2024"
research = research_agent.research(topic)
article = writer_agent.write(research)

print(article)

The Future is Autonomous

AI agents represent a paradigm shift from reactive to proactive AI systems. With tools like LangChain and vector databases, developers can build applications that understand context, learn from interactions, and execute multi-step tasks autonomously. The possibilities range from intelligent research assistants to automated business process handlers.