context-intelligence-gds
Skill5 starsChanged 5 days agoMITView on GitHub
Use when about to write naive Cypher for a graph-topology question — pathfinding, reachability, centrality/influence, community/clustering, structural similarity, or similar event paths/trajectories (with/without time) — reach for Neo4j GDS or APOC instead of hand-rolling traversals one hop at a time. WHEN/WHY layer; graph-query's "Push Work to the Database" section is the HOW.
In this repository12 other files it gives its agents.
- AGENTS.mdAGENTS.md
- context-intelligence-derived-metricsSkill
- context-intelligence-eval-designSkill
- context-intelligence-evaluation-methodologySkill
- context-intelligence-graph-querySkill
- context-intelligence-hill-climbingSkill
- context-intelligence-server-data-opsSkill
- context-intelligence-session-navigationSkill
- context-intelligence-session-reconstructionSkill
- context-intelligence-tool-designSkill
- transcriptSkill
- workflow-pattern-analysisSkill
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 106
Read-only fallback — no bipartite edges needed: When the store is read-only and you can't materialise Session→Tool edges, compute the …
- Distinctive: line 164
Default to these instead of re-deriving structure:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Context Intelligence — Graph Data Science First
The context-intelligence graph is large (millions of nodes across thousands of sessions). Naive Cypher tends to re-derive, one hop and one round-trip at a time, what a graph algorithm computes in a single server-side pass. This skill trains the reflex: recognize the shape of the question, and when it is a graph-algorithm shape, reach for GDS or APOC instead of improvising Cypher.
This skill is WHEN and WHY. The HOW lives next door. The graph-query skill owns the schema meaning, the traps, and the worked projection queries — its Section 8, "Push Work to the Database (APOC / GDS)" has the concrete
gds.graph.project → algorithm → gds.graph.droplifecycle and theSession/FORKED+ agent-rollup example. Loadcontext-intelligence-graph-queryfor mechanics; use this skill to decide whether the algorithm is the right tool at all.
The naive-query smell test
You are probably about to write naive Cypher where GDS/APOC would be better if you catch yourself doing any of these:
- Guessing edge types to walk a tree (
-[:HAS_SUBSESSION|FORKED|HAS_FORK]->) or repeatedly steppingSession.parent_idone hop at a time to rebuild a delegation tree. collect()thensize([x IN … WHERE …])to count how many things are reachable / match — reconstructing an algorithm's output by hand.- A giant
WHERE node_id IN [ …50 literals… ]pasted into the query text (client-side set-building shoved into Cypher). UNWIND range(0, size(list)-2)to compute consecutive gaps / pairwise math.- Variable-length
-[*1..n]->followed by client-side filtering of the paths. - Pulling many rows to the client to iterate and aggregate what the DB could reduce.
Each of these is a tell that the question has a graph-algorithm shape.
What the graph-data-science package buys you (the advantages)
| Advantage | Naive Cypher | GDS / APOC |
| One pass, not many round-trips | N queries + client stitching | project once, compute server-side, return a bounded result |
| Scales to the whole graph | degrades / times out on deep or wide traversals | algorithms are built for millions of nodes |
| Correct, not approximate | hand-rolled shortest-path / "influence" is easy to get subtly wrong | gds.shortestPath, gds.pageRank, gds.betweenness are the real thing |
| Less context churn | large client-side pulls flood the session | the payload never crosses the wire; only the answer does |
| Stable, reusable shapes | every question becomes a new bespoke query | a handful of parameterized primitives cover most questions |
Best-fit scenarios → the right tool
Match the question shape to the tool. This is the core of the skill.
| The question is really… | Naive trap | Reach for | Why it wins |
| Full delegation subtree / all descendants of a session | one-hop parent_id walks, edge-type guessing | apoc.path.expandConfig(root, {relationshipFilter:'FORKED>', minLevel:1, maxLevel:20}), or gds.bfs | one call returns the whole bounded lineage; respects Trap 1 (lineage is FORKED, not HAS_SUBSESSION) |
| How are two sessions connected / shortest path | manual -[*1..n]-> + filtering | gds.shortestPath.* (or apoc.path.expandConfig) | correct pathfinding in one pass |
| Which agent/session is a hub / most influential | collect + size degree-counting | gds.pageRank / gds.degree / gds.betweenness over Session/FORKED, rolled up by the Session.agent property | real centrality; see graph-query §8 for the exact projection + agent-rollup (agents are a property to roll up by, not a projectable graph) |
| Clusters / communities of related sessions | can't express it naively | gds.louvain / gds.wcc | community structure in one call |
| Sessions similar by shared tools/skills | pairwise collect intersections | gds.nodeSimilarity over a Session→Tool/Skill projection | scalable similarity instead of O(n²) hand-joins |
Reach a JSON field inside Event.data | e.data.working_dir (raises a type error) | apoc.convert.fromJsonMap(e.data).working_dir | correct and lean — see graph-query §8's authoritative pattern |
| Operate over a known set of ids | 50-id IN [ … ] literal | pass $ids and UNWIND $ids AS id | one reusable shape; for heavy scans, apoc.periodic.iterate |
| Consecutive-pair math (inter-event gaps) | UNWIND range(0,size-2) | apoc.coll.pairsMin(list) | expresses the intent directly |
Complex topology searches — the hard ones this skill exists for
These are the searches naive Cypher either cannot express or does at O(n²) with wrong/approximate results. When the question is one of these, do NOT hand-roll it — project the right graph and run the algorithm.
1. Centrality / influence — "which sessions, agents, or tools are structurally most important?"
gds.pageRank·gds.betweenness·gds.degree·gds.closeness·gds.eigenvector.- Project the relevant graph (
Session/FORKEDfor delegation influence; a tool co-occurrence graph for tool influence), stream, roll up by the property you care about,gds.graph.drop.
2. Topological / structural similarity — "which sessions are shaped alike?"
- By shared neighbors (same tools/skills/agents used): project a bipartite
Session → Tool(or→Skill/→Agent) graph →gds.nodeSimilarity(Jaccard/overlap) orgds.knn. - By structural role (behave alike even without sharing exact neighbors):
gds.fastRP(orgds.node2vec) node embeddings →gds.knnfor nearest structural neighbors. This finds role-equivalent sessions. - Weight the vector before you compare it. Raw tool-usage counts are dominated by glue
tools (
bash,read_file,todo) — un-weighted, every session looks similar and the result is noise. Down-weight ubiquitous tools with a TF-IDF weighting (the same jobfastRPotherwise buys you), built in-graph withapoc.map.fromPairs(collect([tool_name, count])). - Read-only fallback — no bipartite edges needed. When the store is read-only and you
can't materialise
Session→Tooledges, compute the weighted vector as a node property inside the Cypher projection and rungds.knn(nodeProperties: ['toolVector'])directly on it — same answer, no derived edges. (General principle: when an algorithm's naive input is wrong or unavailable, reshape the input in the projection before reaching for a fancier algorithm.)
3. Similar event PATHS / trajectories — the sequence question, with or without time This is the "find similar paths of events" search. The time dimension decides the tool:
- WITHOUT time (bag of steps): reduce each session to its multiset of event/tool
types, then
gds.nodeSimilarity/gds.knnover theSession → Toolprojection. Order is ignored — "used A, B, C" matches "used C, B, A". - WITH time (ordered trajectory): order matters, so build the ordering first. Sort
each session's events by
started_at, form consecutive pairs withapoc.coll.pairsMin(ordered_list), and materialise a transition signature —(:Session)-[:HAS_TRANSITION]->(:TypePair {a,b}). Then eithergds.nodeSimilarityover that transition projection, orgds.fastRP+gds.knnto cluster whole trajectories. This distinguishesA→B→CfromA→C→B, which set-similarity cannot. - Extract one session's ordered path with
apoc.path.expandConfigor a time-orderedMATCH— never a client-side reconstruction.
4. Pathfinding / reachability — shortest, k-shortest, all-reachable.
gds.shortestPath.dijkstra·gds.allShortestPaths· Yen's k-shortest ·gds.bfs/gds.dfs; orapoc.path.expandConfigfor filtered reach.
Projection recipe (similarity/trajectory graphs are not stored edges — build them):
// bipartite Session→ToolCall for similarity (Cypher projection, GDS 2.x)
// confirm the Session→ToolCall reach against the graph-query skill / live schema first
CALL gds.graph.project.cypher('sess-tool',
'MATCH (n) WHERE n:Session OR n:ToolCall RETURN id(n) AS id',
'MATCH (s:Session)-[:HAS_EXECUTION|HAS_PART*1..3]->(tc:ToolCall)
RETURN id(s) AS source, id(tc) AS target');
CALL gds.nodeSimilarity.stream('sess-tool')
YIELD node1, node2, similarity
RETURN gds.util.asNode(node1).node_id AS a, gds.util.asNode(node2).node_id AS b, similarity
ORDER BY similarity DESC LIMIT 20;
CALL gds.graph.drop('sess-tool') YIELD graphName; // always release (in-memory only, no data touched)Deriving a graph that isn't stored (co-occurrence / teaming). "Which agents work
together?" has no stored Agent→Agent edge — but you can derive one from shared group
membership (e.g. agents whose sessions share a parent), then run community/centrality on the
derived graph. This is valid and different from projecting the real (edge-less) Agent
nodes, which is the dead end graph-query §8 warns about — confirm the grouping edge against
the live schema first:
CALL gds.graph.project.cypher('agent-team',
'MATCH (s:Session) WHERE s.agent IS NOT NULL RETURN id(s) AS id, s.agent AS agent',
'MATCH (a:Session)<-[:FORKED]-(p)-[:FORKED]->(b:Session)
WHERE a.agent < b.agent RETURN id(a) AS source, id(b) AS target, count(*) AS weight');
CALL gds.louvain.stream('agent-team') YIELD nodeId, communityId RETURN communityId, count(*) LIMIT 20;
CALL gds.graph.drop('agent-team') YIELD graphName;Four primitives that replace most naive Cypher here
Default to these instead of re-deriving structure:
- The lineage walker —
apoc.path.expandConfigoverFORKED(or aSession/FORKEDGDS projection for tree analytics). This one primitive replaces the single largest class of hand-rolled queries on this graph. - The JSON-lift reflex — never touch
Event.datawith dot-access; parse in-graph withapoc.convert.fromJsonMapand return only the scalar (graph-query §8 is authoritative). - The parameterized id-set —
UNWIND $ids, never a pasted literal list. Collapses a long tail of "unique" queries into one reused shape. - The in-graph frequency map —
apoc.map.fromPairs(collect([key, count]))builds a per-node weight/vector map server-side (feeds TF-IDFgds.knnnode properties). When collecting a set as a grouping key, canonicalise it first withapoc.coll.sortso[A,B]and[B,A]group as one.
When naive Cypher IS the right tool (don't over-reach)
GDS/APOC is not always the answer. A single plain Cypher statement already wins for:
- counts and existence checks (
RETURN count(*)), - single-session scalar lookups,
- group-bys / distributions over one hop (
GROUP BY tool_name), - schema probes (
db.labels(),db.relationshipTypes()).
Reach for the algorithm when the naive alternative means many round-trips, a large client-side pull, or reconstructing an algorithm by hand — not for a plain aggregate.
When GDS itself isn't enough (the upper bound)
GDS answers structural / behavioral questions — how a session was executed, who is
central, what clusters by shape. It does not answer intent questions — what a session
was for. Tool-vector similarity clusters the machinery, not the mission. The tell: if you
cross-tab a GDS cluster against the human's actual objective and the same goal is scattered
across most clusters, stop iterating on GDS. Export the bounded inline text (e.g.
Prompt.prompt) and run LLM-embedding + k-means instead — a different tool for a different
question shape. Escalating to GDS is right; escalating past it when the question is
semantic is the next move, not more algorithms.
Guardrails
- Probe first:
RETURN gds.version()/CALL gds.list();CALL apoc.help('path'). Both plugins run on the live target (Neo4j Community — GDS works). - Always release projections:
gds.graph.drop('g')when done. - Behind a read-only-enforcing endpoint, use
.stream/ scalar.stats. The.write/.mutatevariants can be rejected (HTTP 500) even though they only touch the in-memory catalog, not the store. - Bound the returned result even when the compute is server-side —
count/ aggregate /LIMIT. Pushing work to the DB does not excuse an unboundedRETURN. - Project the labels that exist —
Session(nodes),FORKED(relationships). Agents are a property (Session.agent) to roll up by, not a projectable graph. - Honor the schema traps — especially Trap 1 (delegation lineage is
FORKED+Session.parent_id, andHAS_SUBSESSIONis a single hop). The graph-query skill owns these; load it before writing the query.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

