AACSearch / guide
GraphRAG — entities, communities and claims
Extract entities and relations from your documents, group them into community reports, and answer broad or specific questions with Global Search and DRIFT.
Light-touch GraphRAG over your own document text — no dedicated graph database or offline clustering service. It's a companion to assistants: the assistant blends entity neighbours and community reports into its answers when relevant, and this page's operations are how those graphs get built and can also be queried directly.
Every operation needs a full key and, apart from the plain reads and deletes, is metered from the credit wallet (see credits). listGraphEntities is the one graph read a search key can reach directly (see keys and scopes).
Extract entities and relations
generateGraphEntities — POST /collections/{collectionName}/graph/entities/generate — reads text_fields off each of up to 50 document_ids, asks a model for the named entities it mentions and the relations between them, and upserts them:
await client.graph.generateGraphEntities({
collectionName: "products",
body: { document_ids: ["42", "43"], text_fields: ["description", "specs"] },
});An entity already known by the exact same name gets this document added to its source_doc_ids instead of a duplicate row. A new name that doesn't match exactly is still resolved semantically against the collection's existing entities of the same type by embedding similarity — "De Walt" close enough to "DeWalt" is folded in as an alias rather than becoming a second entity. Structured factual assertions ("claims") extracted alongside the entities — capability, certification, compatibility, pricing, whatever the text supports — are stored too.
| Operation | Endpoint |
|---|---|
listGraphEntities | GET /collections/{collectionName}/graph/entities — most recently updated first |
deleteGraphEntity | DELETE /graph/entities/{entityId} |
listGraphClaims | GET /collections/{collectionName}/graph/claims — filter with subject_id |
deleteGraphClaim | DELETE /graph/claims/{claimId} |
A claim's status (confirmed, suspected, disputed, unverified) reflects how certain the source text is, not the model's confidence in having read it correctly.
This step is human-triggered and incremental by design, not scheduled — extraction is the expensive part, so nothing runs on its own. Re-run it as you index new documents or want more of the catalogue covered.
Group entities into communities
generateGraphCommunities — POST /collections/{collectionName}/graph/communities/generate — groups connected entities (plain connected-components, not Leiden) into a hierarchy: level 0 is the finest grouping, each higher level a coarser merge of the level below, up to max_levels. For every group of at least min_size entities at every level, a model writes a short title and summary, embedded for semantic retrieval:
await client.graph.generateGraphCommunities({
collectionName: "products",
body: { min_size: 3, max_levels: 3 },
});Re-run it after generateGraphEntities adds enough entities to change the shape of the graph — a run replaces the collection's existing reports. listGraphCommunities (GET /collections/{collectionName}/graph/communities) lists them, most recent first; deleteGraphCommunity (DELETE /graph/communities/{communityId}) removes one.
Broad questions with Global Search
globalSearchGraph — POST /collections/{collectionName}/graph/global-search — is GraphRAG's map-reduce: every community report at level (default: the coarsest generated, for the fewest and broadest reports) gets one model call asking for the points it offers toward question, each scored 0–100 for relevance (the "map" step, run in parallel, capped at max_communities reports chosen by embedding similarity when there are more). Every point above a relevance floor feeds one final "reduce" call that synthesizes the answer:
const result = await client.graph.globalSearchGraph({
collectionName: "products",
body: { question: "What kinds of drills do we carry and how do they differ?", max_communities: 10 },
});
// result.answer, result.communities_considered, result.sourcesUse it for "how does this all connect" questions too broad for one document's context.
Specific questions with DRIFT
driftSearchGraph — POST /collections/{collectionName}/graph/drift-search — runs a Global Search primer over level's reports (max_communities of them) to get an intermediate answer plus follow-up questions the reports alone can't answer. Each of the first max_follow_ups follow-ups then gets its own Local Search — the entities closest to it by embedding, their one-hop neighbours, and any claims about them — and a final call synthesizes the primer with every follow-up's local answer:
const result = await client.graph.driftSearchGraph({
collectionName: "products",
body: { question: "Which drill is best for concrete, and what do I need with it?", max_follow_ups: 3 },
});
// result.answer, result.primer_answer, result.follow_upsReach for DRIFT over Global Search when the question has a specific, narrow answer (a single product recommendation) that broad community summaries won't contain on their own; reach for Global Search when the question is genuinely about the whole catalogue.
Cost
Extraction and search each run one or more model calls and are charged from the credit wallet: entity and claim extraction per document processed, community reports per community summarized, Global Search per community report mapped plus one reduce call, DRIFT per primer call, per follow-up answered and one reduce call. See credits.
Media, image search and embeddings
Upload a product image, get a multilingual embedding written into a document, search by image or by meaning, and embed text with the same model.
Graph search (GraphRAG)
Extract entities and claims from a collection's documents, cluster them into community reports, and answer broad questions with global search and DRIFT search.