Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from praisonaiagents import Agent
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

To provide the agent with web search capabilities as described in the instructions, you need to import the Tools class which contains the internet_search tool.

Suggested change
from praisonaiagents import Agent
from praisonaiagents import Agent, Tools

import os

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Wire an actual web search tool; the referenced internet_search function doesn’t exist.

Instructions tell the model to use internet_search, but no tool is registered. Add a minimal DuckDuckGo tool with defensive imports.

Apply:

+
+def internet_search(query: str) -> str:
+    """
+    Lightweight DuckDuckGo search tool for the Agent.
+    Returns a short bulleted list of top results (title, url, snippet).
+    """
+    try:
+        from duckduckgo_search import DDGS  # pip install duckduckgo-search
+    except Exception as import_err:
+        return f"Search tool unavailable: {import_err}"
+    try:
+        with DDGS(timeout=10) as ddgs:
+            results = list(ddgs.text(query, max_results=5))
+        lines = []
+        for r in results:
+            title = r.get("title") or r.get("h") or "Untitled"
+            url = r.get("href") or r.get("u") or ""
+            body = r.get("body") or r.get("a") or ""
+            lines.append(f"- {title} — {url}\n  {body}")
+        return "\n".join(lines) if lines else "No results found."
+    except Exception as e:
+        return f"Search error: {e}"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Insert near the top of examples/python/tools/exa-tool/rag_examples/agentic_rag/rag_agent.py
def internet_search(query: str) -> str:
"""
Lightweight DuckDuckGo search tool for the Agent.
Returns a short bulleted list of top results (title, url, snippet).
"""
try:
from duckduckgo_search import DDGS # pip install duckduckgo-search
except Exception as import_err:
return f"Search tool unavailable: {import_err}"
try:
with DDGS(timeout=10) as ddgs:
results = list(ddgs.text(query, max_results=5))
lines = []
for r in results:
title = r.get("title") or r.get("h") or "Untitled"
url = r.get("href") or r.get("u") or ""
body = r.get("body") or r.get("a") or ""
lines.append(f"- {title}{url}\n {body}")
return "\n".join(lines) if lines else "No results found."
except Exception as e:
return f"Search error: {e}"
🤖 Prompt for AI Agents
In examples/python/tools/exa-tool/rag_examples/agentic_rag/rag_agent.py around
line 3, the agent references an internet_search tool that doesn't exist; add a
minimal DuckDuckGo web search tool and register it instead. Import requests
defensively (try/except ImportError and raise a clear RuntimeError or fallback
stub), implement a small function that takes a query string, performs a
DuckDuckGo search (HTTP GET to the simple HTML search endpoint or API) with
timeout and error handling, parses results to return a short list or text
summary, and then register this function under the expected tool name (e.g.,
"internet_search" or update instructions to use the new tool name). Ensure
network timeouts, exceptions are caught and meaningful errors returned so the
agent remains robust.

# Set OpenAI API key if not already set
if not os.getenv("OPENAI_API_KEY"):
print("Please set your OpenAI API key: export OPENAI_API_KEY='your-api-key-here'")
exit(1)
Comment on lines +5 to +7
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For better practice in command-line applications, it's recommended to print error messages to standard error (stderr) and use sys.exit() for termination. This separates normal output from error messages. You'll need to import sys at the top of the file.

Suggested change
if not os.getenv("OPENAI_API_KEY"):
print("Please set your OpenAI API key: export OPENAI_API_KEY='your-api-key-here'")
exit(1)
if not os.getenv("OPENAI_API_KEY"):
import sys
print("Please set your OpenAI API key: export OPENAI_API_KEY='your-api-key-here'", file=sys.stderr)
sys.exit(1)

Comment on lines +4 to +7
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Do not exit at import time; move API key check into main and use sys.exit.

Top-level exit breaks imports/tests and is brittle. Validate the key inside the main block and call sys.exit(1).

Apply this diff to remove the top-level check (see a follow-up comment for adding it inside main):

