DEV Community

Cover image for Beyond the Linear CV
Pascal CESCATO
Pascal CESCATO

Posted on • Edited on

Beyond the Linear CV

Google AI Challenge Submission

This is a submission for the New Year, New You Portfolio Challenge Presented by Google AI

About Me

My professional path isn't linear. It's atypical, composed of pivots, skill acquisitions across different contexts, and transitions that traditional CVs struggle to represent.

For years, the challenge wasn't "how to write a CV" but rather: how to make a non-linear journey readable?

The classic portfolio format—chronological, linear, static—works well for continuous trajectories. It breaks down for everything else. This project emerged from that personal need: what if we stopped trying to flatten our careers into a timeline, and instead represented them as they truly are—a network of interconnected skills, projects, and experiences?

As we enter 2026, "New Year, New You" doesn't have to mean reinventing yourself. Sometimes it means representing yourself more accurately.

Portfolio

Live Demo: AI Knowledge Graph CV Builder

What You'll See

The app loads with my CV as a demo so you can explore immediately:

  • Network Graph: 30+ interconnected nodes showing skills, projects, and expertise domains

Network Graph - Interactive knowledge graph visualization

  • Flow Diagram: Visual journey from skills → projects → specialized areas

Flow Diagram - Skills to Projects to Expertise

  • Skills Matrix: Heatmap showing which projects use which technologies

Skills Matrix - Heatmap of skills across projects

Zero friction: No upload required to see it in action. Click "Upload Your Own CV" when you want to try yours.

Visualizing Career Evolution

To test the system's ability to capture career trajectories, I ran my own CV from 2021 vs 2025:

2021 Graph (37 nodes, 74 edges):

  • Corporate-focused: Skyrock, Logic-Immo, Photobox
  • Legacy tech: Flash/Zend_Amf, Palm webOS, ORACLE
  • Broader scope: Lead Dev, Project Manager, Full-Stack Engineer

2025 Graph (30 nodes, 74 edges, +23% density):

  • Independent: Freelance + personal projects
  • Modern stack: Astro, LLM/RAG, Docker, PostgreSQL
  • Focused expertise: Migration Engineering + AI Automation

What changed?

  • -8 technologies (legacy tech retired)
  • +2 concepts (AI Automation, Migration Engineering)
  • +23% density (deeper specialization vs wider breadth)

The graph doesn't just show skills—it tells the story of a career pivot from corporate generalist to independent specialist.

This is exactly what traditional CVs fail to capture.

Career Evolution: 2021 → 2025

Metric 2021 2025 Change
Nodes 37 30 -19% ↓
Edges ~74 74 =
Density 2.0 2.2 +23% ↑
Stack Legacy + Modern Modern only 🔄
Focus Corporate generalist Independent specialist 🎯

Key transitions:

  • Out: Flash, ORACLE, Palm webOS, 5 corporate clients
  • In: Astro, LLM/RAG, Docker, AI Automation, Migration Engineering
  • Evolved: PHP 4→7, WordPress (legacy→modern), MySQL

The graph doesn't just track skills—it reveals strategic pivots.

Real-World Testing

I tested the tool with three different profiles:

Senior Specialist (30 nodes, 2.47 density)

  • Deep expertise in AI/Migration
  • Modern stack (Astro, LLM, Docker)
  • High interconnection within niche

Mid-Level Generalist (33 nodes, 2.42 density)

  • Broad CMS expertise (WordPress, Magento, PrestaShop)
  • Traditional e-commerce stack
  • Skills distributed across varied projects

Junior Polyvalent (35 nodes, 2.57 density)

  • Modern full-stack (MERN, Angular, Symfony)
  • Creative skills (design, video)
  • The matrix revealed interesting gaps: claimed Symfony expertise with no projects demonstrating it

Key insight: The tool adapts to different career stages and reveals actionable patterns—like skills declared but not proven in projects.

How I Built It

The Problem: Structure, Not Extraction

This isn't keyword extraction. It's about asking AI to reason about context and produce a structured representation: nodes, relationships, and a graph-oriented vision.

Most CV parsers extract surface-level keywords. This project asks: "What are the semantic connections between my Python skills, my migration projects, and my AI automation expertise?"

