К основному содержанию
скилл CX Codex

neo4j-driver-go-skill — скилл для Claude Code: как установить

Скилл учит ИИ-агента работать с библиотекой neo4j-go-driver версии 6: создавать пул соединений драйвера и настраивать транзакции.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add neo4j-contrib/neo4j-skills --skill neo4j-driver-go-skill -a claude-code
Открыть на GitHub

Что делает neo4j-driver-go-skill

Скилл даёт правила работы с библиотекой github.com/neo4j/neo4j-go-driver/v6/neo4j. Ассистент учится инициализировать пул соединений через neo4j.NewDriver и проверять доступность базы вызовом VerifyConnectivity. Пул создаётся один на всё приложение. Поддерживаются схемы подключения neo4j:// и защищённая neo4j+s:// для кластера Aura.

Внутри собраны шаблоны выполнения запросов через neo4j.ExecuteQuery и потокового чтения в ExecuteRead. С версии драйвера 6.2.0 поддерживается передача структур Go в параметры запросов Cypher. Ошибки тоже типизированы. Команды вроде CALL IN TRANSACTIONS завершатся сбоем внутри управляемых транзакций, поэтому для них инструкция предписывает использовать session.Run.

Составлять сам синтаксис Cypher скилл не учит. Для генерации запросов к графу нужен отдельный neo4j-cypher-skill. Также в инструкциях нет шагов миграции со старых версий драйвера.

Какие задачи решает

  • Настроить жизненный цикл neo4j.Driver с пулом соединений в сервисе на Go
  • Выполнять запросы к Neo4j через ExecuteQuery с безопасной передачей параметров
  • Организовать потоковую обработку записей через ManagedTransaction без буферизации
  • Разделять сетевые сбои ConnectivityError и ошибки базы данных Neo4jError

Примеры запросов агенту

  • Напиши функцию подключения к базе Neo4j на Go через neo4j.NewDriver с проверкой связи
  • Сделай выборку данных через ExecuteQuery с ReadersRouting и передачей структуры в параметры
  • Как правильно настроить чтение большого объёма данных через ExecuteRead в сессии Go?

Как установить neo4j-driver-go-skill

1Через Skills CLI (Vercel)

npx skills add neo4j-contrib/neo4j-skills --skill neo4j-driver-go-skill -a claude-code

2Вручную: положить файлы

~/.claude/skills/neo4j-driver-go-skill/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/neo4j-driver-go-skill/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о neo4j-driver-go-skill

Как установить neo4j-driver-go-skill в Claude Code?

Выполните команду npx skills add neo4j-contrib/neo4j-skills --skill neo4j-driver-go-skill -a claude-code.

Что делает neo4j-driver-go-skill?

Он обучает ассистента работе с Neo4j Go Driver v6: инициализации пула соединений, вызовам ExecuteQuery, режимам транзакций и типизированной обработке ошибок.

Поможет ли этот скилл написать Cypher-запрос?

Нет, скилл сфокусирован только на интеграции драйвера в Go. Для синтаксиса и оптимизации Cypher используется neo4j-cypher-skill.

Исходный текст

SKILL.md · MIT
---
name: neo4j-driver-go-skill
description: Covers the Neo4j Go Driver v6 — driver lifecycle, ExecuteQuery, managed and
  explicit transactions, session config, error handling, data type mapping, and connection
  tuning. Use when writing Go code that connects to Neo4j, setting up NewDriver or ExecuteQuery,
  debugging sessions/transactions/result handling, or working with neo4j-go-driver v5→v6 migration.
  Triggers on NewDriver, ExecuteQuery, SessionConfig, ManagedTransaction, neo4j-go-driver.
  Does NOT handle Cypher query authoring — use neo4j-cypher-skill.
  Does NOT cover driver version migration steps — use neo4j-migration-skill.
version: 1.0.7
allowed-tools: Bash WebFetch
---