-# Set OpenAI API key if not already set
-if not os.getenv("OPENAI_API_KEY"):
-    print("Please set your OpenAI API key: export OPENAI_API_KEY='your-api-key-here'")
-    exit(1)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Set OpenAI API key if not already set
if not os.getenv("OPENAI_API_KEY"):
print("Please set your OpenAI API key: export OPENAI_API_KEY='your-api-key-here'")
exit(1)
🤖 Prompt for AI Agents
In examples/python/tools/exa-tool/rag_examples/agentic_rag/rag_agent.py around
lines 4 to 7, remove the top-level OPENAI_API_KEY check and exit call so
imports/tests aren't terminated during module import; instead, add the
environment key validation inside the if __name__ == "__main__": main() flow (or
at start of main()), and when the key is missing call sys.exit(1) after printing
the message. Ensure you import sys in the module if not already present.


# Create the RAG agent with web search capabilities
rag_agent = Agent(
instructions="""You are a helpful AI assistant specialized in Thai recipes and cooking.

You have access to a PDF knowledge base about Thai recipes from: https://phi-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf

You can also search the web for additional information about Thai cooking, ingredients, and techniques.
Comment on lines +13 to +15
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

PDF “knowledge base” is only mentioned in the prompt; no retrieval/RAG is wired.

If the goal is Agentic RAG, connect an actual knowledge component (e.g., vector store over ThaiRecipes.pdf) instead of relying solely on instructions. Otherwise, reword the prompt to avoid overstating capabilities.

I can help integrate the library’s knowledge/RAG API once confirmed. To locate the supported API surface in this repo, run:


🏁 Script executed:

#!/bin/bash
# Locate Knowledge APIs and Agent constructor to see how to pass knowledge.
rg -nP -C2 'class\s+Knowledge\b|def\s+(from_pdfs|from_pdf|add_pdf|add_document|add_documents)\b' src
rg -nP -C3 'class\s+Agent\b|def\s+__init__\(' src

Length of output: 55975


🏁 Script executed:

#!/bin/bash
# Locate the Agentic RAG example file
find examples -type f -name 'rag_agent.py'
# Display the first 50 lines to inspect retrieval wiring
sed -n '1,50p' examples/python/tools/exa-tool/rag_examples/agentic_rag/rag_agent.py

Length of output: 1840


Wire actual PDF retrieval or remove PDF reference
The prompt asserts access to a ThaiRecipes.pdf “knowledge base,” but rag_agent.py never instantiates or passes a Knowledge/memory component. Either load the PDF (e.g. via Knowledge.from_pdfs or add_pdf) and pass it into Agent(..., memory=True, memory_config=...), or remove the PDF mention from the instructions to avoid overstating capabilities.

🤖 Prompt for AI Agents
In examples/python/tools/exa-tool/rag_examples/agentic_rag/rag_agent.py around
lines 13 to 15, the prompt claims access to ThaiRecipes.pdf but the file never
instantiates or wires a Knowledge/memory component; either load the PDF into the
agent (e.g., call Knowledge.from_pdfs([...]) or use agent.memory.add_pdf(...)
and create a memory/memory_config object, then pass memory=True and
memory_config=<your_config> (or memory=<memory_instance>) into the Agent
constructor, or remove the PDF reference from the prompt so the instructions
don't claim an unavailable knowledge source.


When answering questions:
1. Use your knowledge about Thai cuisine to provide helpful information
2. If needed, search the web for additional details, current information, or clarification
3. Provide comprehensive, helpful answers about Thai cuisine
4. Always be informative and helpful about Thai cooking!

You can use the internet_search function to search the web when needed.""",
llm="gpt-4o",
markdown=True,
verbose=True
)
Comment on lines +26 to +27
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The agent's instructions on line 23 mention using internet_search, but this tool is not provided to the agent during initialization. You need to pass it in the tools parameter for the agent to be able to perform web searches.

Suggested change
verbose=True
)
verbose=True,
tools=[Tools.internet_search]
)

