RAG + Web Search Agent β AutoGen Γ Saf3AI
A production-ready AI research agent powered by Microsoft AutoGen 0.4.x, secured and observed by the Saf3AI SDK.
Combines a local RAG knowledge base with live web search β available as a Gradio web UI or a terminal CLI.
What It Does
Send any question in the chat. The agent will:
- Search the internal knowledge base (ChromaDB + local embeddings) for relevant context
- Fall back to live web search (DuckDuckGo) if the KB has nothing useful
- Answer with cited sources β knowledge base file name or web URL
- Block dangerous prompts and responses via Saf3AI real-time security scanning
- Export full conversation traces to the Saf3AI Analyzer dashboard via OpenTelemetry
You can also attach images or documents β they are scanned and injected into the conversation automatically.
Features
| Feature | Details |
|---|---|
| Multi-provider LLM | OpenAI GPT-4o mini, Google Gemini 2.5 Flash Lite, Groq LLaMA 3.3 70B |
| RAG knowledge base | ChromaDB + sentence-transformers (all-MiniLM-L6-v2); extend by dropping .txt files into data/ |
| Live web search | DuckDuckGo via duckduckgo-search β no API key required |
| File upload | Images (JPEG, PNG, GIF, WebP, BMP) and documents (PDF, DOCX, TXT, CSV, JSON, code files) |
| Security scanning | Every prompt & response scanned for injection, jailbreaks, hate speech, PII leakage, malicious URIs |
| Observability | Full OTel traces (prompt, response, tokens, threats) exported to Saf3AI Analyzer |
| Gradio UI | Browser-based chat with sidebar provider selector and file picker |
| CLI mode | Lightweight terminal chat loop via main.py |
Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User Interface β
β Gradio Web UI (app.py) / CLI (main.py) β
ββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AutoGen AssistantAgent β
β β
β βββββββββββββββββββ ββββββββββββββββββββββββββββ β
β β rag_search β β web_search β β
β β ChromaDB + β β DuckDuckGo (live) β β
β β sentence- β β No API key needed β β
β β transformers β β β β
β βββββββββββββββββββ ββββββββββββββββββββββββββββ β
β β
β LLM: OpenAI / Google Gemini / Groq β
ββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Saf3AI SDK Layer β
β (wraps every on_messages call transparently) β
β β
β ββββββββββββββββββββββββββββ βββββββββββββββββββββββ β
β β Security Scanner β β OTel Exporter β β
β β scanner-dev.saf3ai.com β β analyzer-dev. β β
β β Prompt + response scan β β saf3ai.com β β
β ββββββββββββββββββββββββββββ βββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Prerequisites
- Python 3.10 β 3.12
- Saf3AI account β API key from saf3ai.com
- At least one LLM API key β OpenAI, Google AI Studio, or Groq (all free tiers available)
Quick Start
1. Clone the repository
git clone https://huggingface.co/satyamsaf3ai/rag-websearch-autogen
cd rag-websearch-autogen
2. Create a virtual environment
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
3. Install the Saf3AI SDK
pip install git+https://github.com/saf3ai/saf3ai_sdk.git@satyam-dev
4. Install project dependencies
pip install -r requirements.txt
5. Configure environment
# Windows
copy .env.example .env
# macOS / Linux
cp .env.example .env
Edit .env and fill in your API keys:
LLM_PROVIDER=openai
OPENAI_API_KEY=sk-...
SAF3AI_API_KEY=your-key
SECURITY_API_KEY=your-key
SECURITY_API_ENDPOINT=https://scanner-dev.saf3ai.com
SAF3AI_COLLECTOR_AGENT=https://analyzer-dev.saf3ai.com/v1/traces
6. Run
python app.py
Open http://127.0.0.1:7865 in your browser.
(Optional) Enable PDF and Word document support
pip install pymupdf python-docx
Configuration
Copy the example file
# macOS / Linux
cp .env.example .env
# Windows
copy .env.example .env
Edit .env
# ββ Pick your LLM provider ββββββββββββββββββββββββββββββββ
LLM_PROVIDER=openai # openai | gemini | groq
OPENAI_API_KEY=sk-... # if LLM_PROVIDER=openai
GOOGLE_API_KEY=AIza... # if LLM_PROVIDER=gemini
GROQ_API_KEY=gsk_... # if LLM_PROVIDER=groq
# ββ Saf3AI ββββββββββββββββββββββββββββββββββββββββββββββββ
SAF3AI_API_KEY=your-key
SAF3AI_AGENT_ID=rag-websearch-autogen
SAF3AI_COLLECTOR_AGENT=https://analyzer-dev.saf3ai.com/v1/traces
SECURITY_API_ENDPOINT=https://scanner-dev.saf3ai.com
SECURITY_API_KEY=your-key
THREAT_ACTION_LEVEL=BLOCK # BLOCK | WARN | OFF
Full variable reference
| Variable | Required | Default | Description |
|---|---|---|---|
LLM_PROVIDER |
Yes | openai |
Active LLM provider |
OPENAI_API_KEY |
If openai |
β | OpenAI API key |
OPENAI_MODEL |
No | gpt-4o-mini |
OpenAI model name |
GOOGLE_API_KEY |
If gemini |
β | Google AI Studio key |
GEMINI_MODEL |
No | gemini-2.5-flash-lite |
Gemini model name |
GROQ_API_KEY |
If groq |
β | Groq API key |
GROQ_MODEL |
No | llama-3.3-70b-versatile |
Groq model name |
SAF3AI_API_KEY |
Yes | β | Saf3AI org API key |
SAF3AI_AGENT_ID |
No | rag-websearch-autogen |
Agent label in dashboard |
SAF3AI_COLLECTOR_AGENT |
Yes | http://localhost:19999 |
OTel traces endpoint |
SECURITY_SCAN_ENABLED |
No | true |
Set to false to disable scanning |
SECURITY_API_ENDPOINT |
Yes | β | Saf3AI Scanner URL |
SECURITY_API_KEY |
Yes | β | Scanner API key (same as SAF3AI_API_KEY) |
SECURITY_API_TIMEOUT |
No | 30 |
Scanner request timeout (seconds) |
THREAT_ACTION_LEVEL |
No | BLOCK |
BLOCK / WARN / OFF |
RAG_TOP_K |
No | 4 |
Documents returned per RAG query |
RAG_EMBED_MODEL |
No | all-MiniLM-L6-v2 |
Sentence-transformers model |
ENVIRONMENT |
No | development |
Shown in Analyzer traces |
Running
Gradio Web UI
python app.py
Open http://127.0.0.1:7865 in your browser.
UI walkthrough:
- Left sidebar β shows active tools and lets you switch LLM provider
- Chat area β type your question and press Enter or click Send
- File picker β attach an image or document before sending; it is scanned and included in the message context
- Clear button β resets the conversation
Terminal CLI
python main.py
============================================================
RAG + Web Search Agent (AutoGen + Saf3AI)
============================================================
Provider: openai
Type 'exit' to quit.
You: What is prompt injection?
Agent: Prompt injection is an attack where...
Adding Custom Knowledge
The agent ships with 5 built-in documents covering: Saf3AI SDK, Microsoft AutoGen, RAG, OpenTelemetry, and LLM security.
Add your own documents
Create the
data/directory if it doesn't exist:mkdir dataDrop any
.txtfiles intodata/β they are loaded automatically on the next startup.To ingest files without restarting the app:
# All .txt files in data/ python scripts/ingest_docs.py # Specific files python scripts/ingest_docs.py path/to/file1.txt path/to/file2.txt
The agent will now prefer these documents when answering relevant questions.
Saf3AI Security & Observability
How scanning works
The Saf3AI SDK patches AutoGen's on_messages method transparently. For every user message:
User sends message
β
βΌ
[Saf3AI] Prompt scan βββΊ POST /scan β scanner endpoint
β
βββ THREAT FOUND β raise ValueError β "π« Blocked by Saf3AI"
β
βββ CLEAN βββββββ LLM called normally
β
βΌ
[Saf3AI] Response scan (non-blocking, logged only)
β
βΌ
Answer shown in UI
Threat action levels
| Level | Behaviour |
|---|---|
BLOCK |
Dangerous prompts and responses are blocked; user sees an error message |
WARN |
Threats are logged as warnings but the request proceeds |
OFF |
Threat enforcement is disabled (scanning still runs, results only logged) |
File upload scanning
Images are scanned with the Saf3AI image scanner before display.
Documents are scanned with the Saf3AI document scanner before text extraction.
Unsafe files are rejected with a π« blocked message β content never reaches the LLM.
Observability dashboard
Every conversation emits an OTel span to SAF3AI_COLLECTOR_AGENT containing:
- Conversation ID and agent name
- Full prompt and response text
- Security scan results β detected categories, threat types, severity
- Token usage
View all traces at the Saf3AI Analyzer dashboard.
Project Structure
rag-websearch-autogen/
β
βββ app.py # Gradio web UI β main entry point
βββ main.py # Terminal CLI entry point
βββ requirements.txt # Pinned dependencies
βββ pyproject.toml # Package metadata
βββ .env.example # Configuration template (copy β .env)
β
βββ autogen_agent/
β βββ agent.py # AssistantAgent factory + Saf3AI SDK init
β βββ llm.py # LLM client factory (OpenAI / Gemini / Groq)
β βββ tools.py # rag_search + web_search FunctionTools
β βββ security.py # Threat policy + scanner setup
β βββ rag/
β βββ store.py # ChromaDB in-memory vector store
β
βββ scripts/
β βββ ingest_docs.py # Batch document ingestion CLI
β
βββ data/ # Drop .txt files here to extend the KB
# (auto-loaded on startup)
Switching LLM Providers
Set LLM_PROVIDER in .env and restart. The UI also has a live provider selector in the sidebar.
| Provider | Model | Notes |
|---|---|---|
openai |
gpt-4o-mini |
Best tool-calling reliability |
gemini |
gemini-2.5-flash-lite |
Fast, low cost |
groq |
llama-3.3-70b-versatile |
Very fast inference |
Troubleshooting
model_info is required error
AutoGen doesn't recognise the model name. Make sure LLM_PROVIDER matches one of openai, gemini, or groq exactly.
Chatbot.__init__() got an unexpected keyword argument
Gradio version mismatch. Run pip install gradio==6.19.0.
OSError: Cannot find empty port
Port 7865 is already in use. Change server_port in app.py or kill the existing process.
Scanner not appearing in dashboard
Check that SAF3AI_COLLECTOR_AGENT points to your Analyzer endpoint (not localhost) and that SECURITY_API_ENDPOINT is set correctly.
No documents found in RAG search
Make sure the data/ directory exists and contains .txt files, or run python scripts/ingest_docs.py to verify ingestion.
License
MIT