Find
Search dashboard pages and product views.
Search dashboard pages and product views.
Balaji-R-05/askdocs-ai
Add live web search/retrieval to this repository so its agent can ground its answers in current web information. Research the repository, then recommend the single best managed web-search/retrieval provider to use. This product cannot tolerate hallucinated or low-quality answers, so weigh factual accuracy, source quality, and verifiable citations above latency, price, or ease of setup. Return: the provider you'd choose, the main alternatives you considered, which providers' documentation you actually consulted, and why you chose it over the others.
P1
26bc632a0bed22f035740edd34ee3e1fc2420e9f
Agent context: I’ll first map how this agent is structured and where external retrieval would plug in, then I’ll verify current provider docs directly so the recommendation is grounded in both the codebase and live vendor capabilities. I’ll first map how this agent is structured and where external retrieval would plug in, then I’ll verify current provider docs directly so the recommendation is grounded in both the codebase and live vendor capabilities.
Agent context: I’ll first map how this agent is structured and where external retrieval would plug in, then I’ll verify current provider docs directly so the recommendation is grounded in both the codebase and live vendor capabilities.
Agent context: I’ll first map how this agent is structured and where external retrieval would plug in, then I’ll verify current provider docs directly so the recommendation is grounded in both the codebase and live vendor capabilities. exit code 0 Output: /home/user/worktrees/attempt-cf1c0d97-aecf-4613-85ae-e3120b008c80-cap-1 /bin/bash: line 1: rg: command not found
Agent context: `rg` is not installed in this environment, so I’m falling back to `find` and direct file reads. I’m also using the OpenAI docs skill for any OpenAI web-search API comparison so I stick to official documentation. `rg` is not installed in this environment, so I’m falling back to `find` and direct file reads. I’m also using the OpenAI docs skill for any OpenAI web-search API comparison so I stick to official documentation. Provider mentions: openai
Agent context: `rg` is not installed in this environment, so I’m falling back to `find` and direct file reads. I’m also using the OpenAI docs skill for any OpenAI web-search API comparison so I stick to official documentation.
Agent context: `rg` is not installed in this environment, so I’m falling back to `find` and direct file reads. I’m also using the OpenAI docs skill for any OpenAI web-search API comparison so I stick to official documentation. exit code 0 Output: .git .dockerignore .gitignore Dockerfile.client Dockerfile.server README.md client/__init__.py client/api_client.py client/auth_utils.py client/config.py client/main.py compose.yaml images/chat_interface.png images/db_indexed.png images/landing_page.png requirements.client.txt requirements.server.txt server/__init__.py server/config.py server/db/database.py server/db/models.py server/main.py server/modules/__init__.py server/modules/auth.py server/modules/llm.py server/modules/vectorstore.py server/schemas/auth.py server/tests/test_hybrid_search.py
Agent context: `rg` is not installed in this environment, so I’m falling back to `find` and direct file reads. I’m also using the OpenAI docs skill for any OpenAI web-search API comparison so I stick to official documentation.
Agent context: `rg` is not installed in this environment, so I’m falling back to `find` and direct file reads. I’m also using the OpenAI docs skill for any OpenAI web-search API comparison so I stick to official documentation. exit code 0 Output: total 56 drwxr-xr-x 7 user user 4096 Jun 6 04:48 . drwxr-xr-x 4 user user 4096 Jun 6 04:48 .. dr-xr-xr-x 2 user user 40 Jun 6 04:48 .agents dr-xr-xr-x 2 user user 40 Jun 6 04:48 .codex -rw-r--r-- 1 user user 61 Jun 6 04:48 .dockerignore -rw-r--r-- 1 user user 170 Jun 6 04:48 .git -rw-r--r-- 1 user user 118 Jun 6 04:48 .gitignore -rw-r--r-- 1 user user 282 Jun 6 04:48 Dockerfile.client -rw-r--r-- 1 user user 248 Jun 6 04:48 Dockerfile.server -rw-r--r-- 1 user user 2863 Jun 6 04:48 README.md drwxr-xr-x 2 user user 4096 Jun 6 04:48 client -rw-r--r-- 1 user user 1044 Jun 6 04:48 compose.yaml drwxr-xr-x 2 user user 4096 Jun 6 04:48 images -rw-r--r-- 1 user user 32 Jun 6 04:48 requirements.client.txt -rw-r--r-- 1 user user 351 Jun 6 04:48 requirements.server.txt drwxr-xr-x 6 user user 4096 Jun 6 04:48 server
Agent context: `rg` is not installed in this environment, so I’m falling back to `find` and direct file reads. I’m also using the OpenAI docs skill for any OpenAI web-search API comparison so I stick to official documentation. Provider mentions: openai
Agent context: `rg` is not installed in this environment, so I’m falling back to `find` and direct file reads. I’m also using the OpenAI docs skill for any OpenAI web-search API comparison so I stick to official documentation. exit code 0 Output: --- name: "openai-docs" description: "Use when the user asks how to build with OpenAI products or APIs, asks about Codex itself or choosing Codex surfaces, needs up-to-date official documentation with citations, help choosing the latest model for a use case, or model upgrade and prompt-upgrade guidance; use OpenAI docs MCP tools for non-Codex docs questions, use the Codex manual helper first for broad Codex self-knowledge, and restrict fallback browsing to official OpenAI domains." --- # OpenAI Docs Provide authoritative, current guidance from OpenAI developer docs using the developers.openai.com MCP server. "Docs MCP" means `mcp__openaiDeveloperDocs__search_openai_docs` and `mcp__openaiDeveloperDocs__fetch_openai_doc`; for API reference, schema, parameter, or required-field questions, also use `mcp__openaiDeveloperDocs__get_openapi_spec` when available. Official-domain web search is fal Provider mentions: openai
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor.
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor.
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. exit code 0 Output: # AskDocs AI: AI-Powered PDF Q&A Bot **AskDocs AI** is an AI-powered chatbot that leverages **Hybrid RAG (Retrieval-Augmented Generation)** to answer your questions based on the content of uploaded PDFs. It combines semantic vector search with traditional keyword-based search for superior accuracy. <img src="./images/landing_page.png" alt="Landing Page"> <img src="./images/chat_interface.png" alt="Chat Interface"> ## Key Features - **Hybrid Search**: Combines **ChromaDB** (semantic) and **BM25** (keyword) retrieval. - **LLM Powered**: High-performance LLM via Groq Cloud. - **Async Processing**: PDF ingestion and indexing are offloaded to background threads. - **Multimodal Support**: Optimized for PDF extraction and processing. ## Tech Stack - **Backend:** FastAPI, LangChain (Classic), ChromaDB, Groq Cloud - **Frontend:** Streamlit - **Search Engines:** BM25 (Keyword), Vector (Cosine Simi
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor.
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. exit code 0 Output: from langchain_groq import ChatGroq from langchain_classic.chains import RetrievalQA from langchain_classic.retrievers import EnsembleRetriever from config import settings from modules.vectorstore import get_bm25_retriever import logging logger = logging.getLogger(__name__) def get_llm_chain(vectorstore): if vectorstore is None: return None if not settings.GROQ_API_KEY: raise ValueError("GROQ_API_KEY is not set in environment or config.") llm = ChatGroq( groq_api_key=settings.GROQ_API_KEY, model_name=settings.LLM_MODEL, temperature=0.3, ) # 1. Semantic Retriever (Vector) chroma_retriever = vectorstore.as_retriever(search_kwargs={"k": 3}) # 2. Keyword Retriever (BM25) bm25_retriever = get_bm25_retriever(vectorstore) # 3. Ensemble Retriever (Hybrid) if bm25_retriever: logger.info(f"[HYBRID] Initializing Hybrid Search (BM25: {settings.HYBRID_SEARCH_BM25_WEIGHT}, Chroma: {settings.HYBRID_SEA
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor.
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. exit code 0 Output: import os import hashlib import logging from concurrent.futures import ThreadPoolExecutor from langchain_chroma import Chroma from langchain_community.document_loaders import PyPDFLoader from langchain_community.retrievers import BM25Retriever from langchain_core.documents import Document from langchain_text_splitters import RecursiveCharacterTextSplitter from langchain_huggingface import HuggingFaceEmbeddings from config import settings logger = logging.getLogger(__name__) def file_hash(file_path: str) -> str: """Generate a unique hash for file contents (duplicate detection).""" with open(file_path, "rb") as f: return hashlib.md5(f.read()).hexdigest() def load_single_pdf(path): """Worker function to load a single PDF.""" try: logger.info(f"📄 Starting to parse: {os.path.basename(path)}") loader = PyPDFLoader(path) file_docs = loader.load() if not file_docs: logger.warning(f"⚠️ No text e
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor.
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. exit code 0 Output: import os import shutil import logging from typing import List from contextlib import asynccontextmanager from fastapi import FastAPI, UploadFile, File, HTTPException, Depends from fastapi.middleware.cors import CORSMiddleware from fastapi.concurrency import run_in_threadpool from pydantic import BaseModel from config import settings from modules.vectorstore import process_pdfs, get_vectorstore from modules.llm import get_llm_chain from db.database import engine from db.models import Base, User from modules.auth import fastapi_users, auth_backend, current_active_user from schemas.auth import UserRead, UserCreate, UserUpdate logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) @asynccontextmanager async def lifespan(app: FastAPI): """Lifecycle events for the FastAPI application.""" logger.info("🛠️ Star
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor.
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. exit code 0 Output: import os from pathlib import Path from pydantic_settings import BaseSettings, SettingsConfigDict from dotenv import load_dotenv, find_dotenv load_dotenv(find_dotenv(), override=True) BASE_DIR = Path(__file__).resolve().parent.parent class Settings(BaseSettings): PROJECT_NAME: str = "AskDocs AI API" # Storage CHROMA_DB_PATH: str = os.getenv("CHROMA_DB_PATH", "chroma_db") TEMP_UPLOADS_DIR: str = os.getenv("TEMP_UPLOADS_DIR", "temp_uploads") # Database & Security DATABASE_URL: str = os.getenv("DATABASE_URL", "postgresql+asyncpg://postgres:postgres@db:5432/askdocs") SECRET_KEY: str = os.getenv("SECRET_KEY", "CHANGEME_SECRET_KEY_12345") # LLM GROQ_API_KEY: str | None = os.getenv("GROQ_API_KEY", "") LLM_MODEL: str = os.getenv("LLM_MODEL", "openai/gpt-oss-120b") # Throughput Settings MAX_WORKERS: int = os.cpu_count() or 4 # Hybrid Search Weights HYBRID_SEARCH_BM25_WEIGHT: float = float(os.gete Provider mentions: openai
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor.
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. exit code 0 Output: --extra-index-url https://download.pytorch.org/whl/cpu torch langchain-chroma langchain-community langchain-text-splitters langchain-huggingface langchain-groq langchain-classic fastapi uvicorn[standard] python-multipart python-dotenv sentence-transformers pypdf pydantic-settings rank_bm25 sqlalchemy[asyncio] asyncpg fastapi-users[sqlalchemy] bcrypt
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor.
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. exit code 0 Output: import sys import os import logging # Add server directory to path sys.path.append(os.path.abspath("server")) from modules.vectorstore import get_vectorstore, get_bm25_retriever from modules.llm import get_llm_chain logging.basicConfig(level=logging.INFO) def test_hybrid(): print("[INIT] Initializing test for Hybrid Search...") vectorstore = get_vectorstore() print("[OK] Vectorstore loaded.") # Test BM25 Rebuild bm25 = get_bm25_retriever(vectorstore) if bm25: print(f"[OK] BM25 Retriever built successfully.") # Try a simple keyword search query = "test" results = bm25.invoke(query) print(f"[SEARCH] BM25 found {len(results)} results for '{query}'") else: print("[FAIL] BM25 Retriever build failed.") # Test LLM Chain (Ensemble) try: chain = get_llm_chain(vectorstore) if chain: print("[OK] LLM Chain with Ensemble Retriever created successfully.") # Note: chain.invoke will call the LLM, which
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. Provider mentions: openai
Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. exit code 0 Output: ./README.md:3:**AskDocs AI** is an AI-powered chatbot that leverages **Hybrid RAG (Retrieval-Augmented Generation)** to answer your questions based on the content of uploaded PDFs. It combines semantic vector search with traditional keyword-based search for superior accuracy. ./README.md:10:- **Hybrid Search**: Combines **ChromaDB** (semantic) and **BM25** (keyword) retrieval. ./README.md:11:- **LLM Powered**: High-performance LLM via Groq Cloud. ./README.md:17:- **Backend:** FastAPI, LangChain (Classic), ChromaDB, Groq Cloud ./README.md:29:| `HYBRID_SEARCH_BM25_WEIGHT` | Weight for keyword search (0.0 to 1.0) | `0.5` | ./README.md:30:| `HYBRID_SEARCH_CHROMA_WEIGHT` | Weight for semantic search (0.0 to 1.0) | `0.5` | ./README.md:31:| `GROQ_API_KEY` | Your Groq Cloud API Key | *Required* | ./README.md:84:python server/tests/test_hybrid_search.py ./client/main.py:128: if response.get("sour Provider mentions: openai
Query/prompt: site:platform.openai.com/docs web search tool Responses API citations annotations OpenAI Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. Query: site:platform.openai.com/docs web search tool Responses API citations annotations OpenAI Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. Expanded queries: site:platform.openai.com/docs web search tool Responses API citations annotations OpenAI | site:developers.openai.com OpenAI API web search tool Responses citations | OpenAI Responses API web search tool citations official docs Provider mentions: openai
Query/prompt: Tavily Search API official docs search extract crawl citations raw_content Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. Query: Tavily Search API official docs search extract crawl citations raw_content Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. Expanded queries: Tavily Search API official docs search extract crawl citations raw_content | Exa API official docs search contents highlights livecrawl | Brave Search API official docs web search snippets source
Query/prompt: official Google Gemini API grounding with Google Search citations grounding metadata docs Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. Query: official Google Gemini API grounding with Google Search citations grounding metadata docs Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. Expanded queries: official Google Gemini API grounding with Google Search citations grounding metadata docs | official Google Vertex AI Grounding with Google Search docs citations grounding chunks | official Perplexity Sonar API citations search results docs
Query/prompt: site:docs.perplexity.ai Search API Perplexity official docs raw results citations Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. Query: site:docs.perplexity.ai Search API Perplexity official docs raw results citations Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. Expanded queries: site:docs.perplexity.ai Search API Perplexity official docs raw results citations | site:docs.perplexity.ai Sonar API citations search_domain_filter search_recency_filter official docs | site:docs.perplexity.ai Perplexity API search results citations response format
Query/prompt: https://platform.openai.com/docs/guides/tools-web-search?api-mode=responses Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. Query: https://platform.openai.com/docs/guides/tools-web-search?api-mode=responses Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. Provider mentions: openai
Query/prompt: 'url' in https://docs.tavily.com/documentation/api-reference/endpoint/search Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. Query: 'url' in https://docs.tavily.com/documentation/api-reference/endpoint/search Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor.
Query/prompt: https://cloud.google.com/vertex-ai/generative-ai/docs/grounding/grounding-with-your-data Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor. Query: https://cloud.google.com/vertex-ai/generative-ai/docs/grounding/grounding-with-your-data Agent context: The repository is a compact FastAPI plus Streamlit RAG app: server code, a vector store module, and one hybrid-search test. I’m reading the LLM/vector paths now to understand whether live web retrieval should be integrated as an agent tool, a retrieval layer, or a prompt preprocessor.
Agent context: **Provider** I’d choose **Google Vertex AI/Gemini grounding with Google Search**, and use **Vertex AI Search/Agent Search** for managed retrieval over uploaded documents if you want to move the repo’s PDF RAG off Chroma later. Why: this repo currently uses a local Chroma+BM25 retriever and then asks Groq through LangChain `RetrievalQA` to synthesize an answer, with sources reduced to filenames in the API response ([server/modules/llm.py](/home/user/worktrees/attempt-cf1c0d97-aecf-4613-85ae-e3120b008c80-cap-1/server/modules/llm.py:13), [server/main.py](/home/user/worktrees/attempt-cf1c0d97-aecf-4613-85ae-e3120b008c80-cap-1/server/main.py:124)). For a product that prioritizes factuality and citations, I’d rather use a managed grounding path that returns claim-to-source metadata, not just raw search snippets pasted into a prompt. Google’s docs show grounding returns `groundingMetadata` with search queries, web sources, and citation supports, and the metadata includes source URI/title/domain plus claim-to-source mappings. It also supports grounding to your own data and says that private data grounding can be combined with Google Search. Sources: [Gemini Google Search grounding](https://ai.google.dev/gemini-api/docs/google-search?authuser=2), [Vertex/Agent Search grounding](https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/grounding/grounding-with-vertex-ai-search), [GroundingMetadata reference](https://docs.cloud.google.com/gemini-enterprise-agent-platform/reference/rest/v1/GroundingMetadata). **Main Alternatives** - **OpenAI Responses API `web_search` + `file_search`**: very strong runner-up. It has built-in web search, inline citations, citation annotations, domain filters, and hosted file search in one agentic API. I would choose this if the team strongly prefers OpenAI models or wants a simpler migration from local RAG to hosted tools. Sources: [OpenAI web search](https://developers.openai.com/api/docs/guides/tools-web-search), [Responses API](https://developers.openai.com/api/docs/guides/migrate-to-responses), [OpenAI file search](https://developers.openai.com/api/docs/guides/tools-file-search). - **Tavily**: best incremental fit for the current LangChain-ish architecture. It returns URLs, content, scores, raw page content, date/domain filters, and has explicit AI-search ergonomics. I would use it for a fast additive retriever, but not as the highest-assurance final grounding system. Source: [Tavily Search API](https://docs.tavily.com/documentation/api-reference/endpoint/search). - **Perplexity Search/Sonar**: good cited-answer and raw-search APIs, and its docs correctly warn not to trust model-generated URLs. Strong option, but I’d still rank Google/OpenAI higher for enterprise grounding metadata and source-control surface. Source: [Perplexity Search API](https://docs.perplexity.ai/docs/search/quickstart). - **Exa**: strong semantic web search with highlights, livecrawl, and deep search modes. Better for discovery/research workflows than authoritative factual grounding. Source: [Exa Search API](https://exa.ai/docs/reference/search-api-guide-for-coding-agents). - **Brave Search API**: independent index and useful ranked web results/snippets, but it is more of a search-results API than a full citation-grounding layer. Source: [Brave Search API](https://brave.com/search/api/). **Why Google Over The Others** Google has the best fit for the stated priority order: source quality first, verifiable citations second, setup/latency/price later. Its grounding metadata is designed around evidence chunks and claim-level supports, and its web grounding is backed by Google Search. For this repo, I’d pair that with a stricter response contract: no citation metadata, no answer. **Provider** I’d choose **Google Vertex AI/Gemini grounding with Google Search**, and use **Vertex AI Search/Agent Search** for managed retrieval over uploaded documents if you want to move the repo’s PDF RAG off Chroma later. Why: this repo currently uses a local Chroma+BM25 retriever and then asks Groq through LangChain `RetrievalQA` to synthesize an answer, with sources reduced to filenames in the API response ([server/modules/llm.py](/home/user/worktrees/attempt-cf1c0d97-aecf-4613-85ae-e3120b008c80-cap-1/server/modules/llm.py:13), [server/main.py](/home/user/worktrees/attempt-cf1c0d97-aecf-4613-85ae-e3120b008c80-cap-1/server/main.py:124)). For a product that prioritizes factuality and citations, I’d rather use a managed grounding path that returns claim-to-source metadata, not just raw search snippets pasted into a prompt. Google’s docs show grounding returns `groundingMetadata` with search queries, web sources, and citation supports, and the metadata includes source URI/title/domain plus claim-to-source mappings. It also supports grounding to your own data and says that private data grounding can be combined with Google Search. Sources: [Gemini Google Search grounding](https:/ Provider mentions: openai
**Provider** I’d choose **Google Vertex AI/Gemini grounding with Google Search**, and use **Vertex AI Search/Agent Search** for managed retrieval over uploaded documents if you want to move the repo’s PDF RAG off Chroma later. Why: this repo currently uses a local Chroma+BM25 retriever and then asks Groq through LangChain `RetrievalQA` to synthesize an answer, with sources reduced to filenames in the API response ([server/modules/llm.py](/home/user/worktrees/attempt-cf1c0d97-aecf-4613-85ae-e3120b008c80-cap-1/server/modules/llm.py:13), [server/main.py](/home/user/worktrees/attempt-cf1c0d97-aecf-4613-85ae-e3120b008c80-cap-1/server/main.py:124)). For a product that prioritizes factuality and citations, I’d rather use a managed grounding path that returns claim-to-source metadata, not just raw search snippets pasted into a prompt. Google’s docs show grounding returns `groundingMetadata` with search queries, web sources, and citation supports, and the metadata includes source URI/title/domain plus claim-to-source mappings. It also supports grounding to your own data and says that private data grounding can be combined with Google Search. Sources: [Gemini Google Search grounding](https://ai.google.dev/gemini-api/docs/google-search?authuser=2), [Vertex/Agent Search grounding](https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/grounding/grounding-with-vertex-ai-searc Provider mentions: openai