Comment on lines +10 to +27
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This example is presented as a RAG agent, but it doesn't use the framework's RAG capabilities effectively. The PDF URL is only mentioned in the instructions, which doesn't guarantee the agent can access and retrieve information from it. To make this a true RAG example, you should use the knowledge parameter of the Agent. Since the framework may not support URLs directly, you can download the PDF and provide the local path. This will ensure the agent properly ingests the document into its knowledge base.

Here's a suggestion on how to modify the code to implement this. You would need to add import requests and import sys at the top of the file.

# Download the knowledge base if it doesn't exist
pdf_url = "https://phi-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf"
pdf_path = "ThaiRecipes.pdf"
if not os.path.exists(pdf_path):
    print(f"Downloading knowledge base from {pdf_url}...")
    try:
        response = requests.get(pdf_url, timeout=30)
        response.raise_for_status()
        with open(pdf_path, "wb") as f:
            f.write(response.content)
        print("Download complete.")
    except requests.RequestException as e:
        print(f"Error downloading knowledge base: {e}", file=sys.stderr)
        sys.exit(1)

# Create the RAG agent with web search capabilities
rag_agent = Agent(
    instructions="""You are a helpful AI assistant specialized in Thai recipes and cooking.

    You have access to a PDF knowledge base about Thai recipes.
    
    You can also search the web for additional information about Thai cooking, ingredients, and techniques.
    
    When answering questions:
    1. Use your knowledge about Thai cuisine to provide helpful information
    2. If needed, search the web for additional details, current information, or clarification
    3. Provide comprehensive, helpful answers about Thai cuisine
    4. Always be informative and helpful about Thai cooking!
    
    You can use the internet_search function to search the web when needed.""",
    knowledge=[pdf_path],
    llm="gpt-4o",
    markdown=True,
    verbose=True,
    tools=[Tools.internet_search]
)

Comment on lines +10 to +27
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Register the search tool with the Agent; otherwise the LLM can’t call it.

Apply:

 rag_agent = Agent(
@@
-    llm="gpt-4o",
+    llm="gpt-4o",
+    tools=[internet_search],
     markdown=True,
     verbose=True
 )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
rag_agent = Agent(
instructions="""You are a helpful AI assistant specialized in Thai recipes and cooking.
You have access to a PDF knowledge base about Thai recipes from: https://phi-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf
You can also search the web for additional information about Thai cooking, ingredients, and techniques.
When answering questions:
1. Use your knowledge about Thai cuisine to provide helpful information
2. If needed, search the web for additional details, current information, or clarification
3. Provide comprehensive, helpful answers about Thai cuisine
4. Always be informative and helpful about Thai cooking!
You can use the internet_search function to search the web when needed.""",
llm="gpt-4o",
markdown=True,
verbose=True
)
rag_agent = Agent(
instructions="""You are a helpful AI assistant specialized in Thai recipes and cooking.
You have access to a PDF knowledge base about Thai recipes from: https://phi-public.s3.amazonaws.com/recipes/ThaiRecipes.pdf
You can also search the web for additional information about Thai cooking, ingredients, and techniques.
When answering questions:
1. Use your knowledge about Thai cuisine to provide helpful information
2. If needed, search the web for additional details, current information, or clarification
3. Provide comprehensive, helpful answers about Thai cuisine
4. Always be informative and helpful about Thai cooking!
You can use the internet_search function to search the web when needed.""",
llm="gpt-4o",
tools=[internet_search],
markdown=True,
verbose=True
)


if __name__ == "__main__":
print("🤖 Thai Recipe RAG Agent is ready!")
print("Ask me anything about Thai recipes or cooking!")
print("Type 'quit' to exit.\n")

Comment on lines +29 to +33
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Validate OPENAI_API_KEY inside main and fix the exit message list.

Apply:

 if __name__ == "__main__":
