How to Do Graph Engineering With Opus 5 (Exact Config Inside)

@0x_rody
rody@0x_rody
132 views Jul 28, 2026 ~6 min read
Advertisement

Graph memory has one killer cost: every episode you ingest runs an extraction call, and naive setups run that at full frontier rates. Opus 5 shipped the exact levers that kill that bill.

Media image

Inside: the extraction config that bills at $0.50 instead of $5, the effort split between ingest and query, and the full routing.

Build it right and a temporal graph costs less to feed than a vector store costs to embed.

Here's the full setup 👇

Media image

Why graphs and Opus 5 fit together

A knowledge graph gives your agent memory that survives compaction: entities, relationships, and timestamps it can traverse instead of re-reading.

The catch has always been the build cost.

Every conversation and document you feed in runs an extraction pass, and at frontier rates that adds up fast.

Opus 5 changes the math on exactly that step:

  • Cache reads at $0.50 per million, a 90% discount off the $5 base. Graph ingestion re-sends the same schema and instructions on every episode, and that repeated prefix now bills at a tenth of the price
  • Minimum cacheable prefix dropped to 512 tokens, half what Opus 4.8 needed. Short extraction prompts that were too small to cache before now qualify with zero code change
  • Batch API at 50% off, stacking with caching. Backfilling a year of history into a graph is the textbook batch job: not time-sensitive, high volume, perfectly cacheable
  • The result: the one operation that made graph memory expensive is now the cheapest thing Opus 5 does.

    Media image

    The core split: cheap extraction, careful traversal

    Graph engineering has two model-facing jobs, and they want opposite settings. Getting this split right is the whole skill.

  • Extraction (high volume, low judgment): pulling entities and typed relations out of raw text. Runs on every episode, thousands of times. This wants low effort and a stable cached prefix
  • Traversal reasoning (low volume, high judgment): answering a multi-hop question by walking the graph and synthesizing. Runs rarely, matters a lot. This wants high or max effort
  • Run extraction at max effort and you burn frontier tokens on mechanical work.

    Run traversal at low effort and your multi-hop answers get lazy.

    The bill and the quality both live in this one decision.

    The extraction config (copy this)

    Keep the schema and instructions as an identical prefix on every episode so the cache actually hits:

    import anthropic
    
    client = anthropic.Anthropic()
    
    # Stable prefix: identical every call = $0.50/M cache reads
    EXTRACTION_SYSTEM = """Extract a knowledge graph from the text.
    Return JSON only:
    {
      "entities": [{"name", "type", "description"}],
      "edges": [{"source", "target", "relation", "valid_from"}]
    }
    Rules:
    - Canonical names only (resolve "Buzz Aldrin" = "Edwin Aldrin")
    - Every edge needs a valid_from date if the text implies one
    - Never invent relations not stated in the text
    """
    
    def extract(episode_text, occurred_at):
        return client.messages.create(
            model="claude-opus-5",
            max_tokens=2000,
            system=[{
                "type": "text",
                "text": EXTRACTION_SYSTEM,
                "cache_control": {"type": "ephemeral"},   # cache the prefix
            }],
            messages=[{"role": "user", "content":
                f"reference_time: {occurred_at}\n\n{episode_text}"}],
            extra_headers={"effort": "low"},   # mechanical work, low effort
        )

    Three details that decide the bill:

  • cache_control on the system block is what turns $5 into $0.50 on every repeat. Without it you pay full rate every episode
  • effort: low because extraction is pattern-matching, not reasoning. Save the thinking budget for traversal
  • The variable part goes last. Episode text and timestamp change every call; the schema never does. Stable-first, variable-last is what keeps the prefix cacheable
  • The traversal config (the other half)

    When the agent answers a real question, flip both settings:

    ## Graph routing (CLAUDE.md)
    
    Ingestion (writing to the graph):
    - Model: Opus 5, effort low
    - Always cache the extraction schema prefix
    - Batch historical backfills, never run them synchronously
    
    Traversal (querying the graph):
    - Model: Opus 5, effort high (max for deep multi-hop)
    - Force a retrieval step: pull the relevant subgraph first,
      then reason only over those facts
    - Every answer cites the specific edges it used
    
    Never:
    - Run extraction at high effort (burns tokens on mechanics)
    - Run traversal at low effort (lazy multi-hop answers)
    - Change effort mid-session (it invalidates your cache)

    That last rule is a real trap on Opus 5: effort is part of the prompt-cache key.

    Flip it mid-conversation and the next turn re-reads your entire context at full uncached price.

    Set ingestion and traversal as separate sessions, not one session toggling effort.

    Wiring it into Claude Code

    Graphiti ships an MCP server, so Claude Code reads and writes the graph with no glue code.

    Point extraction at the cheap setting right in the config:

    {
      "mcpServers": {
        "graphiti": {
          "command": "uvx",
          "args": ["graphiti-mcp"],
          "env": {
            "NEO4J_URI": "bolt://localhost:7687",
            "NEO4J_PASSWORD": "${NEO4J_PASSWORD}",
            "MODEL_NAME": "claude-opus-5",
            "MODEL_EFFORT": "low"
          }
        }
      }
    }

    Neo4j runs in one Docker container for a dev graph.

    Now Claude Code has memory that survives every compaction, every restart, and every new session, and the extraction feeding it bills at cache-read rates.

    The bill, worked out

    A realistic shape: backfilling 5,000 episodes, each ~800 tokens of text against a ~600-token cached schema prefix.

    Naive (full rate, no cache, high effort):
      5,000 × 1,400 tokens × $5/M  = $35.00 input
      plus heavy reasoning output at $25/M
    
    Opus 5 done right (cached prefix, low effort, batched):
      schema:  600 tokens × $0.50/M cache read
      text:    800 tokens × $2.50/M batch input
      = roughly $10.30 input, output minimal at low effort

    Same graph, built for under a third of the naive cost, and the batch backfill runs while you sleep. Feeding a temporal graph is now cheaper than embedding the same corpus into a vector store.

    Common mistakes

  • Extraction at high effort. The single most expensive habit. Entity extraction is mechanical, low effort handles it, and you save the reasoning budget for the queries that need it
  • No cache_control on the schema. You re-send the same instructions on every episode. Without caching that's full rate every time; with it, a tenth
  • Synchronous backfill. Loading history one blocking call at a time forfeits the 50% batch discount for zero benefit. Nobody's waiting on a backfill
  • Toggling effort mid-session. It's part of the cache key. One flip and your next turn re-reads everything at full price. Separate sessions for ingest and query
  • Skipping reference_time. No timestamps means no temporal graph, just a static ontology that rots. The whole reason to build this over embeddings is the time layer
  • The 20-minute setup

  • Run Neo4j in Docker and add the Graphiti MCP block, effort low (5 min)
  • Set the extraction schema as a cached prefix, variable text last (5 min)
  • Backfill your history through the Batch API, not synchronously (4 min)
  • Add the traversal routing to CLAUDE.md, high effort for queries (3 min)
  • Ask one multi-hop question and check it cites real edges (3 min)
  • The frontier got cheaper and the graph got a cache. Most people will run extraction at max effort and wonder why their memory layer costs more than their model. Split the jobs, cache the schema, batch the backfill, and a temporal graph becomes the cheapest upgrade your agent can get.

    Thanks for reading!

    Media image
    Actions
    What You Can Do
    • Export as PDF or Markdown
    • Batch Export to Notion
    • Bookmark & Highlight
    • LinkedIn & Instagram Carousel Maker
    Create Free Account

    Includes 7-day Premium trial

    Advertisement