## When to Use
- Writing Go code that connects to Neo4j
- Setting up `neo4j.NewDriver()`, `ExecuteQuery()`, or session/transaction patterns
- Debugging connection errors, result iteration, type assertions, causal consistency

## When NOT to Use
- **Writing/optimizing Cypher** → `neo4j-cypher-skill`
- **v5→v6 migration steps** → `neo4j-migration-skill`

---

## Installation

```bash
go get github.com/neo4j/neo4j-go-driver/v6
```

Import: `github.com/neo4j/neo4j-go-driver/v6/neo4j`

**v5→v6 rename** (deprecated aliases still compile, remove before v7):

| v5 | v6 |
|----|----|
| `neo4j.NewDriverWithContext(...)` | `neo4j.NewDriver(...)` |
| `neo4j.DriverWithContext` | `neo4j.Driver` |

---

## Environment Variables

```go
import "os"

uri      := getEnv("NEO4J_URI",      "neo4j://localhost:7687")
user     := getEnv("NEO4J_USERNAME", "neo4j")
password := getEnv("NEO4J_PASSWORD", "")
database := getEnv("NEO4J_DATABASE", "neo4j")

func getEnv(key, fallback string) string {
    if v := os.Getenv(key); v != "" { return v }
    return fallback
}
```

Use [godotenv](https://github.com/joho/godotenv) to load `.env` in dev: `godotenv.Load()`. `.env` in `.gitignore`.

---

## Driver Lifecycle

One `Driver` per application. Goroutine-safe, connection-pooled, expensive to create.

```go
func NewNeo4jDriver(uri, user, password string) (neo4j.Driver, error) {
    driver, err := neo4j.NewDriver(
        uri, // "neo4j+s://xxx.databases.neo4j.io" for Aura
        neo4j.BasicAuth(user, password, ""),
    )
    if err != nil {
        return nil, fmt.Errorf("create driver: %w", err)
    }
    ctx := context.Background()
    if err := driver.VerifyConnectivity(ctx); err != nil {
        driver.Close(ctx)
        return nil, fmt.Errorf("verify connectivity: %w", err)
    }
    return driver, nil
}

// In main / app teardown:
defer driver.Close(ctx)
```

❌ Never create driver per-request. Create once at startup; share across goroutines.

URI schemes: `neo4j+s://` (Aura/TLS+routing), `neo4j://` (plain+routing), `bolt+s://` (TLS+single), `bolt://` (plain+single).

---

## Choosing the Right API

| API | Use when | Auto-retry | Lazy results |
|-----|----------|:----------:|:------------:|
| `neo4j.ExecuteQuery()` | Most queries — simple default | ✅ | ❌ eager |
| `session.ExecuteRead/Write()` | Large result sets / streaming | ✅ | ✅ |
| `session.BeginTransaction()` | Spans multiple functions / ext coordination | ❌ | ✅ |
| `session.Run()` | `CALL IN TRANSACTIONS` / auto-commit only | ❌ | ✅ |

`CALL { … } IN TRANSACTIONS` and `USING PERIODIC COMMIT` manage their own transactions — use `session.Run()`. They fail inside managed transactions.

---

## ExecuteQuery (Recommended Default)

Manages sessions, transactions, retries, and bookmarks automatically.

```go
result, err := neo4j.ExecuteQuery(ctx, driver,
    `MATCH (p:Person {name: $name})-[:KNOWS]->(friend)
     RETURN friend.name AS name`,
    map[string]any{"name": "Alice"},
    neo4j.EagerResultTransformer,
    neo4j.ExecuteQueryWithDatabase("neo4j"),       // always specify
    neo4j.ExecuteQueryWithReadersRouting(),         // for read queries
)
if err != nil {
    return fmt.Errorf("query people: %w", err)
}

for _, record := range result.Records {
    name, _ := record.Get("name")
    fmt.Println(name)
}
fmt.Println(result.Summary.Counters().NodesCreated())
```

Key options:
```go
neo4j.ExecuteQueryWithDatabase("mydb")          // required for performance
neo4j.ExecuteQueryWithReadersRouting()           // route reads to replicas
neo4j.ExecuteQueryWithImpersonatedUser("jane")  // impersonate
neo4j.ExecuteQueryWithoutBookmarkManager()       // opt out of causal consistency
```

❌ Never concatenate user input into query strings. Always use `map[string]any` parameters.

Struct parameters [v6.2.0+, Object Mapping preview] — a struct (or pointer) in `params` is sent as a Cypher map; same rules in `Session.Run`, `ManagedTransaction.Run`, `ExplicitTransaction.Run`:
```go
type Person struct {
    Name     string `neo4j:"name"`
    Age      int    `neo4j:"age,omitempty"`  // zero value dropped
    Internal string `neo4j:"-"`              // never sent
}
_, err := neo4j.ExecuteQuery(ctx, driver,
    "MERGE (p:Person {name: $person.name}) SET p += $person",
    map[string]any{"person": Person{Name: "Alice", Age: 30}},
    neo4j.EagerResultTransformer,
    neo4j.ExecuteQueryWithDatabase("neo4j"),
)
```

---

## Managed Transactions (Session-Based)

Use for lazy streaming (large result sets) or callback-level control.

```go
session := driver.NewSession(ctx, neo4j.SessionConfig{
    DatabaseName: "neo4j", // always specify
    AccessMode:   neo4j.AccessModeRead,
})
defer session.Close(ctx)

result, err := session.ExecuteRead(ctx,
    func(tx neo4j.ManagedTransaction) (any, error) {
        res, err := tx.Run(ctx,
            `MATCH (p:Person) RETURN p.name AS name LIMIT $limit`,
            map[string]any{"limit": 100},
        )
        if err != nil {
            return nil, err
        }
        var names []string
        for res.Next(ctx) { // lazy — don't Collect() on large sets
            name, _ := res.Record().Get("name")
            names = append(names, name.(string))
        }
        return names, res.Err()
    },
)
```

❌ No side effects in callback — retried on transient failures.
`ExecuteRead` → replicas. `ExecuteWrite` → cluster leader.

---

## Explicit Transactions

Use when transaction work spans multiple functions or requires external coordination.

```go
session := driver.NewSession(ctx, neo4j.SessionConfig{DatabaseName: "neo4j"})
defer session.Close(ctx)

tx, err := session.BeginTransaction(ctx)
if err != nil {
    return err
}
if err := doPartA(ctx, tx); err != nil {
    tx.Rollback(ctx)
    return err
}
if err := doPartB(ctx, tx); err != nil {
    tx.Rollback(ctx)
    return err
}
return tx.Commit(ctx)
```

❌ Not auto-retried. Caller handles retry. Prefer managed transactions unless you need explicit control.

---

## Error Handling

```go
result, err := neo4j.ExecuteQuery(...)
if err != nil {
    var neo4jErr *neo4j.Neo4jError
    if errors.As(err, &neo4jErr) {
        slog.Error("database error", "code", neo4jErr.Code, "msg", neo4jErr.Msg)
    }
    var connErr *neo4j.ConnectivityError
    if errors.As(err, &connErr) {
        slog.Error("connectivity error", "err", connErr)
    }
    return fmt.Errorf("execute query: %w", err)
}
```

Helpers:
```go
neo4j.IsNeo4jError(err)                // server-side Cypher/database error
neo4j.IsTransactionExecutionLimit(err) // managed tx retries exhausted
```

In managed tx callback: return error → driver retries if transient.
`ConnectivityError` at startup: check URI scheme, credentials, firewall.

---

## Data Types

| Cypher | Go |
|--------|----|
| `Integer` | `int64` |
| `Float` | `float64` |
| `String` | `string` |
| `Boolean` | `bool` |
| `List` | `[]any` |
| `Map` | `map[string]any` |
| `Node` | `neo4j.Node` |
| `Relationship` | `neo4j.Relationship` |
| `Path` | `neo4j.Path` |
| `Date` | `neo4j.Date` |
| `DateTime` | `neo4j.Time` |
| `Duration` | `neo4j.Duration` |
| `UUID` | `neo4j.UUID` (= `dbtype.UUID`, `[16]byte` RFC 9562) — v6.2.0+, Bolt 6.1; parse with `dbtype.ParseUUID(s)`, render with `.String()` |
| `null` | `nil` |

```go
// Typed extraction (v6+, preferred):
neo4j.GetRecordValue[string](record, "name")

// Manual extraction:
rawAge, ok := record.Get("age")
if !ok { return errors.New("missing 'age' field") }
age := rawAge.(int64) // Neo4j integers → int64

// Node access:
rawNode, _ := record.Get("p")
node := rawNode.(neo4j.Node)
name := node.Props["name"].(string)
labels := node.Labels // []string
```

❌ Always check `ok` from `record.Get()` before type-asserting — panics on missing key.
❌ After lazy `for res.Next(ctx)` loop, always check `res.Err()`.

---

## Key Patterns

### Context — always propagate

```go
ctx, cancel := context.WithTimeout(parentCtx, 5*time.Second)
defer cancel()
// pass ctx to all driver calls
```

`context.Background()` has no deadline — slow queries block indefinitely.

### Batching Writes

```go
// Bad: one transaction per record
for _, item := range items {
    neo4j.ExecuteQuery(ctx, driver, writeQuery, item, ...)
}

// Good: UNWIND batch in one transaction
neo4j.ExecuteQuery(ctx, driver,
    `UNWIND $items AS item
     MERGE (n:Node {id: item.id})
     SET n += item`,
    map[string]any{"items": items},
    neo4j.EagerResultTransformer,
    neo4j.ExecuteQueryWithDatabase("neo4j"),
)
```

### Generic Helpers (v6+)

Prefer type-safe helpers over manual assertions:

```go
// GetRecordValue[T] — extract + cast in one call
name, isNil, err := neo4j.GetRecordValue[string](record, "name")
// isNil=true when OPTIONAL MATCH returned null; err != nil when key absent or wrong type

// CollectTWithContext — map all records to a slice
people, err := neo4j.CollectTWithContext(ctx, result, func(record *neo4j.Record) (Person, error) {
    name, _, err := neo4j.GetRecordValue[string](record, "name")
    age, _, _   := neo4j.GetRecordValue[int64](record, "age")
    return Person{Name: name, Age: int(age)}, err
})

// SingleTWithContext — expect exactly one record (error if 0 or 2+)
person, err := neo4j.SingleTWithContext(ctx, result, func(record *neo4j.Record) (Person, error) {
    name, _, _ := neo4j.GetRecordValue[string](record, "name")
    return Person{Name: name}, nil
})

// GetProperty — typed property from Node or Relationship
node, _, _ := neo4j.GetRecordValue[neo4j.Node](record, "p")
nameVal, err := neo4j.GetProperty[string](node, "name")
```

Result mapping [v6.3.0+, Object Mapping preview] — map records onto `neo4j`-tagged structs (same tags as struct parameters):
```go
type Person struct {
    Name string `neo4j:"name"`
    Age  int    `neo4j:"age"`   // INTEGER converted; lossy conversion → error, not truncation
}

// EagerResult from ExecuteQuery
res, err := neo4j.ExecuteQuery(ctx, driver,
    "MATCH (p:Person) RETURN p.name AS name, p.age AS age LIMIT 25",
    nil, neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase("neo4j"))
people, err := neo4j.CollectRecordsAs[Person](res.Records)

// Streaming Result inside a transaction
all, err := neo4j.CollectAs[Person](ctx, result)      // all records
person, err := neo4j.SingleAs[Person](ctx, result)    // exactly one record
p, err := neo4j.As[Person](record)                    // single record
```
Mapping rules: one column holding a node, relationship, or map → its properties map to fields; otherwise columns map by name. Missing/null → zero value; extra columns ignored.

### Spatial Types

```go
// 2D Cartesian (SRID 7203), 3D Cartesian (SRID 9157)
pt2d := neo4j.Point2D{X: 1.23, Y: 4.56, SpatialRefId: 7203}
pt3d := neo4j.Point3D{X: 1.23, Y: 4.56, Z: 7.89, SpatialRefId: 9157}

// 2D WGS-84 (SRID 4326), 3D WGS-84 (SRID 4979)
london := neo4j.Point2D{X: -0.118092, Y: 51.509865, SpatialRefId: 4326}
shard  := neo4j.Point3D{X: -0.0865, Y: 51.5045, Z: 310, SpatialRefId: 4979}

// Pass as parameter
result, err := neo4j.ExecuteQuery(ctx, driver,
    "CREATE (p:Place {location: $loc})",
    map[string]any{"loc": london},
    neo4j.EagerResultTransformer,
    neo4j.ExecuteQueryWithDatabase("neo4j"),
)

// Read from result — assert to Point2D or Point3D
raw, _ := record.Get("location")
if p2d, ok := raw.(neo4j.Point2D); ok {
    fmt.Printf("lon=%f lat=%f srid=%d\n", p2d.X, p2d.Y, p2d.SpatialRefId)
}

// Distance (same SRID only)
result, _ = neo4j.ExecuteQuery(ctx, driver,
    "RETURN point.distance($p1, $p2) AS distance",
    map[string]any{"p1": pt2d, "p2": neo4j.Point2D{X: 10, Y: 10, SpatialRefId: 7203}},
    neo4j.EagerResultTransformer, neo4j.ExecuteQueryWithDatabase("neo4j"),
)
dist, _ := result.Records[0].Get("distance")
fmt.Println(dist.(float64))
```

### Always Specify Database

```go
neo4j.ExecuteQueryWithDatabase("neo4j")    // in ExecuteQuery
neo4j.SessionConfig{DatabaseName: "neo4j"} // in sessions
```

Omitting costs a network round-trip per call to resolve home database.

### Causal Consistency

`ExecuteQuery` manages bookmarks automatically — no action needed for sequential calls.
Cross-session (parallel workers): combine bookmarks explicitly — see [references/repository-pattern.md](references/repository-pattern.md).

---

## Common Errors

| Error / Symptom | Cause | Fix |
|-----------------|-------|-----|
| `ConnectivityError` at startup | URI wrong / TLS mismatch / firewall | Check scheme (`neo4j+s://` for Aura), credentials, port 7687 |
| `ConnectivityError` mid-run | Pool exhausted | Increase `MaxConnectionPoolSize`; check for leaked sessions |
| Panic on type assertion | `record.Get()` returned nil/wrong type | Use `neo4j.GetRecordValue[T]()` or check `ok` first |
| `res.Err()` non-nil after loop | Network error mid-stream | Handle error; re-run transaction |
| Callback retried unexpectedly | Side effect inside managed tx | Move side effects outside callback |
| Context deadline exceeded | No timeout on context | Use `context.WithTimeout` |
| 0 results, query looks correct | Wrong `DatabaseName` | Always set `DatabaseName` in config |
| `CALL IN TRANSACTIONS` fails | Run inside managed tx | Use `session.Run()` (auto-commit) |

---

## References

Load on demand:
- [references/advanced-config.md](references/advanced-config.md) — connection pool tuning, custom address resolver, notification config, Bolt logging, auth options, URI scheme table, deprecated result-summary accessors (`Profile()` → `QueryProfile()`)
- [references/repository-pattern.md](references/repository-pattern.md) — repository wrapper pattern, cross-session causal consistency with bookmarks

## WebFetch

| Need | URL |
|------|-----|
| Go driver manual | `https://neo4j.com/docs/go-manual/current/` |
| API reference | `https://pkg.go.dev/github.com/neo4j/neo4j-go-driver/v6/neo4j` |

---

## Checklist
- [ ] One driver created at startup; shared across goroutines; `defer driver.Close(ctx)`
- [ ] `driver.VerifyConnectivity(ctx)` called at startup
- [ ] `DatabaseName` set in all `SessionConfig` / `ExecuteQueryWithDatabase`
- [ ] `context.WithTimeout` used for production queries
- [ ] `map[string]any` parameters used — no string interpolation
- [ ] `ExecuteQueryWithReadersRouting()` on read-only `ExecuteQuery` calls
- [ ] `res.Err()` checked after lazy `for result.Next(ctx)` loop
- [ ] Type assertions guarded (use `GetRecordValue[T]` or check `ok`)
- [ ] No side effects inside managed transaction callbacks
- [ ] `session.Run()` used for `CALL IN TRANSACTIONS` / auto-commit queries
- [ ] Sessions closed with `defer session.Close(ctx)`

© neo4j-contrib · MIT · neo4j-contrib/neo4j-skills

Похожие скиллы

Все скиллы по теме «Данные и базы» →
xlsx официальный anthropics Работает с табличными файлами: создаёт, читает, правит и преобразует книги. Подходит, когда итогом должен стать файл Excel или другой табличный формат. 187 223установок google-agents-cli-observability официальный Google Помогает настроить трассировку и сбор данных о работе ИИ-агентов, включая агентов на ADK. Пригодится, когда нужно разбирать выполнение запросов или наблюдать за агентом после развёртывания. CX Codex +1 511 300установок caveman-evidence-review JuliusBrussee Скилл читает данные Caveman Cloud о расходах LLM, трассах и маршрутизации. Подходит для проверки того, куда уходит бюджет проекта. CX Codex +1 104 500установок migration JuliusBrussee Скилл задаёт правила безопасных миграций схем, данных и API с обязательным откатом. Пригодится при изменениях, где нельзя терять данные или ломать совместимость. CX Codex +1 103 900установок performance-optimization addyosmani Скилл для агентов ИИ-кодинга: сначала замеряет, потом чинит узкое место — от Core Web Vitals до N+1 запросов и индексов в базе. CX Codex +1 65 200установок supabase официальный supabase Скилл помогает настраивать базу данных, аутентификацию и RLS в Supabase без скрытых дыр в безопасности. CX Codex GP ChatGPT 8установок

Из того же набора22

neo4j-aura-graph-analytics-skill Скилл для запуска алгоритмов GDS в серверлесс-сессиях Aura Graph Analytics: проекции графа, оценка памяти, асинхронные задачи и запись результатов обратно. CX Codex +1 798установок neo4j-aura-provisioning-skill Создаёт и ведёт инстансы Neo4j Aura через aura-cli или REST API: пауза, возобновление, изменение размера, удаление, выгрузка пароля. CX Codex +1 789установок neo4j-kafka-skill Настраивает коннектор Neo4j для Kafka в обе стороны и нативный CDC API. Пригодится, когда события Kafka нужно писать в граф или транслировать изменения Neo4j в топики. CX Codex +1 772установок neo4j-driver-java-skill Подсказывает агенту, как подключить Java или Kotlin к Neo4j: драйвер, сессии, транзакции, пул соединений. CX Codex +1 770установок neo4j-aura-agent-skill Скилл ведёт Claude по REST API v2beta1: создаёт агентов Neo4j Aura, настраивает инструменты и вызывает их запросами на естественном языке. CX Codex +1 760установок neo4j-driver-dotnet-skill Помогает писать надёжный код на C# для Neo4j через официальный драйвер v6. Настраивает синглтон в DI, запросы ExecutableQuery и транзакции. CX Codex +1 756установок neo4j-snowflake-graph-analytics-skill Скилл для запуска графовых алгоритмов Neo4j прямо в Snowflake через SQL CALL, без выгрузки данных. Пригодится, когда таблицы уже лежат в Snowflake. CX Codex +1 752установок neo4j-nvl-skill Помогает встроить интерактивный граф Neo4j в веб-приложение через Canvas или WebGL2 и настроить жесты взаимодействия. CX Codex +1 716установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой