neo4j-genai-plugin-skill
Use Neo4j GenAI Plugin ai.text.* functions and procedures for in-Cypher
git clone --depth 1 https://github.com/neo4j-contrib/neo4j-skills /tmp/neo4j-genai-plugin-skill && cp -r /tmp/neo4j-genai-plugin-skill/neo4j-genai-plugin-skill ~/.claude/skills/neo4j-genai-plugin-skillSKILL.md
## When to Use
- Generating embeddings inside Cypher without external Python (`ai.text.embed()`)
- Batch-embedding nodes/chunks during ingestion (`ai.text.embedBatch()`)
- Calling LLMs directly in Cypher for completions or GraphRAG (`ai.text.completion()`)
- Extracting structured JSON maps from LLM inside Cypher (`ai.text.structuredCompletion()`)
- Aggregating LLM summaries over grouped rows (`ai.text.aggregateCompletion()`)
- Stateful chat sessions in Cypher (`ai.text.chat()`)
- Counting tokens or chunking text by token limit (`ai.text.tokenCount()`, `ai.text.chunkByTokenLimit()`)
## When NOT to Use
- **Python-based GraphRAG pipelines** (VectorCypherRetriever, HybridCypherRetriever) → `neo4j-graphrag-skill`
- **Vector index CREATE / kNN search / SEARCH clause** → `neo4j-vector-index-skill`
- **GDS embeddings** (FastRP, Node2Vec) → `neo4j-gds-skill`
- **Fulltext / keyword search** → `neo4j-cypher-skill`
---
## Prerequisites
**CYPHER 25 required** for all `ai.*` functions. Two ways to enable:
```cypher
// Per-query prefix (self-managed, no admin rights needed):
CYPHER 25 MATCH (n:Chunk) ...
// Per-database default (admin; applies to all sessions):
ALTER DATABASE neo4j SET DEFAULT LANGUAGE CYPHER 25
```
**Installation:**
- **Aura**: GenAI plugin enabled by default — no action needed
- **Self-managed JAR**: copy plugin JAR to `plugins/` directory
- **Docker**: `--env NEO4J_PLUGINS='["genai"]'`
---
## Provider Config Quick Reference
All `ai.text.*` functions accept a `configuration :: MAP` as last argument.
| Provider string | Required keys | Notes |
|---|---|---|
| `'openai'` | `token`, `model` | `token` = OpenAI API key |
| `'azure-openai'` | `token`, `resource`, `model` | `token` = OAuth2 bearer; `resource` = Azure resource name |
| `'vertexai'` | `model`, `project`, `region`, `token` or `apiKey` | `publisher` defaults to `'google'` |
| `'bedrock-titan'` | `model`, `region`, `accessKeyId`, `secretAccessKey` | Embedding only |
| `'bedrock-nova'` | `model`, `region`, `accessKeyId`, `secretAccessKey` | Completion only |
Optional for all: `vendorOptions :: MAP` passes provider-specific extras (e.g. `{ dimensions: 1024 }` for OpenAI).
❌ Never hardcode API key literals. ✅ Always use `$param` passed via driver parameters dict.
Full provider config table → [references/providers.md](references/providers.md)
---
## Embedding
### Single embed [2025.11]
```cypher
CYPHER 25
MATCH (c:Chunk)
WHERE c.embedding IS NULL
WITH c
CALL {
WITH c
SET c.embedding = ai.text.embed(c.text, 'openai', {
token: $openaiKey,
model: 'text-embedding-3-small'
})
} IN TRANSACTIONS OF 500 ROWS
```
`ai.text.embed()` returns `VECTOR` — directly storable and queryable in a vector index.
### Batch embed procedure [2025.11]
```cypher
CYPHER 25
MATCH (c:Chunk) WHERE c.embedding IS NULL
WITH collect(c) AS chunks
UNWIND chunks AS c
WITH c.text AS text, c AS node
CALL ai.text.embedBatch(text, 'openai', { token: $openaiKey, model: 'text-embedding-3-small' })
YIELD index, resource, vector
MATCH (c:Chunk {text: resource})
SET c.embedding = vector
```
Procedure signature: `CALL ai.text.embedBatch(resource, provider, config) YIELD index, resource, vector`
### List configured embed providers
```cypher
CYPHER 25
CALL ai.text.embed.providers()
YIELD name, requiredConfigType, optionalConfigType, defaultConfig
RETURN name, requiredConfigType
```
---
## Text Completion [2025.11]
```cypher
CYPHER 25
RETURN ai.text.completion(
'Summarize: ' + $text,
'openai',
{ token: $openaiKey, model: 'gpt-4o-mini' }
) AS summary
```
Returns `STRING`.
### Aggregate completion — summarize across rows [2026.03]
```cypher
CYPHER 25
MATCH (c:Chunk)-[:PART_OF]->(a:Article {id: $articleId})
RETURN ai.text.aggregateCompletion(
c.text,
'Summarize the following article chunks in 3 sentences',
'openai',
{ token: $openaiKey, model: 'gpt-4o-mini' }
) AS summary
```
`value` parameter = each row's STRING fed to the LLM. Uses `toString()` for non-string values.
---
## Pure-Cypher GraphRAG Pattern
Embed question → vector search → graph traverse → LLM completion — all in one Cypher query:
```cypher
CYPHER 25
WITH ai.text.embed($question, 'openai', { token: $openaiKey, model: 'text-embedding-3-small' }) AS qEmbedding
CALL db.index.vector.queryNodes('chunk_embedding', 10, qEmbedding) YIELD node AS chunk, score
MATCH (chunk)<-[:HAS_CHUNK]-(article:Article)
OPTIONAL MATCH path = shortestPath((article)-[*..3]-(other:Article))
WITH chunk, article, collect(DISTINCT other.title) AS related, score
ORDER BY score DESC LIMIT 5
WITH collect(chunk.text + '\n[Source: ' + article.title + ']') AS context, $question AS question
RETURN ai.text.completion(
'Answer based on context:\n' + reduce(s='', c IN context | s + c + '\n') + '\nQuestion: ' + question,
'openai',
{ token: $openaiKey, model: 'gpt-4o-mini' }
) AS answer
```
Key insight (Bergman): shortest path between seed nodes surfaces relationships not visible from direct neighbors alone.
---
## Structured Output [2026.02]
Returns `MAP` — directly storable as node properties or used downstream in Cypher.
```cypher
CYPHER 25
MATCH (p:Product {id: $productId})
WITH p,
ai.text.structuredCompletion(
'Extract key attributes from: ' + p.description,
{
type: 'object',
properties: {
category: { type: 'string' },
tags: { type: 'array', items: { type: 'string' } },
priceRange: { type: 'string', enum: ['budget', 'mid', 'premium'] }
},
required: ['category', 'tags', 'priceRange'],
additionalProperties: false
},
'openai',
{ token: $openaiKey, model: 'gpt-4o-mini' }
) AS extracted
SET p.category = extracted.category,
p.priceRange = extracted.priceRange
WITH p, extracted.tags AS tags
UNWIND tags AS tag
MERGE (t:Tag {name: tag})
MERGE (p)-[:TAGGED]->(t)
```
### Aggregate structured completion — extract across multiple rows [2026.03]
```cypher
CYPHER 25
MATCH (:User {id: $userId})-[:ORDERED]->(o:Order)-[Authoritative reference for the neo4j-agent-memory Python package — a graph-native memory system for AI agents built on Neo4j — and for the hosted service (NAMS) at memory.neo4jlabs.com. Use this skill whenever the user mentions neo4j-agent-memory, agent memory with Neo4j, context graphs, the POLE+O model, MemoryClient/MemorySettings, the memory MCP server, or any of the framework integrations (LangChain, PydanticAI, CrewAI, AWS Strands, Google ADK, Microsoft Agent Framework, OpenAI Agents, LlamaIndex). Also use when the user mentions the hosted service at memory.neo4jlabs.com, NAMS, the Neo4j Agent Memory Service, the `nams_` API key prefix, or the hosted MCP endpoint. Also use when writing documentation, blog posts, tutorials, PRDs, or code samples for the project, when comparing agent memory approaches, or when positioning graph-native memory against vector-only approaches — even if the user doesn't explicitly name the package.
Manages Neo4j Aura Agents via the v2beta1 REST API — create, list, get, update, delete,
Serverless Aura Graph Analytics (AGA) GDS Sessions — covers GdsSessions,
Provisions and manages Neo4j Aura instances via CLI (aura-cli v1.7+) or REST API.
Use when working with Neo4j command-line tools — neo4j-cli (modern unified
Generates, optimizes, and validates Cypher 25 queries for Neo4j 2025.x and 2026.x.
Ingests unstructured and semi-structured documents into Neo4j as a knowledge graph.
Neo4j .NET Driver v6 — IDriver lifecycle, DI registration (singleton), ExecutableQuery