Tech Stack

AI Layer:

  • Gemini Flash Preview 3.0 for CV analysis
  • Google AI Studio for prompt engineering & iteration
  • Custom system prompt with 6 levels of extraction rules

Visualization Layer:

  • Streamlit for the web interface (rapid prototyping)
  • vis.js (via streamlit-agraph) for network graphs
  • Plotly for Sankey flow diagrams & heatmaps

Deployment:

  • Google Cloud Run for containerized deployment (challenge requirement)
  • Docker for containerization
  • GitHub integration for CI/CD

Why streamlit-agraph for Network Visualization?

The Network Graph view uses streamlit-agraph (a vis.js wrapper). During development, I evaluated several alternatives for displaying interactive network graphs in Streamlit. Here's the decision matrix that led to this choice:

Library Responsive Interactive Force-Directed Layout Dev Time Verdict
streamlit-agraph ⚠️ Fixed canvas ✅ Full (click, zoom, pan) ✅ Automatic ~2 hours Selected
Plotly Graph Objects ✅ 100% responsive ⚠️ Limited interactions ❌ Manual positioning ~6 hours ❌ Too much effort
Pyvis ⚠️ HTML file generation ✅ Full ✅ Automatic ~4 hours ❌ Complex integration
NetworkX + Matplotlib ✅ Fully responsive ❌ Static image ✅ Automatic ~3 hours ❌ No interactivity
D3.js Custom ✅ 100% responsive ✅ Full control ✅ Custom ~8+ hours ❌ Time prohibitive

Decision rationale:

For this project, interactivity was the priority. The ability to click nodes, activate focus mode, and explore connections dynamically was more valuable than perfect responsive behavior in iframes.

streamlit-agraph delivered:

✅ Zero-configuration force-directed layout (nodes position themselves)
✅ Full interaction support (click handlers, zoom, pan)
✅ Production-ready in ~2 hours of development
✅ Professional visual quality out of the box

Trade-off accepted:

⚠️ Fixed canvas size (1400×900px) doesn't fill 100% of iframe width
✅ Mitigation: Canvas size chosen to work well on 1440px+ screens (laptops/desktops)

Alternative approaches considered (Plotly, D3.js) would have provided better responsive behavior but at the cost of 3-4× development time and reduced interactivity.

So streamlit-agraph hit the sweet spot between functionality, visual quality, and development speed.

Note: For optimal experience, open the full application directly.

Responsive Strategy

While the canvas is fixed at 1400×900px, users can collapse the sidebar (<< button) to gain ~250px of vertical space. This makes the app work perfectly even on 1366-1680px screens.

  • Sidebar open: Full controls + graph (optimal on 1920px+)
  • Sidebar closed: Full-screen graph (optimal on 1366px+)

User-controlled responsiveness proved more practical than attempting CSS magic with fixed-size canvas elements.


Development Process

1. Prompt Engineering in Google AI Studio

Before writing any application code, I spent time in AI Studio crafting the extraction prompt. This phase was critical:

LEVEL 1: Core entities (Person, Skills, Projects)
LEVEL 2: Relationships (USES, CREATED, MASTERS)
LEVEL 3: Technical relationships (PHP ENABLES WordPress)
LEVEL 4: Concepts & expertise domains
LEVEL 5: Temporal & contextual relationships
LEVEL 6: Bidirectional concept-project links ← Key innovation
Enter fullscreen mode Exit fullscreen mode

Why this matters: A CV isn't just nodes, it's the connections that matter. "Python" isn't just a skill—it ENABLES AI Automation, which is IMPLEMENTED_IN multiple projects, which DEMONSTRATES Migration Engineering expertise.

The prompt evolved through 20+ iterations in AI Studio before integration.

2. Multi-View Dashboard

Initial version had only the network graph. User feedback revealed a problem: different audiences need different views.

  • Developers want to explore connections (Network Graph)
  • Recruiters need quick visual narratives (Flow Diagram)
  • Managers want fast skill scanning (Skills Matrix)

The breakthrough was realizing this isn't three separate features—it's three perspectives on the same data.

3. Iterative UX Refinement

