Amazon Neptune: Graph Memory for Code Dependency Reasoning in Coding Agents

2 views

Vector RAG is great until your coding agent needs to answer “what breaks if I rename AuthService.validate?” Embedding neighbors will surface similar comments; they will not reliably walk callers, callees, and package edges. Amazon Neptune gives you a managed property graph (or RDF) where those relationships are first-class — agents issue Gremlin/openCypher traversals as tools, not as hope. Distinct from OpenSearch Serverless semantic scratch memory (similarity over blobs) and GraphRAG for call graphs (bootcamp pattern): here we wire Neptune as the durable graph store behind coding-agent tools with IAM, VPC, and incremental ingest.

⚡ TL;DR: Index repo call graphs + package deps into Neptune (property graph), expose traverse_callers / impact_of_symbol / packages_depending_on as Bedrock Converse tools, keep embeddings for prose in Knowledge Bases / OpenSearch, and refresh edges on CI with idempotent upserts. Related: Bedrock Knowledge Bases, Step Functions agent graphs, MemoryDB session state, EFS shared workspaces.

Why flat chunks fail dependency questions

Coding-agent failure modes that scream “you needed a graph”:

  1. Blast-radius blind — agent edits a shared util; tests fail three packages away
  2. CVE triage theater — agent finds lodash@4.17.15 in one lockfile and misses five transitive paths
  3. Rename hallucinations — agent “updates all callers” by grepping strings, misses dynamic imports
  4. Architecture lies — agent claims service A does not call B because no shared file content matched
Store Strength Weak for
OpenSearch / KB vectors Prose, docs, similar code Exact edge walks
ElastiCache / MemoryDB Hot session scratch Multi-hop typed edges at scale
DynamoDB adjacency lists Simple 1–2 hop Deep traversals + graph algos
Neptune Multi-hop, filters on edge props Full-text prose search alone

❌ Dumping the whole AST as text into RAG and asking the model to “reason about dependencies.”

Model the coding graph (property graph)

Keep the schema boring and agent-friendly:

(:File {path, lang, repo, commit})
(:Symbol {fqn, kind, file_path, line_start, line_end})
(:Package {name, version, ecosystem})  // npm, pypi, maven
(:Service {name, team})

(:Symbol)-[:DEFINED_IN]->(:File)
(:Symbol)-[:CALLS {static:true|false}]->(:Symbol)
(:File)-[:IMPORTS]->(:File)
(:Package)-[:DEPENDS_ON {scope:prod|dev}]->(:Package)
(:Service)-[:OWNS]->(:File)
gremlin
// ✅ upsert pattern: merge vertex by stable id (repo:path:fqn)
g.V().has('Symbol','id','acme/auth:AuthService.validate')
  .fold()
  .coalesce(
    unfold(),
    addV('Symbol')
      .property('id','acme/auth:AuthService.validate')
      .property('fqn','AuthService.validate')
      .property('kind','method')
      .property('repo','acme')
  )
cypher
// ✅ openCypher: impact radius of a symbol (2 hops callers)
MATCH (s:Symbol {id: $symbolId})<-[:CALLS*1..2]-(caller:Symbol)
RETURN DISTINCT caller.fqn AS caller, caller.file_path AS path
LIMIT 200

Provision Neptune for agent workloads

bash
# ✅ Neptune cluster in private subnets; agents reach it via VPC
aws neptune create-db-cluster \
  --db-cluster-identifier coding-agent-graph \
  --engine neptune \
  --engine-version 1.3.2.0 \
  --vpc-security-group-ids sg-agent-data \
  --db-subnet-group-name agent-data-subnets \
  --storage-encrypted \
  --enable-cloudwatch-logs-exports audit

aws neptune create-db-instance \
  --db-instance-identifier coding-agent-graph-a \
  --db-instance-class db.r5.large \
  --engine neptune \
  --db-cluster-identifier coding-agent-graph

Put the writer endpoint in Secrets Manager / SSM; never bake it into prompts. Pair egress with Network Firewall so sandboxes cannot exfiltrate the graph over the public internet.

Agent tools: traverse, don’t dump

Expose narrow tools. Dumping 50k vertices into the context window is how you burn tokens and invent edges.

python
# ✅ tool: impact_of_symbol — bounded traversal for Converse toolConfig
import json
from gremlin_python.driver import client, serializer

GREMLIN = client.Client(
    "wss://coding-agent-graph.cluster-xxxx.us-east-1.neptune.amazonaws.com:8182/gremlin",
    "g",
    message_serializer=serializer.GraphSONSerializersV2d0(),
)

TOOL_SPEC = {
    "name": "impact_of_symbol",
    "description": "Return callers of a symbol up to max_hops (default 2). Use before renames/deletes.",
    "inputSchema": {
        "type": "object",
        "properties": {
            "symbol_id": {"type": "string"},
            "max_hops": {"type": "integer", "minimum": 1, "maximum": 3},
            "limit": {"type": "integer", "minimum": 1, "maximum": 200},
        },
        "required": ["symbol_id"],
    },
}

