Language: English | 简体中文
SAG: Graph retrieval technology capable of running on large-scale dynamic data.
This project is an out-of-the-box document retrieval workbench built on SAG. After you upload Markdown or TXT documents, SAG automatically handles chunking, vectorization, event extraction, entity extraction, and relation organization. You can ask questions over project documents in a ChatGPT-like interface, inspect chunks, events, entities, embeddings, search traces, raw model logs, and explore the knowledge graph.
SAG benchmark reproduction code: Zleap-AI/SAG-Benchmark
SAG is a next-generation RAG approach designed for agents. Instead of stuffing more chunks into the model, it organizes document knowledge with a lighter structure:
chunk -> event
chunk -> entities
event <-> entities
Each chunk extracts one complete event and multiple entities. The event preserves the full semantic unit, while entities build the index and enable relational expansion, so retrieval can start from a matched event and continue through multi-hop recall without the rebuild cost of a heavyweight knowledge graph.
On HotpotQA / 2WikiMultiHop / MuSiQue, under the same configuration:
Embedding = bge-large-en-v1.5
LLM = qwen3.6-flash
Datasets = HotpotQA / 2WikiMultiHop / MuSiQue
Compared with HippoRAG 2, SAG achieves clear recall improvements on multi-hop QA: average Recall@2 improves from 68.14% to 79.30%, a gain of 11.16 percentage points, or about 16.4% relative improvement. Higher Recall@2 means agents can hit key evidence earlier with less context, reducing token cost, latency, and distraction in multi-turn tasks.
On MuSiQue Recall@5, SAG improves from HippoRAG 2's 65.13% to 80.04%; after switching to NV-Embed-v2, it further reaches 81.71%, showing that the gain mainly comes from the structure rather than only a stronger embedding model.
This project turns SAG into a local workbench that can run immediately. It is suitable for:
- Project document Q&A
- Personal knowledge base search
- RAG / agent prototype validation
- Document event and entity analysis
- MCP tool integration testing
- Search pipeline debugging and model-call inspection
Core features:
- Project management: each project has its own documents, conversations, graph, and MCP configuration.
- Multi-document upload: upload multiple Markdown / TXT files at once, with processing stages and progress.
- Document processing results: inspect chunks, events, entities, embedding data, keyword title search, and paginated browsing.
- Conversational retrieval: ask multi-turn questions over the current project, with streaming output and stop generation.
- Source citations: answers can show numbered citations; click a number to view the original chunk.
- Search trace visualization: the right panel shows SAG's internal retrieval steps and latency in real time.
- Raw logs: browser cache stores raw LLM / Embedding / Rerank requests and responses.
- Knowledge graph: explore project relations with event and entity nodes; drag, zoom, expand, and open details.
- MCP integration: each project exposes its own MCP configuration so external agents can call the current project directly.
SAG uses TypeScript across the stack. The frontend is a React + Vite + Tailwind CSS WebUI. The backend uses Fastify HTTP APIs, the MCP TypeScript SDK, and layered service modules. The data layer uses PostgreSQL, pgvector, full-text search, and SQL multi-hop queries. Model providers are OpenAI-compatible LLM, Embedding, and Rerank APIs.
In the Document tab, you can upload documents, inspect processing status, chunks, events, entities, and embeddings.
In the Graph tab, you can explore entity-event relations across a project. Nodes support drag, zoom, click-to-expand, and double-click details.
In the Chat tab, you can ask continuous questions over the current project. Each retrieval refreshes the right-side trace panel for debugging the current call chain.
SAG provides two modes:
- Fast mode: directly matches the query against the entity store using full-text / BM25 search, expands through SAG multi-hop retrieval, and finally uses
qwen3-rerankto select top-k. This mode does not use an LLM to extract query entities or filter candidates, so it is much faster. - Standard mode: uses an LLM to extract query entities, then runs SAG multi-route recall and LLM reranking. This is useful when you want to compare the higher-precision pipeline.
Both modes are more than ordinary vector search because both use SAG's event/entity index and SQL multi-hop expansion.
You need:
- Node.js 20 or later
- npm
- PostgreSQL
- pgvector
If you want the fastest setup, use Docker to start PostgreSQL.
git clone https://github.com/Zleap-AI/SAG.git
cd SAGcp .env.example .env.env.example already contains default values. For real usage, fill in your own LLM and Embedding API keys.
Using Docker:
docker compose up -dIf you do not want to use Docker, you can use Homebrew on macOS:
brew install postgresql@17 pgvector
brew services start postgresql@17
/opt/homebrew/opt/postgresql@17/bin/createdb sag_lite
/opt/homebrew/opt/postgresql@17/bin/psql -d sag_lite -c 'create extension if not exists vector;'If you use a local PostgreSQL instance, update DATABASE_URL in .env, for example:
DATABASE_URL=postgres://your_user@localhost:5432/sag_litenpm install
npm run db:setupnpm run devDefault development URLs:
WebUI: http://localhost:5173
API: http://localhost:4173
npm run build
npm startDefault production URL:
http://localhost:4173
- Open the WebUI.
- Click "New Project" at the top of the left project list.
- Go to the Document tab and click "Add Document".
- Upload
.mdor.txtfiles. - Wait for the processing queue to finish.
- Inspect chunks, events, entities, and embedding status.
- Return to the Chat tab and ask questions over the current project.
- For debugging, inspect the right-side Search Trace and Raw Logs.
- For relationship exploration, open the Graph tab.
- For external agents, open the MCP tab and copy the current project's configuration.
SAG supports OpenAI-compatible APIs. Default example:
EMBEDDING_BASE_URL=https://api.302ai.cn/v1
EMBEDDING_MODEL=text-embedding-3-large
EMBEDDING_DIMENSIONS=1024
LLM_BASE_URL=https://api.302ai.cn/v1
LLM_MODEL=qwen3.6-flash
RERANK_MODEL=qwen3-rerank
DEFAULT_SEARCH_MODE=fastYou can configure models in two ways:
Click the settings icon at the top of the left sidebar, open Global Settings, and fill in provider, model names, and API keys.
API keys only show as "Configured / Not configured". Plaintext keys are not echoed in the UI or API responses.
EMBEDDING_API_KEY=your_embedding_key
LLM_API_KEY=your_llm_key
RERANK_BASE_URL=https://api.your-provider.com/v1/rerankBy default, rerank requests use LLM_BASE_URL and append /reranks, for example https://api.302ai.cn/v1/reranks. Set RERANK_BASE_URL only when your provider needs a different full endpoint such as /v1/rerank.
If no API key is configured, the system uses a local deterministic fallback. This is useful for tests and UI inspection, but real retrieval quality requires remote models.
SAG can act as an MCP Server for external agents. Each project's MCP configuration binds the current project ID, so tool calls do not need to pass projectId.
Open the MCP tab in the WebUI to see the auto-generated mcpServers JSON for the current project. It looks like this:
{
"mcpServers": {
"sag": {
"command": "npm",
"args": ["run", "mcp"],
"env": {
"SAG_MCP_SOURCE_ID": "current_project_id"
}
}
}
}Available MCP tools:
sag_ingest_document: import a document and run chunking, event extraction, entity extraction, and vectorization.sag_search: run SAG multi-route retrieval on the current project and return the internal trace.sag_explain_search: return the current project's retrieval pipeline explanation and trace.sag_get_event: query event details by event ID.
Health check:
curl http://localhost:4173/healthCreate a project:
curl -X POST http://localhost:4173/api/projects \
-H 'Content-Type: application/json' \
-d '{"name":"Demo Project"}'Ingest a document:
curl -X POST http://localhost:4173/ingest \
-H 'Content-Type: application/json' \
-d '{"sourceId":"project_id","title":"Demo","content":"# Demo\n\nSAG can search project documents.","extract":true}'Run search:
curl -X POST http://localhost:4173/api/search \
-H 'Content-Type: application/json' \
-d '{"query":"Why is SAG suitable for multi-hop retrieval?","sourceIds":["project_id"],"strategy":"multi","searchMode":"fast","topK":5,"returnTrace":true}'Stream search trace:
curl -N -X POST http://localhost:4173/api/search/stream \
-H 'Content-Type: application/json' \
-d '{"query":"Explain SAG event/entity indexing","sourceIds":["project_id"],"strategy":"multi","returnTrace":true}'# Type check
npm run typecheck
# Run tests
npm test
# Build production assets
npm run build
# Start production server
npm start
# Start MCP stdio server
npm run mcpsrc/
ai/ LLM, Embedding, and Rerank clients
api/ HTTP API
config/ Environment configuration
db/ Database connection, migrations, repositories, vector tools
ingestion/ Document chunking and event extraction
mcp/ MCP Server
observability/ Logs and model-call records
services/ Document processing, search, graph, and WebUI services
web/
src/ React WebUI
migrations/ PostgreSQL schema
test/ Unit tests
docs/assets/ README screenshots and diagrams
First confirm that the database is running:
docker compose psThen confirm that DATABASE_URL in .env is correct.
Make sure pgvector is installed and run:
create extension if not exists vector;If you use docker compose up -d, the image already includes pgvector.
If LLM_API_KEY and EMBEDDING_API_KEY are not configured, the system enters local fallback mode. This is useful for testing, but it is not suitable for judging real retrieval quality.
Document processing calls Embedding and LLM APIs. Speed mainly depends on document count, chunk count, model API latency, and concurrency settings. You can tune this in .env:
INGEST_CONCURRENCY=5In development mode, update .env:
HTTP_PORT=4173The Vite WebUI uses 5173 by default. If the port is occupied, Vite will show the new address automatically.
MIT License. See LICENSE.