Based on real user testing:

  • V7.0: Multi-view dashboard
  • V7.1-V7.6: Spacing optimization (nodes were overlapping)
  • V8.0-V8.2: English interface + demo auto-loading

The demo CV auto-load was inspired by the challenge theme: show, don't tell. Let visitors see the result instantly instead of asking them to upload first.

4. Deployment on Google Cloud Run

As required by the challenge, the app is deployed on Google Cloud Run. The deployment is straightforward:

  • Containerized: Streamlit app packaged in Docker
  • Serverless: Auto-scaling, pay-per-use
  • Public URL: Accessible without authentication
  • CI/CD: Connected to GitHub for automatic deployments

Cloud Run was chosen for its simplicity and alignment with the Google AI ecosystem.

Google AI Tools Used

Google AI Studio was essential for:

  1. Rapid prompt iteration without deploying code
  2. JSON validation to ensure consistent output structure
  3. Token optimization to stay within rate limits

Gemini Flash Preview 3.0 chosen for:

  • Multimodal capabilities (PDF → structured JSON)
  • Large context window (handles long CVs)
  • Structured output with consistent formatting
  • Speed for real-time extraction

Design Decisions

Why Graphs?

Traditional CVs are tree structures (chronological). Professional identities are graphs (relational). The mismatch creates information loss.

Example: My "WordPress to Astro Migration" project connects to:

  • Astro framework (USES)
  • WordPress (USES)
  • Web Performance (DEMONSTRATES)
  • Migration Engineering (DEMONSTRATES)
  • SSG Ecosystem (IMPLEMENTED_IN)

A timeline can't represent this richness. A graph can.

Why Three Visualizations?

Network Graph: For exploration and discovery

  • Best for: Deep dives, understanding connections
  • Audience: Technical leads, fellow developers

Flow Diagram: For storytelling

  • Best for: Quick pitches, visual narratives
  • Audience: Recruiters, hiring managers

Skills Matrix: For scanning

  • Best for: 30-second skill assessment
  • Audience: HR, technical screeners

One visualization can't serve all audiences. This was the key insight.

Why Demo-First?

Inspired by product design principles: reduce friction to zero.

Before: "Upload your CV to see how it works" → 50% bounce rate
After: "Here's mine already loaded, explore now" → Instant engagement

What I'm Most Proud Of

1. Bidirectional Semantic Relationships

The graph doesn't just show that "Newsletter Engine uses Python"—it shows that:

  • Python ENABLES AI Automation (capability)
  • AI Automation is IMPLEMENTED_IN Newsletter Engine (evidence)
  • Newsletter Engine DEMONSTRATES AI Automation (showcase)

This bidirectionality creates semantic completeness. Each project isn't just a container of technologies—it's proof of conceptual expertise.

2. Dense Graph Quality (70+ Relationships)

Most CV extractors produce sparse graphs (1.0-1.5 edges per node). This achieves density 2.4 (72 relationships for 30 nodes) by:

  • Extracting ALL mentioned technologies (not just "main" skills)
  • Creating technology chains (Docker RUNS_ON Linux)
  • Linking related projects (wp2md RELATED_TO WordPress Migration)

A dense graph is a truthful graph.

3. Zero-Config Demo Experience

The app loads with my CV pre-analyzed. No authentication, no API keys to configure, no upload required.

This aligns with "New Year, New You"—the portfolio shows transformation immediately rather than promising it.

4. Real-Time Adaptation to Feedback

Every version (V1 → V8.2) incorporated user feedback:

  • "Nodes overlap" → Mega Wide spacing mode
  • "Labels unreadable" → Verdana sans-serif, size optimization
  • "Need different views" → Multi-view dashboard
  • "Too much friction" → Demo auto-loading

Built in public, refined through dialogue.

5. Technical Elegance

The entire extraction happens in a single prompt. No multi-stage pipeline, no external tools.

response = model.generate_content([
    {"mime_type": "application/pdf", "data": cv_bytes},
    EXTRACTION_PROMPT
])
graph_data = json.loads(response.text)
Enter fullscreen mode Exit fullscreen mode

Input: PDF bytes + prompt
Output: Complete knowledge graph

That's it. The complexity is in the prompt design (crafted in AI Studio), not the code.

Personal Reflection: New Year, New Perspective

