With RAG
Plug the Super RAG subsystem into a plain shipit_agent.Agent with one parameter and read DRK_CACHE-style citations off result.rag_sources.
Wire a knowledge base into a plain Agent using one constructor
parameter: rag=. The agent gains three new tools (rag_search,
rag_fetch_chunk, rag_list_sources) and the system prompt is
augmented with citation instructions automatically.
After every agent.run(...) the result carries a rag_sources field
— the DRK_CACHE-style citation panel.
Want the full Super RAG documentation? See Super RAG → Overview, the Standalone RAG cookbook, and the Files, Chunks & Sources guide.
Quickstart
from shipit_agent import Agent
from shipit_agent.rag import RAG, HashingEmbedder
rag = RAG.default(embedder=HashingEmbedder(dimension=512))
rag.index_text("Shipit supports Python 3.10+.", source="readme.md")
rag.index_text("Agents stream events in real time.", source="streaming.md")
agent = Agent(llm=my_llm, rag=rag)
result = agent.run("What Python version does Shipit support?")
print(result.output)
# "Shipit supports Python 3.10+. [1]"
for src in result.rag_sources:
print(f"[{src.index}] {src.source} (chunk {src.chunk_id}, score {src.score:.2f})")
print(f" {src.text}")What rag= actually does
When you construct an Agent with rag=..., the constructor:
- Auto-appends three tools —
rag_search,rag_fetch_chunk,rag_list_sources— toagent.tools. If you already supplied a tool with the same name, the existing one wins (no duplication). - Augments the system prompt with a short instruction block telling
the LLM how to use the tools and how to cite sources with
[N]markers. - Wraps
runandstreaminrag.begin_run()/rag.end_run()so every chunk retrieved during the run is captured by a per-runSourceTracker.
After the run completes, the captured sources are deduplicated by
chunk_id, indexed with stable [1], [2], … citation numbers, and
attached to result.rag_sources as a list of RAGSource dataclasses.
Indexing files (PDF, MD, HTML, …)
rag.index_file("docs/manual.pdf") # needs `pip install shipit-agent[rag-pdf]`
rag.index_file("docs/install.md") # zero deps
rag.index_file("docs/architecture.html") # zero depsFor an in-depth recipe (chunk size tuning, persisting chunks to disk, reloading them later) see Files, Chunks & Sources.
Streaming with sources
agent.stream(...) yields events as they happen. RAG-equipped runs
emit a final rag_sources event with the consolidated citation list:
for event in agent.stream("How do I configure logging?"):
if event.type == "rag_sources":
for src in event.payload["sources"]:
print(f" [{src['index']}] {src['source']}")
elif event.type == "run_completed":
print(event.payload.get("output"))Multiple agents sharing one RAG
researcher = Agent(llm=llm, prompt="You research the codebase.", rag=rag)
writer = Agent(llm=llm, prompt="You write user-facing copy.", rag=rag)The internal source tracker uses thread-local state so concurrent
runs on different threads don't bleed citations into each other. Each
agent's result.rag_sources is independent.
Customising the auto-injected prompt section
class MyRAG(RAG):
def prompt_section(self) -> str:
return (
"You may call rag_search, rag_fetch_chunk, and rag_list_sources. "
"Cite results with `(source: chunk_id)` markers."
)
agent = Agent(llm=llm, rag=MyRAG.default(embedder=embedder))Disabling auto-wiring
If you want fine-grained control — for example to wire only
rag_search and skip rag_fetch_chunk — build the tools manually and
pass them to tools= instead of using rag=:
from shipit_agent.rag.tools import RAGSearchTool
agent = Agent(
llm=llm,
tools=[RAGSearchTool(rag=rag)],
# Don't pass rag= here, so the prompt isn't auto-augmented.
)In this mode result.rag_sources will still be empty — source tracking
only runs when the Agent knows about the RAG via the rag= field.
Call rag.begin_run() / rag.end_run() manually around your own loop
to capture sources without the auto-wiring.