Inspiration
Studying for a certification starts with two questions nobody answers well: what do I actually need to learn, and when am I going to do it. A chat assistant will happily produce a study plan. Then you close the tab and nothing happens, because a plan you have to re-read is not a plan — it is homework about homework.
The second question is the one that kills people. You can know exactly which topic you are weak at and still never study it, because the week is already full. So SkillPath answers both questions and then acts on the answer: it puts the blocks in your calendar, around the appointments you already have.
What it does
You tell it one thing: which exam, and when.
I am taking the Google Cloud Professional Cloud Network Engineer exam
on 2026-11-20.
No syllabus, no reading list. From that, the agent:
- Identifies the certification and researches the official exam guide with Google Search grounding. Every extracted skill records which official section it came from, so coverage can be checked rather than assumed — all six sections, thirty skills for this exam.
- Builds a prerequisite graph in Neo4j.
(Skill)-[:PREREQUISITE_OF]->(Skill). This graph is the product, not a cache. - Orders the work with a topological sort so prerequisites come first, and schedules it into genuinely free evenings — earliest deadline first across every exam you are studying for at once.
- Writes the blocks into a real Google Calendar, one dedicated calendar per certification, working around the events already on it.
Then you take a mock exam and hand it a photograph of the score sheet.
A low score is a symptom. The weakness detector walks the prerequisite edges backwards up to four hops to find the foundations that are actually broken — you failed load balancing, but the reason is that you never understood backend services and health checks. Red is what you got wrong. Amber is why. Those become review blocks, and the whole calendar is rebuilt.
How we built it
One ADK graph, with a hard line down the middle of it.
The model does: intent classification, researching an exam from its official guide, and reading a photograph of a score sheet. Structure extraction only.
Plain code does: which prerequisite is broken (a Cypher traversal), what order you study in (a topological sort), and which time slot each block gets (a deterministic allocator). No model is consulted for any of it. Same inputs, same output, every run — and unit tested against a real Neo4j, because the Cypher is the logic.
That separation is the whole design. An agent that books time on your calendar has to be predictable in the part that touches your week.
Stack: Gemini 3.5 on Vertex AI · Google Agent Development Kit · Cloud Run · Neo4j on Compute Engine (private VPC, no public IP) · Google Calendar API · Secret Manager · Identity-Aware Proxy · Cloud Build and Artifact Registry. Every piece of it defined in Terraform.
Challenges we ran into
Entity resolution was the hard problem, not the agent. The syllabus says "Cloud Load Balancing backend services (NEGs and MIGs)". The mock exam says "ロード バランシング (4問)". These are the same thing and nothing matches them. Twelve duplicate skill pairs in production before we fixed it. The answer was a three-stage resolver — a normalized match key with all separators stripped, containment matching with a length ratio floor, and machine-generated alias candidates pulled out of parentheses — plus a deterministic sanitizer that strips question counts before anything reaches the graph.
Coverage, honestly measured. An early version extracted nineteen skills and looked fine. It was silently skipping sections of the official guide. We made the researcher carry the official six-section structure through to the extractor and report coverage per section. Nineteen became thirty.
Not dropping the tail. When the syllabus does not fit before the exam date, the tempting thing is to truncate. We compress proportionally instead and tell the user plainly: hours needed, hours secured, compression ratio, load per day.
Idempotency everywhere. Every Neo4j write is a MERGE. Every calendar event is keyed by a session id derived from the plan, the certification and the skill. Re-run the same input and nothing duplicates — which matters, because the agent re-plans on every interaction.
Accomplishments that we're proud of
Two exams running at once, coordinated on a single timeline by earliest deadline, each writing to its own calendar — verified in production with zero double-booked slots and zero duplicate sessions.
And the guardrails, which we treated as a feature rather than an afterthought: quantity caps and name normalization applied to every model output before it can reach the graph, admin endpoints behind a Secret Manager token, per-uid isolation on every query, rate limiting, and automated adversarial tests in the suite — a prompt injection buried inside mock exam text, and a syllabus that asks for a thousand junk skills. Both are caught.
What we learned
The moment an agent writes to something real — your calendar — "usually right" stops being acceptable. That pressure is what pushed the model out of the decision path and into the extraction path, and the design got better for it.
Also: the prerequisite edge is what a chat interface cannot replicate. Anyone can list topics. Knowing that your load balancing score is really a backend services problem requires a graph you have been maintaining.
What's next for SkillPath
Resource selection (choosing the specific chapter or video for each block) is the one LLM node still unimplemented. Beyond that: real authentication so the uid comes from a token rather than the request, spaced repetition on top of the mastery scores, and learning each user's actual completion rate to calibrate future estimates.
Log in or sign up for Devpost to join the conversation.