This repository contains a collection of Python scripts and Jupyter Notebook examples demonstrating advanced techniques for building applications with Large Language Models (LLMs) using the LangChain framework and Google's Gemini models. LangChain & Google Gemini: Advanced LLM Techniques This repository contains a collection of Python scripts and Jupyter Notebook examples demonstrating advanced techniques for building applications with Large Language Models (LLMs) using the LangChain framework and Google's Gemini models.
📜 Overview This project explores several key patterns in LLM application development, from simple conversational bots with memory to complex, multi-agent systems capable of reasoning, using tools, and answering questions from documents.
✨ Features Conversational Memory: Building chatbots that can remember previous interactions.
Retrieval-Augmented Generation (RAG): Querying and extracting information from your own documents (PDFs).
Vector Stores: Using FAISS for efficient similarity searches on document embeddings.
Query Analysis & Rewriting: Improving retrieval accuracy by refining user questions.
LLM-based Evaluation: Assessing the quality of RAG system responses.
AI Agents & Tools: Creating agents that can use tools like a calculator or a web search.
Advanced Routing: Building a multi-agent system that intelligently routes user queries to the most appropriate agent (e.g., a conversational agent, a document agent, or a tool-using agent).
🚀 Getting Started Follow these steps to set up and run the examples.
- Prerequisites Python 3.8 or higher.
A Google API Key for using the Gemini models. You can get one from Google AI Studio.
- Installation Clone the repository:
git clone cd
Install the required Python packages:
pip install langchain langchain-google-genai google-generativeai pypdf faiss-cpu sentence-transformers
- Environment Setup Set your Google API key as an environment variable. This is the most secure way to handle your API keys.
On macOS/Linux:
export GOOGLE_API_KEY="YOUR_API_KEY"
On Windows:
set GOOGLE_API_KEY="YOUR_API_KEY"
Alternatively, you can pass the key directly when initializing the LLM, but this is not recommended for production code.
⚙️ Code Examples Breakdown The code is divided into several key examples demonstrating different functionalities.
- Basic Chatbot with Memory This example shows how to create a simple chatbot that remembers the context of a conversation using ConversationBufferMemory.
from langchain.memory import ConversationBufferMemory from langchain.chains import LLMChain from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain_google_genai import ChatGoogleGenerativeAI
llm = ChatGoogleGenerativeAI(model="gemini-pro") # Or another Gemini model
chat_prompt = ChatPromptTemplate.from_messages([ ("system", "You are a helpful assistant who replies concisely."), MessagesPlaceholder(variable_name="history"), # This is where memory will be injected ("human", "{input}") ])
memory = ConversationBufferMemory(memory_key="history", return_messages=True)
chat_chain = LLMChain( llm=llm, prompt=chat_prompt, memory=memory, verbose=True # Set to True to see the full prompt being sent to the LLM )
print(chat_chain.run(input="Hello! My name is Talha Shaikh, the vibe coder.")) print(chat_chain.run(input="What is my name?"))
- Retrieval-Augmented Generation (RAG) from a PDF This example demonstrates how to build a system that can answer questions based on the content of a PDF file.
Note: Place a PDF file named SurroundedbyIdiots.pdf in the root directory or update the file path.
from langchain_community.document_loaders import PyPDFLoader from langchain.text_splitter import CharacterTextSplitter from langchain.vectorstores import FAISS from langchain.embeddings import HuggingFaceEmbeddings from langchain.chains import RetrievalQA
loader = PyPDFLoader("SurroundedbyIdiots.pdf") docs = loader.load() splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=100) split_docs = splitter.split_documents(docs)
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2") vectorstore = FAISS.from_documents(split_docs, embeddings)
retriever = vectorstore.as_retriever()
llm = ChatGoogleGenerativeAI(model="gemini-pro")
qa_chain = RetrievalQA.from_chain_type( llm=llm, retriever=retriever, return_source_documents=True )
query = "Summarize the key points about personality types." result = qa_chain({"query": query})
print("Answer:", result["result"]) print("\nSources:", [doc.metadata["source"] for doc in result["source_documents"]])
- Agent with Tools This example creates an agent that can use external tools, like a calculator, to answer questions it cannot solve on its own.
from langchain.agents import Tool, initialize_agent, AgentType from langchain_google_genai import ChatGoogleGenerativeAI
llm = ChatGoogleGenerativeAI(model="gemini-pro")
def calculator_tool(query: str): try: return str(eval(query)) except Exception as e: return f"Error: {e}"
tools = [ Tool( name="Calculator", func=calculator_tool, description="Performs basic arithmetic calculations. Use this for any math questions." ) ]
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True) agent = initialize_agent( tools, llm, agent=AgentType.CONVERSATIONAL_REACT_DESCRIPTION, memory=memory, verbose=True )
response = agent.run("What is 25 * 7?") print("Answer:", response)
- Multi-Agent Router This is the most advanced example. It uses a router to decide which specialized agent should handle a given query. This allows the system to handle conversational chit-chat, document-based questions, and tool-based queries effectively.
import re
def multi_agent_router(query): query_lower = query.lower()
# Route 1: If it's a math question, use the tool agent if re.search(r"\d+[\+\-\*\/]\d+", query): print("--- Routing to API/Tool Agent ---") return api_agent.run(query) # Route 2: If it mentions a document, use the RAG agent elif any(word in query_lower for x in ["pdf", "document", "book", "chapter"]): print("--- Routing to Document Retrieval Agent ---") result_dict = retrieval_agent({"query": query}) return result_dict["result"] # Route 3: Default to the conversational agent else: print("--- Routing to Conversational Agent ---") return conversational_chain.run(input=query, style="Elaborate", wording="friendly") queries = [ "Summarize key points from the PDF about red personalities.", "What is 125 * 8?", "Hello! Who are you today?", ]
for q in queries: print("\n[User Query]:", q) response = multi_agent_router(q) print("[Final Response]:", response)
Happy coding!