This project started as a personal need and became something more: an invitation to view professional identity differently.

We spend so much energy trying to fit our careers into templates. What if the template was wrong?

A knowledge graph doesn't judge whether your path was "correct." It simply represents what is: the skills you have, the projects you built, and how they connect.

In the spirit of "New Year, New You," this isn't about reinventing yourself. It's about representing yourself with more accuracy. Sometimes that's enough.

Try It Yourself

🔗 Live App: knowledge-graph-cv-837592265234.europe-west1.run.app

My CV is loaded by default—explore the three views, then upload your own.

📂 Source Code: https://github.com/pcescato/knowledge-graph-cv

Technical Metrics

  • Extraction Time: ~15-25 seconds (Gemini Flash Preview 3.0)
  • Average Graph: 25-35 nodes, 60-80 relationships
  • Density: 2.0-2.8 (edges per node)
  • Supported Formats: PDF only
  • Visualizations: 3 (Network, Flow, Matrix)
  • Languages: English interface

What's Next?

This MVP was built in 3 days as a proof of concept for the Google AI Challenge.

Technical roadmap (not yet implemented):

  • Export formats: JSON, GraphML, Neo4j cypher for data portability
  • Comparison mode: Side-by-side CV analysis to track career evolution
  • Skill gap analysis: Compare your graph against target job descriptions
  • Temporal dimension: Visualize career progression over time

But I see potential beyond personal portfolios:

  • HR Tech: Intelligent candidate matching based on skill graphs, not keywords
  • Internal Talent Mapping: Companies understanding who knows what across teams
  • Career Coaching: Visualizing skill gaps and growth paths

The graph-based approach reveals connections that traditional CVs hide. If you're building in this space or interested in exploring applications for recruitment, talent analytics, or knowledge management—I'd love to chat.

The FinOps Victory: Slashing my Cloud Bill by 97% Against a Botnet

The biggest challenge of this project wasn't the AI—it was budgetary survival. Within 48 hours, my application went from a quiet demo to the target of an intensive piloning (bots from Poland, Vietnam, and the USA).

The Final Architecture: The "Thermal Shield"

The problem? Streamlit (Python) is notoriously bad at closing persistent WebSocket connections quickly, which kept my Cloud Run instances running (and billing) indefinitely.

The solution: Injecting a Caddy server (written in Go) as a Reverse Proxy inside the same Cloud Run container.

Cloud Run Container (512Mi)
├── Caddy (:8080) ← The "Bouncer" at the door
│   ├── IP Filtering (via X-Forwarded-For headers) → 403 Forbidden
│   └── Proxy legitimate traffic → localhost:8501
└── Streamlit (:8501) ← The (now protected) App
Enter fullscreen mode Exit fullscreen mode

The Numbers (Last Hour Report)

Using a custom monitoring script, I isolated the efficiency of this defense during a high-traffic hour:

Traffic Type Requests Action CPU Time Projected Budget
Bot Attacks 945 Blocked (403) 2.17s €0.01 / month
Human Sessions 12 Allowed (101) 328.68s €1.58 / month
TOTAL 957 - 330.85s €1.59 / month

Cost Evolution (Monthly Projection)

  • Day 1 (Initial Deploy): ~€25/mo (No protection).

  • Day 3 (Attack Detected): ~€42/mo (Python-level filtering failed to close sockets).

  • Day 6 (Caddy "Sniper" Active): €1.59/mo (Bots are ejected in under 2ms).

Drastic Reduction: -96% from the worst-case scenario.

Lessons Learned "From the Trenches"

  1. The App is not a Firewall: In Serverless environments, if traffic hits your Python code, you’ve already paid. You must block the attack as early as possible in the network stack.

  2. The IPv6 Trap: Modern bots use IPv6 tunnels extensively (Comcast, Indian ISPs) which bypass traditional IPv4 filters.

  3. The Internal Sidecar: Running two processes (Caddy + Streamlit) in a single container is an elegant, free, and ultra-robust way to secure a public demo without the cost of a Load Balancer or Cloud Armor.

The irony of the challenge: I probably learned more about reverse proxies, X-Forwarded-For headers, and cloud cost optimization than I did about Knowledge Graphs. But that's the reality of production: **Production > Tutorials, always.

