Think of them as smart assistants that can chain together multiple steps to accomplish complex goals. Unlike simple chatbots, agents can:
Make decisions about what tools to use
Break down complex tasks into smaller steps
Maintain context throughout a conversation
Validate and verify their own outputs
Understanding the Tech Stack
For this project, we're using several powerful tools. As always, the full script is at the bottom:
LangChain: A framework for building AI applications that can chain together different capabilities. It provides:
Tools for working with Large Language Models (LLMs)
Vector stores for efficient information retrieval
Agent frameworks for complex task execution
Tavily: An AI-optimized search engine that provides:
Relevant and recent web results
Built-in fact checking
Clean, parsed content ready for AI consumption
OpenAI: We'll use their GPT-4 model for:
Natural language understanding
Content generation
Task planning
Getting Started with API Keys
Before we dive in, you'll need three API keys:
Setting Up Our Environment
Before we write any code, we need to prepare our development environment. We'll need several Python packages and a proper virtual environment setup.
$ pip install langchain-community langchain-openai langchain-chroma langchain-core pydantic asyncio
Here we are importing LangChain's ecosystem including tools for search, embeddings, and agent creation, along with Pydantic for data validation.
We then define a simple yet effective SearchResult model that inherits from Pydantic's BaseModel, providing a structured way to handle search results with title, URL, and content fields.
The system's foundation is established with GPT-4 configured at zero temperature for consistent output, alongside Tavily's search tool limited to five results, and OpenAI's embedding model. We then set up our Chroma vector store to manage research results and configure a recursive text splitter with 500-character chunks and 50-character overlap for optimal document processing.
The setup_research_agent function configures our research assistant using LangChain's agent framework. It takes our GPT-4 model and Tavily search tool as inputs, creates a prompt template defining the agent's behavior, and returns an AgentExecutor that manages the interaction between these components.
โ
The setup_research_agent function creates our agent by combining three key components: a system prompt that defines the search and analysis behavior, a ChatPromptTemplate that structures the conversation flow, and an OpenAI functions agent that connects our language model with the Tavily search tool. The function returns an AgentExecutor configured for verbose output to track the agent's decision-making process.
โ
Our search processing is handled by two functions: process_search_results, which asynchronously fetches and formats Tavily search results into our SearchResult model, and update_vectorstore, which prepares these results for vector storage by creating document objects with metadata and splitting them into manageable chunks before adding them to our Chroma database.
The research function ties our system together in a five-step process. It starts by fetching search results for a query, stores them in our vector database, and creates a detailed research prompt. Using LangChain's Conversational Retrieval Chain with our configured retriever, it generates a comprehensive response. Finally, it formats the output with both the answer and source citations from our vector store.
The generate_report function automates comprehensive report creation. It takes a topic and optional focus areas, defaulting to overview, key findings, current trends, and challenges if none are specified. For each area, it triggers a research query and compiles the results. Finally, it uses our agent to create an executive summary of all findings, returning a structured document with the topic, executive summary, and detailed sections.
The main function orchestrates the entire research process by first using setup_research_agent to create an AI agent, then uses process_search_results to gather information from Tavily searches, feeds those results into update_vectorstore to store in the Chroma database, and finally calls generate_report which combines all the stored information to create a complete research document with citations - all running asynchronously for faster execution.
By leveraging asynchronous processing and vector storage, it efficiently transforms a simple research query into a structured report, making it a valuable tool for researchers, analysts, or anyone needing quick, well-sourced information on complex topics.
Here are the results from when I ran it: