beginner5 min· python · siftq · openai

RAG with the OpenAI Responses API

Same recipe, different model — drop-in OpenAI grounding.

Prerequisites

  • $pip install openai requests
  • $export SIFTQ_API_KEY=mk-...
  • $export OPENAI_API_KEY=sk-...

How it works

The retrieval primitive is model-agnostic. If your stack is on OpenAI rather than Anthropic, the loop is identical — same SiftQ call, same system instructions, swap the synthesis layer. This is the value of separating retrieval and generation: you keep model optionality without rewriting your search code.

The recipe

rag_with_openai.py
import os
import requests
from openai import OpenAI

client = OpenAI()
SIFTQ_KEY = os.environ["SIFTQ_API_KEY"]


def search(q: str, n: int = 8) -> list[dict]:
    r = requests.post(
        "https://api.siftq.com/v1/search",
        headers={"Authorization": f"Bearer {SIFTQ_KEY}"},
        json={"q": q, "scope": "webpage", "size": str(n), "conciseSnippet": True},
        timeout=20,
    )
    r.raise_for_status()
    return r.json().get("webpages", [])


def answer(question: str) -> str:
    hits = search(question)
    sources = "\n\n".join(
        f"[{i + 1}] {h['title']}\n{h['snippet']}\nURL: {h['link']}"
        for i, h in enumerate(hits)
    )

    resp = client.responses.create(
        model="gpt-5",
        instructions=(
            "Answer using only the provided sources. "
            "Cite as [N] inline next to every factual claim. "
            "Refuse to answer if the sources do not contain the information."
        ),
        input=f"SOURCES:\n{sources}\n\nQUESTION: {question}",
    )
    return resp.output_text


if __name__ == "__main__":
    print(answer("What are the latest open-source LLM benchmarks?"))

Variations

Structured outputs (JSON)

Pass response_format with a JSON schema so the LLM returns {answer, citations:[]} parsed objects instead of free text.

Function calling

Expose SiftQ as a tool the model decides when to call, rather than hard-coding retrieval before every prompt.

Keep cooking

RAG with Claude in 30 lines
Web-grounded Q&A using SiftQ retrieval + Claude Sonnet, with inline citations.
SiftQ as a LangChain agent tool
Wrap SiftQ in @tool, hand it to a ReAct agent, watch it search autonomously.
Test this query in the SiftQ API playground →