The full story: Why Streamlit + Cloud Run is a Billing Trap (and How I Fixed It)


Thanks for reading! If this resonates with you, I'd love to hear your thoughts.

Does your career fit into a timeline, or is it a graph? 💭

Top comments (20)

Collapse
 
sylwia-lask profile image
Sylwia Laskowska

Pascal, that’s an absolutely brilliant idea - a CV as a skills graph! I honestly never thought about it that way, and it really is genius; that’s exactly how we grow. Well, I don’t want to worry you, but I guess you can’t stop writing your blog after all - your ideas are just too good!

Collapse
 
pascal_cescato_692b7a8a20 profile image
Pascal CESCATO • Edited

Careful, you’re dangerously close to convincing me 😄
I’ll admit: once you start thinking about careers as graphs, it’s hard to unsee it.
Thanks for the kind words — they definitely make the writing pause feel… flexible.
By the way: did you try with yours?

Collapse
 
sylwia-lask profile image
Sylwia Laskowska

Ah, not yet. I’ve given myself too many tasks for January and now I have to somehow deal with them 😅

Thread Thread
 
pascal_cescato_692b7a8a20 profile image
Pascal CESCATO

Haha, that sounds very familiar 😄
January does have that “let’s do everything at once” energy.
No rush at all — if you ever feel like feeding one task into another, I’ll be curious to see what your graph looks like.

Collapse
 
dariomannu profile image
Dario Mannu

Very creative, indeed, but does it not focus a bit too much on how to express it, rather than how to interpret it?
Hiring managers need certain questions to be answered, otherwise they'll risk making some totally wrong hires:

  • Is this person deeply knowledgeable using platform X, or they're just echoing buzzwords heard from colleagues?
  • What are their communication skills like? Are they going to tell me in a concise sentence what's going on, or will they get lost in hundreds of useless details and total confusion every time?
  • Do they possess sound fundamentals? When we put them in front of the new tech we're creating, are they going to pick it up and improve it better than ourselves, or will they just leave a total mess and be even proud of it, genuinely believing and writing in their next CV that they've done good?
  • Do they have initiative, or we'll need to assign them one task after another?
  • Can we see any potential in this hire, if they're a junior and we want to help them grow?
  • Do they collaborate and help up or down the organisation?
  • Any signs of narcisistic or otherwise toxic behaviour we need to gauge before we're screwed?
  • If our environment is already a toxic hell, will this person survive at all?
  • Any signs they are just saying what we want to hear (or lying outright) to get hired?
  • Is this an AI-generated CV, which would hide all the above, or a genuine statement of who this person is?
Collapse
 
pascal_cescato_692b7a8a20 profile image
Pascal CESCATO

That’s a very fair question — and I actually agree with most of it.
This project deliberately focuses on representation, not evaluation. It doesn’t try to answer hiring questions directly, and it shouldn’t replace interviews, references, or human judgment.
What it tries to surface is something more upstream: structure.
Patterns of focus, evolution, depth vs. breadth, long-term coherence, or sudden buzzword spikes become visible in ways a linear CV often hides.
All the questions you list — fundamentals, communication, initiative, collaboration, honesty, even toxicity — still require human interaction. A graph can’t (and shouldn’t) “score” those.
But as a complementary view, it can help frame better conversations:
why certain technologies persist, why others disappear, where real depth might be worth probing, or where something looks inflated and deserves scrutiny.
In that sense, it’s less about making hiring decisions and more about asking better questions — earlier, and with fewer blind spots.
And yes, the risk of AI-generated CVs is real. Ironically, that’s also why alternative representations may become more useful: consistency over time, evolution across versions, and structural coherence are harder to fake than polished bullet points.
So I see this less as a hiring tool, and more as a lens — one that still requires humans on both sides to do the actual thinking.

Collapse
 
art_light profile image
Art light