-    print("🤖 Thai Recipe RAG Agent is ready!")
-    print("Ask me anything about Thai recipes or cooking!")
-    print("Type 'quit' to exit.\n")
+    # Validate key at runtime (avoid exiting on import)
+    if not os.getenv("OPENAI_API_KEY"):
+        print("Please set your OpenAI API key first, e.g.:")
+        print("  export OPENAI_API_KEY='your-api-key-here'")
+        sys.exit(1)
+    print("🤖 Thai Recipe RAG Agent is ready!")
+    print("Ask me anything about Thai recipes or cooking!")
+    print("Type 'quit', 'exit', or 'bye' to exit.\n")
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if __name__ == "__main__":
print("🤖 Thai Recipe RAG Agent is ready!")
print("Ask me anything about Thai recipes or cooking!")
print("Type 'quit' to exit.\n")
if __name__ == "__main__":
# Validate key at runtime (avoid exiting on import)
if not os.getenv("OPENAI_API_KEY"):
print("Please set your OpenAI API key first, e.g.:")
print(" export OPENAI_API_KEY='your-api-key-here'")
sys.exit(1)
print("🤖 Thai Recipe RAG Agent is ready!")
print("Ask me anything about Thai recipes or cooking!")
print("Type 'quit', 'exit', or 'bye' to exit.\n")
🤖 Prompt for AI Agents
In examples/python/tools/exa-tool/rag_examples/agentic_rag/rag_agent.py around
lines 29-33, add a runtime validation inside the main block to check that the
OPENAI_API_KEY environment variable is present and non-empty, and if missing
print a clear error and exit with a non-zero status; also replace the single
exit-message print with a corrected exit command list (e.g., show both "quit"
and "exit" or print a list of accepted exit keywords) or build the message from
that list so users know all valid ways to quit.

while True:
user_input = input("You: ")
if user_input.lower() in ['quit', 'exit', 'bye']:
print("👋 Goodbye! Happy cooking!")
break

try:
response = rag_agent.start(user_input)
print(f"\n🤖 Assistant: {response}\n")
Comment on lines +41 to +42
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The rag_agent.start() method can return None if an error occurs during generation. The current code would print "Assistant: None". It's better to handle this case explicitly for a more user-friendly experience.

Suggested change
response = rag_agent.start(user_input)
print(f"\n🤖 Assistant: {response}\n")
response = rag_agent.start(user_input)
if response:
print(f"\n🤖 Assistant: {response}\n")
else:
print("\n🤖 Assistant: I could not generate a response.\n")

except Exception as e:
print(f"❌ Error: {e}\n")
154 changes: 154 additions & 0 deletions examples/python/tools/exa-tool/rag_examples/agentic_rag_gpt5/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# 🧠 Agentic RAG with GPT-5

An agentic RAG application built with the PraisonAI Agents framework, featuring GPT-5 and built-in vector search for efficient knowledge retrieval and question answering.

## ✨ Features

- **🤖 GPT-5**: Latest OpenAI model for intelligent responses
- **🗄️ Built-in Vector Search**: ChromaDB integration 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 Responses**: Fast answer generation- **🎯 Clean Interface**: Simplified UI without configuration complexity
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix merged list items (“Real-time Responses” + “Clean Interface”).

The two bullets are concatenated, breaking formatting.

Apply:

-- **⚡ Real-time Responses**: Fast answer generation- **🎯 Clean Interface**: Simplified UI without configuration complexity
+- **⚡ Real-time Responses**: Fast answer generation
+- **🎯 Clean Interface**: Simplified UI without configuration complexity
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- **⚡ Real-time Responses**: Fast answer generation- **🎯 Clean Interface**: Simplified UI without configuration complexity
- **⚡ Real-time Responses**: Fast answer generation
- **🎯 Clean Interface**: Simplified UI without configuration complexity
🧰 Tools
🪛 LanguageTool

[grammar] ~12-~12: There might be a mistake here.
Context: ...time Responses**: Fast answer generation- 🎯 Clean Interface: Simplified UI wit...

(QB_NEW_EN)


[grammar] ~12-~12: There might be a mistake here.
Context: ...fied UI without configuration complexity ## 🚀 Quick Start ### Prerequisites - Pyt...

(QB_NEW_EN)