def impact_of_symbol(symbol_id: str, max_hops: int = 2, limit: int = 100) -> str:
    # ❌ g.V().repeat(in('CALLS')).emit() without hop/limit caps
    q = (
        f"g.V().has('Symbol','id',symbol_id)"
        f".repeat(__.in('CALLS')).times({int(max_hops)}).emit()"
        f".dedup().limit({int(limit)})"
        f".project('fqn','path').by('fqn').by('file_path')"
    )
    rows = GREMLIN.submit(q, {"symbol_id": symbol_id}).all().result()
    return json.dumps({"symbol_id": symbol_id, "callers": rows, "truncated": len(rows) >= limit})

Wire the tool through Verified Permissions so tenant A cannot traverse tenant B’s repo property. Orchestrate multi-step “analyze → patch → re-traverse” with Step Functions.

Incremental ingest from CI (not nightly full reloads)

python
# ✅ CodeBuild / GitHub Action step after unit tests
# Extract CALLS edges with your AST walker; upsert by (from_id, to_id)
def upsert_call_edge(g, src: str, dst: str, static: bool, commit: str):
    g.V().has("Symbol", "id", src).as_("a").V().has("Symbol", "id", dst).as_("b") \
        .coalesce(
            __.select("a").outE("CALLS").where(__.inV().has("id", dst)),
            __.select("a").addE("CALLS").to("b"),
        ) \
        .property("static", static) \
        .property("commit", commit) \
        .iterate()
Approach Pros Cons
Full rebuild nightly Simple Stale mid-day; long writer lock
Per-PR delta upsert Fresh for agents Need delete/tombstone for removed symbols
Dual-write from indexer Lambda Near real-time Harder consistency

Prefer delta upserts with a commit property; soft-delete symbols missing from the tip commit during a reconcile job.

Hybrid memory: Neptune + vectors + session

Do not force Neptune to be your only memory:

  • Neptune — typed dependency / call / ownership edges
  • Bedrock Knowledge Bases / OpenSearch — docs, READMEs, ADRs (KB monorepo RAG)
  • OpenSearch Serverless scratch — ephemeral semantic notes mid-turn
  • MemoryDB / ElastiCache — dialogue + tool-result cache
  • EFS — checkout workspace for the sandbox

❌ Replacing Knowledge Bases with Neptune and stuffing markdown into vertex properties as a “graph RAG” shortcut.

Cost, ops, and failure modes

Issue Symptom Mitigation
Hot writer Timeout on bulk ingest Bulk loader to S3 → Neptune; scale writer
Runaway traversal Agent latency cliff Hard hop/limit in tool; timeout in Gremlin
Stale edges Wrong blast radius CI upsert + reconcile; show commit in tool output
Cross-tenant leak Wrong repo in results Partition by repo/tenant + Cedar authZ
Prompt stuffing Model invents edges Return structured JSON only; forbid free-form dumps
bash
# ✅ CloudWatch: track Gremlin errors / throttles
aws cloudwatch put-metric-alarm \
  --alarm-name neptune-coding-agent-gremlin-errors \
  --namespace AWS/Neptune \
  --metric-name GremlinRequestsPerSec \
  --dimensions Name=DBClusterIdentifier,Value=coding-agent-graph \
  --statistic Average --period 60 --threshold 1 \
  --comparison-operator LessThanThreshold \
  --evaluation-periods 5 \
  --treat-missing-data notBreaching

(Tune alarms to error/throttle metrics available in your engine version — the point is: alert when agent tools go silent.)

Production checklist

  • [ ] Neptune in private VPC; IAM + SigV4; no public endpoint for agent tools
  • [ ] Schema documented: Symbol / File / Package / CALLS / DEPENDS_ON
  • [ ] Tools are hop- and limit-bounded; outputs include truncation flags
  • [ ] CI delta ingest with commit provenance on edges
  • [ ] Tenant/repo filters enforced in query and Cedar/IAM
  • [ ] Hybrid: vectors for prose, Neptune for edges — not one store for everything
  • [ ] Backup / snapshot policy; restore drill quarterly
  • [ ] Trace tool hops with ADOT
  • [ ] Cost tags workload=coding-agent, store=neptune

FAQ

Q: Neptune Analytics vs Neptune DB?
A: Use Neptune DB for continuous transactional upserts from CI and low-latency agent tools. Neptune Analytics shines for heavy graph algorithms / notebooks — optional batch jobs, not the hot tool path.

Q: Why not Neo4j self-managed on EC2?
A: You can — but Neptune buys you managed HA, IAM integration, and fewer “who patched the graph server at 2am” pages. Self-manage only if you need features Neptune lacks.

Q: Gremlin or openCypher?
A: Pick one for the agent tool layer. Mixed dialects in prompts confuse both humans and models. openCypher is often easier for SQL-minded engineers; Gremlin is flexible for dynamic traversals.

Related reading

Store the edges. Let the model narrate; let Neptune prove the blast radius.

Last updated on October 3, 2026

Deep-dive PDF

Get the expanded guide for this post — extra diagrams-style checklists, failure modes, and a production walkthrough. Free when you subscribe to CheatCoders.

Already subscribed? or open the subscribe page.


Discover more from CheatCoders

Subscribe to get the latest posts sent to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a comment

No account needed. Name and email are optional.