Hello, Paskal.
Wishing you a year filled with growth, health, and success. 🌟
I was waiting for your post.
This is really strong work, both technically and conceptually. You’ve put clear language around something a lot of people with non-linear careers feel but don’t usually know how to describe: how much meaning gets lost when years of connected experience are forced into a simple timeline. Thinking about professional identity as a graph instead of a sequence is a genuinely useful shift, and the way you ground it—through density, two-way relationships, and how things evolve over time—keeps it practical rather than theoretical. The demo-first choice also shows good product sense. It lets people immediately understand the value without needing a lot of explanation or buy-in.

On the technical side, the restraint really comes through. Pushing complexity into prompt design instead of code, choosing tools based on how they actually improve interaction, and being upfront about the trade-offs all point to mature decision-making. The idea of showing the same data through different views for different audiences is especially strong, and it feels useful well beyond portfolios—things like HR tools, internal talent mapping, or career coaching come to mind. Overall, this doesn’t just show a product; it reflects a thoughtful way of thinking about careers, data, and AI that feels current and genuinely applicable.

Collapse
 
pascal_cescato_692b7a8a20 profile image
Pascal CESCATO

Thank you, Art, for such a deep and thoughtful reading! You hit the nail on the head regarding my main motivation: the frustration of seeing rich, interconnected career paths flattened into a simple, lossy timeline.

Your point about use cases beyond the portfolio—like HR tools, talent mapping, or coaching—is particularly interesting. Shifting the focus toward graph density and semantic connections instead of just duration really does change how we perceive professional potential.

Also, glad the 'show, don't tell' approach resonated. It was a deliberate product choice to let the data speak for itself immediately. Much appreciated!

Collapse
 
ehsanpo profile image
Ehsan Pourhadi

Very jaw dropping stuff! never thought about showing my developer knowlage as graph, specially using Neo4j! will def make something simulator. also very interesting stuff about using caddy in the cloud run!!

Collapse
 
pascal_cescato_692b7a8a20 profile image
Pascal CESCATO

Thanks!
I had the same reaction when I first sketched the idea: once you stop forcing a career into a linear timeline, the graph almost builds itself. Neo4j-style thinking fits surprisingly well for skills and roles — the relationships tell a bigger story than the dates.
And yes, running Caddy on Cloud Run is a fun combo. It removes a lot of friction when you want to ship quickly with clean routing.
If you end up experimenting with your own graph, I’d really love to see what direction you take it in.

Collapse
 
ehsanpo profile image
Ehsan Pourhadi

Already on it! you sent me straight down a rabbit hole 😄
I’ve just installed Neo4j and started mapping things out from my portfolio. It’s surprisingly satisfying to see the connections emerge once you stop thinking linearly.

Thread Thread
 
pascal_cescato_692b7a8a20 profile image
Pascal CESCATO

That’s the best part — once you drop the linear mindset, the patterns almost reveal themselves.
Curious to see where your graph takes you next.

Collapse
 
meal profile image
Mateusz Kozak

That's a great idea!
Not for this challenge, but because of my own struggles with recruitment (on both sides over the years), I've built a self-updating developers' portfolio!
Don't want to intercept your thread so won't post here unless asked for ;)

Collapse
 
pascal_cescato_692b7a8a20 profile image
Pascal CESCATO

That sounds really interesting 🙂
And no worries at all about “intercepting” — sharing experiences like that is exactly what makes these discussions valuable.
If you ever feel like expanding on it, I’d genuinely be curious to hear how you approached it.

Collapse
 
benjamin_nguyen_8ca6ff360 profile image
Benjamin Nguyen

Cool! Thank you for sharing :)

Collapse
 
pascal_cescato_692b7a8a20 profile image
Pascal CESCATO

Thanks! Curious to hear if you try it with your own CV -
would love feedback on what works / what doesn't 👍

Collapse
 
benjamin_nguyen_8ca6ff360 profile image
Benjamin Nguyen

No! I have not. I am going to a personal project with AI very soon. I am not sure if I am going to use Matplotlib or potly as graph. I am going to deploy my project on renders.

Thread Thread
 
pascal_cescato_692b7a8a20 profile image
Pascal CESCATO

Nice! For graphs with AI projects, Plotly > Matplotlib if you need
interactivity. That's what I used here for Flow/Matrix views.

Good luck with your project! 🚀

Thread Thread
 
benjamin_nguyen_8ca6ff360 profile image
Benjamin Nguyen

Nice! Thank you :)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.