The workflow

A pile of specialists is not a workflow. LangGraph turns them into a compiled graph with a typed state object, named nodes, and explicit edges between them. This is where orchestration stops being a buzzword and becomes code.

The sequential CV graph

Each agent is a node. Each edge is a transition. State flows from entry to END.

cv_agentic_analyzer.py
python
from typing import TypedDict, Optional, Dict, Any, List

class CVAnalysisState(TypedDict):
    """Shared memory for every agent in the graph."""
    cv_content: str
    job_description: Optional[str]
    job_analysis: Dict[str, Any]
    analysis_results: Dict[str, Any]
    strengths: List[str]
    weaknesses: List[str]
    improvement_suggestions: List[str]
    score: int
    keyword_match_score: int
    experience_relevance: int
    skills_alignment: int
    format_score: int
    score_rationale: Dict[str, str]
    ats_analysis: Dict[str, Any]
    error: Optional[str]

Every agent reads from and writes to this object. TypedDict keeps the contract explicit so a typo in one agent does not silently break the next one.

cv_agentic_analyzer.py
python
from langgraph.graph import StateGraph, END

def _build_workflow(self):
    workflow = StateGraph(CVAnalysisState)

    # Nodes: each agent is registered under a name
    workflow.add_node("extract_content", self.content_extractor.extract_content)
    workflow.add_node("analyze_jd", self.jd_analyzer.analyze_jd)
    workflow.add_node("analyze_strengths", self.strengths_analyzer.analyze_strengths)
    workflow.add_node("analyze_weaknesses", self.weaknesses_analyzer.analyze_weaknesses)
    workflow.add_node("generate_suggestions", self.improvement_suggester.generate_suggestions)
    workflow.add_node("score_cv", self.scorer.score_cv)
    workflow.add_node("analyze_ats", self.ats_analyzer.analyze_ats)

    # Entry point and edges
    workflow.set_entry_point("extract_content")
    workflow.add_edge("extract_content", "analyze_jd")
    workflow.add_edge("analyze_jd", "analyze_strengths")
    workflow.add_edge("analyze_strengths", "analyze_weaknesses")
    workflow.add_edge("analyze_weaknesses", "generate_suggestions")
    workflow.add_edge("generate_suggestions", "score_cv")
    workflow.add_edge("score_cv", "analyze_ats")
    workflow.add_edge("analyze_ats", END)

    return workflow.compile()

Compile once, invoke many times. The compiled graph manages state propagation, error surfacing, and execution order for free.

You can. It works for three agents. It stops working when you need conditional routing, parallel branches, retries on specific nodes, or streaming progress per node. LangGraph is not magic. It is a structure that makes those needs trivial to add later.

Quiz: Quiz

Loading practice…

Checkpoint: Halfway checkpoint

Loading practice…