🤖 Prompt for AI Agents
In examples/python/tools/exa-tool/rag_examples/agentic_rag_gpt5/README.md around
line 12, the two bullet items "Real-time Responses" and "Clean Interface" have
been concatenated on a single line; split them into two separate list items by
inserting a line break and starting each item on its own line using the same
list marker and formatting (e.g., "- **⚡ Real-time Responses**: Fast answer
generation" and "- **🎯 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_examples/agentic_rag_gpt5
```
Comment on lines +25 to +26
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Correct the cd path to match the repo structure.

The file lives under examples/python/tools/exa-tool/rag_examples/agentic_rag_gpt5.

-   cd rag_examples/agentic_rag_gpt5
+   cd examples/python/tools/exa-tool/rag_examples/agentic_rag_gpt5

You can confirm with:


🏁 Script executed:

#!/bin/bash
fd -a agentic_rag_gpt5.py -t f

Length of output: 132


Update cd path to the correct directory
Replace the cd command to include the full relative path.

-   cd rag_examples/agentic_rag_gpt5
+   cd examples/python/tools/exa-tool/rag_examples/agentic_rag_gpt5
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
cd rag_examples/agentic_rag_gpt5
```
cd examples/python/tools/exa-tool/rag_examples/agentic_rag_gpt5
🤖 Prompt for AI Agents
In examples/python/tools/exa-tool/rag_examples/agentic_rag_gpt5/README.md around
lines 25-26, the README uses a shortened cd command ("cd
rag_examples/agentic_rag_gpt5"); update it to the full relative path so readers
run "cd examples/python/tools/exa-tool/rag_examples/agentic_rag_gpt5" instead,
replacing the existing cd line with the corrected path.


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. **Get answers** with markdown formatting

### Suggested Questions

- **"What is PraisonAI?"** - Learn about the PraisonAI Agents framework
- **"Teams in PraisonAI"** - Understand how teams work in PraisonAI
- **"Build RAG system"** - Get a step-by-step guide to building RAG systems

## 🏗️ Architecture

### Core Components

- **`Agent`**: PraisonAI Agents framework for intelligent Q&A
- **`knowledge`**: Built-in knowledge base that handles URLs and documents
- **`llm`**: OpenAI GPT-5-nano for generating responses
- **Built-in Vector Search**: Automatic similarity search without external setup

### Data Flow

1. **Knowledge Loading**: URLs are processed and stored in the built-in vector database
2. **Vector Search**: OpenAI embeddings enable semantic search
3. **Response Generation**: GPT-5-nano processes information and generates answers
4. **Formatted Output**: Markdown-formatted responses

## 🔧 Configuration

### Database Settings
- **Vector DB**: Built-in vector database with automatic indexing
- **Storage**: Local storage managed by PraisonAI Agents
- **Search**: Automatic similarity search

### Model Configuration
- **LLM**: OpenAI GPT-5-nano
- **Embeddings**: Automatic handling by PraisonAI Agents
- **Vector Store**: Built-in with automatic document processing

## 📚 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 PraisonAI documentation: `https://docs.praisonai.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
- **Fast Responses**: Quick answer generation
- **Markdown Rendering**: Beautiful formatted responses

## 🛠️ Technical Details

### Dependencies
```
streamlit>=1.28.0
praisonaiagents>=0.1.0
openai>=1.0.0
python-dotenv>=1.0.0
```

### Key Features
- **Built-in Knowledge Base**: Automatic document processing and indexing
- **Vector Search**: Efficient similarity search with built-in database
- **Caching**: Efficient resource loading with Streamlit caching
- **Error Handling**: Graceful handling of API and processing errors

## 🔍 Troubleshooting

### Common Issues

**Knowledge base not loading**
- Check OpenAI API key is valid
- Ensure URLs are accessible
- Verify internet connection

**Agent initialization errors**
- Check if PraisonAI Agents is properly installed
- Verify OpenAI API key has sufficient credits
- Ensure Python version is 3.11+

### Performance Tips
- **Cache Resources**: Knowledge base and agent are cached for efficiency
- **Built-in Vector Search**: Fast similarity search without external setup
- **Local Storage**: Optimized local storage for optimal performance

## 🎯 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 PraisonAI Agents and GPT-5**
Loading
Loading