feat: Introduce Agentic RAG application with GPT-5 and LanceDB
This commit is contained in:
parent
3478406ea6
commit
cbb10bc472
3 changed files with 366 additions and 0 deletions
153
rag_tutorials/agentic_rag_gpt5/README.md
Normal file
153
rag_tutorials/agentic_rag_gpt5/README.md
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
# 🧠 Agentic RAG with GPT-5
|
||||||
|
|
||||||
|
An agentic RAG application built with the Agno framework, featuring GPT-5 and LanceDB for efficient knowledge retrieval and question answering.
|
||||||
|
|
||||||
|
## ✨ Features
|
||||||
|
|
||||||
|
- **🤖 GPT-5-nano**: Latest OpenAI model for intelligent responses
|
||||||
|
- **🗄️ LanceDB**: Lightweight vector database for fast similarity search
|
||||||
|
- **🔍 Agentic RAG**: Intelligent retrieval augmented generation
|
||||||
|
- **📝 Markdown Formatting**: Beautiful, structured responses
|
||||||
|
- **🌐 Dynamic Knowledge**: Add URLs to expand knowledge base
|
||||||
|
- **⚡ Real-time Streaming**: Watch answers generate live
|
||||||
|
- **🎯 Clean Interface**: Simplified UI without configuration complexity
|
||||||
|
|
||||||
|
## 🚀 Quick Start
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Python 3.11+
|
||||||
|
- OpenAI API key with GPT-5 access
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
1. **Clone and navigate to the project**
|
||||||
|
```bash
|
||||||
|
cd rag_tutorials/agentic_rag_gpt5
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Install dependencies**
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Set up your OpenAI API key**
|
||||||
|
```bash
|
||||||
|
export OPENAI_API_KEY="your-api-key-here"
|
||||||
|
```
|
||||||
|
Or create a `.env` file:
|
||||||
|
```
|
||||||
|
OPENAI_API_KEY=your-api-key-here
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Run the application**
|
||||||
|
```bash
|
||||||
|
streamlit run agentic_rag_gpt5.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 How to Use
|
||||||
|
|
||||||
|
1. **Enter your OpenAI API key** in the sidebar
|
||||||
|
2. **Add knowledge sources** by entering URLs in the sidebar
|
||||||
|
3. **Ask questions** using the text area or suggested prompts
|
||||||
|
4. **Watch answers stream** in real-time with markdown formatting
|
||||||
|
|
||||||
|
### Suggested Questions
|
||||||
|
|
||||||
|
- **"What is Agno?"** - Learn about the Agno framework and agents
|
||||||
|
- **"Teams in Agno"** - Understand how teams work in Agno
|
||||||
|
- **"Build RAG system"** - Get a step-by-step guide to building RAG systems
|
||||||
|
|
||||||
|
## 🏗️ Architecture
|
||||||
|
|
||||||
|
### Core Components
|
||||||
|
|
||||||
|
- **`Agent`**: Orchestrates the entire Q&A process
|
||||||
|
- **`UrlKnowledge`**: Manages document loading from URLs
|
||||||
|
- **`LanceDb`**: Vector database for efficient similarity search
|
||||||
|
- **`OpenAIEmbedder`**: Converts text to embeddings
|
||||||
|
- **`OpenAIChat`**: GPT-5-nano model for generating responses
|
||||||
|
|
||||||
|
### Data Flow
|
||||||
|
|
||||||
|
1. **Knowledge Loading**: URLs are processed and stored in LanceDB
|
||||||
|
2. **Vector Search**: OpenAI embeddings enable semantic search
|
||||||
|
3. **Response Generation**: GPT-5-nano processes information and generates answers
|
||||||
|
4. **Streaming Output**: Real-time display of formatted responses
|
||||||
|
|
||||||
|
## 🔧 Configuration
|
||||||
|
|
||||||
|
### Database Settings
|
||||||
|
- **Vector DB**: LanceDB with local storage
|
||||||
|
- **Table Name**: `agentic_rag_docs`
|
||||||
|
- **Search Type**: Vector similarity search
|
||||||
|
|
||||||
|
## 📚 Knowledge Management
|
||||||
|
|
||||||
|
### Adding Sources
|
||||||
|
- Use the sidebar to add new URLs
|
||||||
|
- Sources are automatically processed and indexed
|
||||||
|
- Current sources are displayed as numbered list
|
||||||
|
|
||||||
|
### Default Knowledge
|
||||||
|
- Starts with Agno documentation: `https://docs.agno.com/introduction/agents.md`
|
||||||
|
- Expandable with any web-based documentation
|
||||||
|
|
||||||
|
## 🎨 UI Features
|
||||||
|
|
||||||
|
### Sidebar
|
||||||
|
- **API Key Management**: Secure input for OpenAI credentials
|
||||||
|
- **URL Addition**: Dynamic knowledge base expansion
|
||||||
|
- **Current Sources**: Numbered list of loaded URLs
|
||||||
|
|
||||||
|
### Main Interface
|
||||||
|
- **Suggested Prompts**: Quick access to common questions
|
||||||
|
- **Query Input**: Large text area for custom questions
|
||||||
|
- **Real-time Streaming**: Live answer generation
|
||||||
|
- **Markdown Rendering**: Beautiful formatted responses
|
||||||
|
|
||||||
|
## 🛠️ Technical Details
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
```
|
||||||
|
streamlit>=1.28.0
|
||||||
|
agno>=0.1.0
|
||||||
|
openai>=1.0.0
|
||||||
|
lancedb>=0.4.0
|
||||||
|
python-dotenv>=1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Features
|
||||||
|
- **Event Filtering**: Only shows `RunResponseContent` events for clean output
|
||||||
|
- **Safe Attribute Access**: Prevents errors from missing attributes
|
||||||
|
- **Caching**: Efficient resource loading with Streamlit caching
|
||||||
|
- **Error Handling**: Graceful handling of API and processing errors
|
||||||
|
|
||||||
|
## 🔍 Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
**ModelProviderError with max_tokens**
|
||||||
|
- ✅ Fixed: Uses `max_completion_tokens` instead of `max_tokens`
|
||||||
|
|
||||||
|
**Tool calls appearing in output**
|
||||||
|
- ✅ Fixed: Filters to only show `RunResponseContent` events
|
||||||
|
|
||||||
|
**Knowledge base not loading**
|
||||||
|
- Check OpenAI API key is valid
|
||||||
|
- Ensure URLs are accessible
|
||||||
|
- Verify internet connection
|
||||||
|
|
||||||
|
### Performance Tips
|
||||||
|
- **Cache Resources**: Knowledge base and agent are cached for efficiency
|
||||||
|
- **Streaming**: Real-time updates without blocking
|
||||||
|
- **LanceDB**: Fast local vector search without external dependencies
|
||||||
|
|
||||||
|
## 🎯 Use Cases
|
||||||
|
|
||||||
|
- **Documentation Q&A**: Ask questions about technical documentation
|
||||||
|
- **Research Assistant**: Get answers from multiple knowledge sources
|
||||||
|
- **Learning Tool**: Interactive exploration of complex topics
|
||||||
|
- **Content Discovery**: Find relevant information across multiple sources
|
||||||
|
|
||||||
|
**Built with ❤️ using Agno, GPT-5, and LanceDB**
|
||||||
208
rag_tutorials/agentic_rag_gpt5/agentic_rag_gpt5.py
Normal file
208
rag_tutorials/agentic_rag_gpt5/agentic_rag_gpt5.py
Normal file
|
|
@ -0,0 +1,208 @@
|
||||||
|
import streamlit as st
|
||||||
|
import os
|
||||||
|
from agno.agent import Agent
|
||||||
|
from agno.embedder.openai import OpenAIEmbedder
|
||||||
|
from agno.knowledge.url import UrlKnowledge
|
||||||
|
from agno.models.openai import OpenAIChat
|
||||||
|
from agno.vectordb.lancedb import LanceDb, SearchType
|
||||||
|
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
|
# Load environment variables
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
# Page configuration
|
||||||
|
st.set_page_config(
|
||||||
|
page_title="Agentic RAG with GPT-5",
|
||||||
|
page_icon="🧠",
|
||||||
|
layout="wide"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Main title and description
|
||||||
|
st.title("🧠 Agentic RAG with GPT-5")
|
||||||
|
st.markdown("""
|
||||||
|
This app demonstrates an intelligent AI agent that:
|
||||||
|
1. **Retrieves** relevant information from knowledge sources using LanceDB
|
||||||
|
2. **Answers** your questions clearly and concisely
|
||||||
|
|
||||||
|
Enter your OpenAI API key in the sidebar to get started!
|
||||||
|
""")
|
||||||
|
|
||||||
|
# Sidebar for API key and settings
|
||||||
|
with st.sidebar:
|
||||||
|
st.header("🔧 Configuration")
|
||||||
|
|
||||||
|
# OpenAI API Key
|
||||||
|
openai_key = st.text_input(
|
||||||
|
"OpenAI API Key",
|
||||||
|
type="password",
|
||||||
|
value=os.getenv("OPENAI_API_KEY", ""),
|
||||||
|
help="Get your key from https://platform.openai.com/"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add URLs to knowledge base
|
||||||
|
st.subheader("🌐 Add Knowledge Sources")
|
||||||
|
new_url = st.text_input(
|
||||||
|
"Add URL",
|
||||||
|
placeholder="https://docs.agno.com/introduction",
|
||||||
|
help="Enter a URL to add to the knowledge base"
|
||||||
|
)
|
||||||
|
|
||||||
|
if st.button("➕ Add URL", type="primary"):
|
||||||
|
if new_url:
|
||||||
|
st.session_state.urls_to_add = new_url
|
||||||
|
st.success(f"URL added to queue: {new_url}")
|
||||||
|
else:
|
||||||
|
st.error("Please enter a URL")
|
||||||
|
|
||||||
|
# Check if API key is provided
|
||||||
|
if openai_key:
|
||||||
|
# Initialize knowledge base (cached to avoid reloading)
|
||||||
|
@st.cache_resource(show_spinner="📚 Loading knowledge base...")
|
||||||
|
def load_knowledge() -> UrlKnowledge:
|
||||||
|
"""Load and initialize the knowledge base with LanceDB"""
|
||||||
|
kb = UrlKnowledge(
|
||||||
|
urls=["https://docs.agno.com/introduction/agents.md"], # Default URL
|
||||||
|
vector_db=LanceDb(
|
||||||
|
uri="tmp/lancedb",
|
||||||
|
table_name="agentic_rag_docs",
|
||||||
|
search_type=SearchType.vector, # Use vector search
|
||||||
|
embedder=OpenAIEmbedder(
|
||||||
|
api_key=openai_key
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
kb.load(recreate=True) # Load documents into LanceDB
|
||||||
|
return kb
|
||||||
|
|
||||||
|
# Initialize agent (cached to avoid reloading)
|
||||||
|
@st.cache_resource(show_spinner="🤖 Loading agent...")
|
||||||
|
def load_agent(_kb: UrlKnowledge) -> Agent:
|
||||||
|
"""Create an agent with reasoning capabilities"""
|
||||||
|
return Agent(
|
||||||
|
model=OpenAIChat(
|
||||||
|
id="gpt-5-nano",
|
||||||
|
api_key=openai_key
|
||||||
|
),
|
||||||
|
knowledge=_kb,
|
||||||
|
search_knowledge=True, # Enable knowledge search
|
||||||
|
instructions=[
|
||||||
|
"Always search your knowledge before answering the question.",
|
||||||
|
"Provide clear, well-structured answers in markdown format.",
|
||||||
|
"Use proper markdown formatting with headers, lists, and emphasis where appropriate.",
|
||||||
|
"Structure your response with clear sections and bullet points when helpful.",
|
||||||
|
],
|
||||||
|
markdown=True, # Enable markdown formatting
|
||||||
|
)
|
||||||
|
|
||||||
|
# Load knowledge and agent
|
||||||
|
knowledge = load_knowledge()
|
||||||
|
agent = load_agent(knowledge)
|
||||||
|
|
||||||
|
# Display current URLs in knowledge base
|
||||||
|
if knowledge.urls:
|
||||||
|
st.sidebar.subheader("📚 Current Knowledge Sources")
|
||||||
|
for i, url in enumerate(knowledge.urls, 1):
|
||||||
|
st.sidebar.markdown(f"{i}. {url}")
|
||||||
|
|
||||||
|
# Handle URL additions
|
||||||
|
if hasattr(st.session_state, 'urls_to_add') and st.session_state.urls_to_add:
|
||||||
|
with st.spinner("📥 Loading new documents..."):
|
||||||
|
knowledge.urls.append(st.session_state.urls_to_add)
|
||||||
|
knowledge.load(
|
||||||
|
recreate=False, # Don't recreate DB
|
||||||
|
upsert=True, # Update existing docs
|
||||||
|
skip_existing=True # Skip already loaded docs
|
||||||
|
)
|
||||||
|
st.success(f"✅ Added: {st.session_state.urls_to_add}")
|
||||||
|
del st.session_state.urls_to_add
|
||||||
|
st.rerun()
|
||||||
|
|
||||||
|
# Main query section
|
||||||
|
st.divider()
|
||||||
|
st.subheader("🤔 Ask a Question")
|
||||||
|
|
||||||
|
# Suggested prompts
|
||||||
|
st.markdown("**Try these prompts:**")
|
||||||
|
col1, col2, col3 = st.columns(3)
|
||||||
|
with col1:
|
||||||
|
if st.button("What is Agno?", use_container_width=True):
|
||||||
|
st.session_state.query = "What is Agno and how do Agents work?"
|
||||||
|
with col2:
|
||||||
|
if st.button("Teams in Agno", use_container_width=True):
|
||||||
|
st.session_state.query = "What are Teams in Agno and how do they work?"
|
||||||
|
with col3:
|
||||||
|
if st.button("Build RAG system", use_container_width=True):
|
||||||
|
st.session_state.query = "Give me a step-by-step guide to building a RAG system."
|
||||||
|
|
||||||
|
# Query input
|
||||||
|
query = st.text_area(
|
||||||
|
"Your question:",
|
||||||
|
value=st.session_state.get("query", "What are AI Agents?"),
|
||||||
|
height=100,
|
||||||
|
help="Ask anything about the loaded knowledge sources"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Run button
|
||||||
|
if st.button("🚀 Get Answer", type="primary"):
|
||||||
|
if query:
|
||||||
|
# Create container for answer
|
||||||
|
st.markdown("### 💡 Answer")
|
||||||
|
answer_container = st.container()
|
||||||
|
answer_placeholder = answer_container.empty()
|
||||||
|
|
||||||
|
# Variables to accumulate content
|
||||||
|
answer_text = ""
|
||||||
|
|
||||||
|
# Stream the agent's response
|
||||||
|
with st.spinner("🔍 Searching and generating answer..."):
|
||||||
|
for chunk in agent.run(
|
||||||
|
query,
|
||||||
|
stream=True, # Enable streaming
|
||||||
|
):
|
||||||
|
# Update answer display - only show content from RunResponseContent events
|
||||||
|
if hasattr(chunk, 'event') and chunk.event == "RunResponseContent":
|
||||||
|
if hasattr(chunk, 'content') and chunk.content and isinstance(chunk.content, str):
|
||||||
|
answer_text += chunk.content
|
||||||
|
answer_placeholder.markdown(
|
||||||
|
answer_text,
|
||||||
|
unsafe_allow_html=True
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
st.error("Please enter a question")
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Show instructions if API key is missing
|
||||||
|
st.info("""
|
||||||
|
👋 **Welcome! To use this app, you need:**
|
||||||
|
|
||||||
|
- **OpenAI API Key** (set it in the sidebar)
|
||||||
|
- Sign up at [platform.openai.com](https://platform.openai.com/)
|
||||||
|
- Generate a new API key
|
||||||
|
|
||||||
|
Once you enter the key, the app will load the knowledge base and agent.
|
||||||
|
""")
|
||||||
|
|
||||||
|
# Footer with explanation
|
||||||
|
st.divider()
|
||||||
|
with st.expander("📖 How This Works"):
|
||||||
|
st.markdown("""
|
||||||
|
**This app uses the Agno framework to create an intelligent Q&A system:**
|
||||||
|
|
||||||
|
1. **Knowledge Loading**: URLs are processed and stored in LanceDB vector database
|
||||||
|
2. **Vector Search**: Uses OpenAI's embeddings for semantic search to find relevant information
|
||||||
|
3. **GPT-5**: OpenAI's GPT-5 model processes the information and generates answers
|
||||||
|
|
||||||
|
**Key Components:**
|
||||||
|
- `UrlKnowledge`: Manages document loading from URLs
|
||||||
|
- `LanceDb`: Vector database for efficient similarity search
|
||||||
|
- `OpenAIEmbedder`: Converts text to embeddings using OpenAI's embedding model
|
||||||
|
|
||||||
|
- `Agent`: Orchestrates everything to answer questions
|
||||||
|
|
||||||
|
**Why LanceDB?**
|
||||||
|
- Lightweight and easy to set up
|
||||||
|
- No external database required
|
||||||
|
- Fast vector search capabilities
|
||||||
|
- Perfect for prototyping and small to medium-scale applications
|
||||||
|
""")
|
||||||
5
rag_tutorials/agentic_rag_gpt5/requirements.txt
Normal file
5
rag_tutorials/agentic_rag_gpt5/requirements.txt
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
streamlit
|
||||||
|
agno
|
||||||
|
openai
|
||||||
|
lancedb
|
||||||
|
python-dotenv
|
||||||
Loading…
Reference in a new issue