Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Neutral, framework-agnostic decision tree for project kickoff: "which agent / RAG / LLM framework should I reach for?" Synthesizes the ecosystem sections of 7 landmark-project SOPs (LangGraph, LlamaIndex, DSPy, CrewAI, vLLM, Aider, Dify) into one layered rubric. Core stance: frameworks are LAYERS, not competitors — a real project usually combines DSPy (compile) + LlamaIndex (retrieve) + LangGraph (orchestrate) + vLLM (serve), and you choose ONE per layer, not one to rule all. Use when starting a
.claude/skills/agentsope-agentsop-framework-selection/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 152% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 153% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 460% | 0% |
| case-17 | ✗→✓ | ▲ Improved | 236% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 160% | 0% |
> Overlay posture: this is the capstone Phase-D skill — the most-cited entry > at any project kickoff. It decides which layer(s) you need and which > framework owns each layer. It does not teach any framework's API; for that, > descend to the per-framework SOPs (langgraph-sop, llamaindex-sop, > dspy-sop, crewai-sop, vllm-sop, aider-sop, dify-sop). Every > load-bearing claim carries an inline source tag resolving in > references/R1-decision-tree.md. > > Neutrality note: vendor pages each claim the center of the universe > (LangChain: "use LangGraph for production"; LlamaIndex: "the document agent > platform"; Dify: "scaffolding is the bottleneck"). This skill quotes those > claims but does not adopt any of them. The 7 SOPs disagree on the crossover > points; we surface the disagreements rather than papering over them.
Activate when any of the following fire:
"LangGraph vs CrewAI?" / "do we need a framework at all?"
pip install an orchestration / RAG / agent frameworkbefore having articulated what layers the project needs.
in a layer it was never good at (e.g., doing deep RAG inside CrewAI, or hand-rolling retrieval inside LangGraph).
ceiling and the team is asking "do we rewrite in code?"
Do not re-run this skill mid-implementation for a layer already chosen — that is churn. Run it once at kickoff, and again only when a new layer appears (e.g., "we now need to self-host the model" → triggers [[agentsop-llm-engine-selection]]).
> Mental check: the wrong framework is the single highest-cost decision in the > project — it is a one-week-to-reverse mistake, sometimes a one-month one. > crewai-sop · OP-1, vllm-sop · OP-7. Spend 20 minutes on this tree before > opening any tutorial.
Frameworks are layers, not competitors. The single most common kickoff error is treating "LangChain vs LlamaIndex vs DSPy vs CrewAI vs vLLM" as a horse race with one winner. They are not on the same axis. A mature LLM system is a stack:
┌─────────────────────────────────────────────────────────────┐
│ L7 App platform / UI / Auth │ Dify, Flowise, LangFlow │ ship-fast scaffolding
├─────────────────────────────────────────────────────────────┤
│ L6 Serving / inference │ vLLM, SGLang, llama.cpp … │ → see [[agentsop-llm-engine-selection]]
├─────────────────────────────────────────────────────────────┤
│ L3 Orchestration / control │ LangGraph, CrewAI, Workflows │ → see [[agentsop-agent-topology-selection]]
├─────────────────────────────────────────────────────────────┤
│ L2 Retrieval / context │ LlamaIndex, Haystack │ ingestion, index, query
├─────────────────────────────────────────────────────────────┤
│ L1 Modeling / prompt-compile │ DSPy, Outlines, Guidance │ the LM call itself
├─────────────────────────────────────────────────────────────┤
│ Coding-agent surface (cross) │ Aider, Cline, Cursor … │ end-user product, not a layer
└─────────────────────────────────────────────────────────────┘DSPy's own ecosystem doc draws this layering explicitly — DSPy "sits underneath LangChain, LlamaIndex, LangGraph as a compiler for individual LM calls" dspy-sop · R5. LlamaIndex's doc says "many production systems use both: LlamaIndex as the retrieval layer, LangGraph as the orchestration layer" llamaindex-sop · R5. Dify's doc describes the hybrid "Dify for frontend/RAG/auth + LangGraph for core agent logic behind HTTP" dify-sop · R5. The convergence is unanimous: choose per layer, then check interop.
Three corollaries:
(stuff the context window). A RAG chatbot needs L1+L2. A durable multi-step agent needs L1+L2+L3. Only self-hosting adds L6. Only mixed-role teams add L7.
DSPy+LangGraph (compile-inside-node) and LlamaIndex+LangGraph (retrieve-then- orchestrate) are textbook dspy-sop · R5. DSPy+LangChain or DSPy+CrewAI are a "smell" — both are L1-ish prompt strategies fighting for the same slot dspy-sop · R5.
dependency surface only past a complexity threshold (§4 gate G0).
The kickoff procedure runs as numbered steps (Pass A = Steps 1–6, Pass B = Step 7, Pass C = Step 8):
Pass A — Identify the layers you actually need. Walk the stack top to bottom and mark each layer needed / not-needed for this project:
swapped across models, or whose output is parsed by code? (Almost always yes.)
cannot fit in context? (Yes → need retrieval. No → skip.)
approval / >1 coordinating agent? (Yes → need orchestration. A single straight- line call → skip; raw SDK suffices.)
API)? (Yes → [[agentsop-llm-engine-selection]]. No → skip.)
app, or do you need UI+API+auth+logging out of the box? (Yes → consider a platform. No → code framework.)
[[agentsop-repo-state-gating]] then Aider/Cline/Cursor. This is orthogonal to L1–L7.)
layer has its own short decision tree; do not let one framework's gravity pull you into using it for a layer it is weak at.
the chosen pieces compose (additive, not same-layer collisions — §7 interop map), and run gate G0 on each layer to confirm a framework beats raw SDK there.
Output of the procedure: a one-line-per-layer decision, e.g. L1: raw prompts (will revisit DSPy at 30 labeled examples) · L2: LlamaIndex · L3: LangGraph · L6: hosted API (no self-host yet) · L7: none (code-first).
Before adopting any framework on a layer, confirm raw SDK is insufficient. Frameworks trade dependency-surface and a learning curve for batteries. Raw wins when the layer is trivial:
| Layer | Raw SDK wins when… | Framework wins when… | |---|---|---| | L1 | 1 LM call, no metric, verbatim-prompt audit need, rapid iteration | ≥2 calls, ≥30 labeled examples, a metric, model swaps dspy-sop · R5 | | L2 | corpus <100k tokens & static → stuff context + prompt cache | reimplementing >2 of {splitter, ingestion, reranker, synthesizer, evaluator} llamaindex-sop · R5 | | L3 | control flow expressible in plain if/else, no state-between-turns, no HITL | cycles, durable state, HITL, parallel topology langgraph-sop · R5 |
> "If the corpus is small (<100k tokens) and static → no framework needed. Stuff > the context window with prompt caching." llamaindex-sop · R5. "Plain LangChain > or raw SDK]: no cycles, no state-between-turns, no HITL — a single LLM call." > langgraph-sop · R5.
Mark each of L1/L2/L3/L6/L7 + coding-surface as needed or not, per §3 Pass A. This is the highest-leverage step: most "wrong framework" pain is actually "picked an L3 tool when the project was L2," or vice versa.
metric, and prompts are brittle on model swap. DSPy compiles prompts into a versioned artifact dspy-sop · R5. Combines additively into L3 (compile inside a LangGraph node) and L2 (compile the synthesizer downstream of a retriever).
(valid JSON / regex / BNF) on a single call. Orthogonal to DSPy: Outlines forces the shape, DSPy makes the prompt good dspy-sop · R5.
prompt-templates is a "smell" dspy-sop · R5).
~5-line baseline RAG, built-in evaluators, LlamaParse for messy documents llamaindex-sop · R5. Reach for it whenever private/large/changing data must be retrieved.
YAML-configurable pipelines are valued by ops llamaindex-sop · R5.
KG-RAG) is the literal bottleneck, not app assembly dify-sop · R5.
primitives (G0); otherwise you rebuild LlamaIndex badly llamaindex-sop · R5.
repo. Aider's symbol-map hits 70.3% file-selection on SWE-Bench Lite without an index aider-sop · R5. The SOPs disagree here (LlamaIndex assumes embeddings work for code; Aider's evidence says repo-map beats them) — for code, prefer the repo-map; for prose, prefer embeddings (§6).
First gate through [[agentsop-agent-topology-selection]] (single-agent + tools handles ~80% of "multi-agent" asks crewai-sop · DC-1). Then, if orchestration is needed:
create_react_agent (LangGraph),dspy.ReAct, a CrewAI single Agent, or a plain SDK tool loop. Start here.
human-in-the-loop (interrupt()), time-travel debugging, or supervisor/swarm/hierarchical parallelism langgraph-sop · R5. The 2026 production-reliability leader.
(researcher → writer → reviewer), non-engineers must read/edit agent definitions (YAML), and you want idea→demo fastest crewai-sop · R5. Trade-off: shallow state, thin eval, no built-in persistence.
some agency; staying in-ecosystem keeps retrieval primitives as first-class neighbors llamaindex-sop · R5.
pattern: prototype on CrewAI, port to LangGraph for production crewai-sop · R5.
maintenance mode as of 2026 — adopt with eyes open crewai-sop · R5, langgraph-sop · R5. OpenAI Swarm — study/reference only, not production.
If self-hosting open-weights models: hand off entirely to [[agentsop-llm-engine-selection]]. One-line summary of that skill's rubric: production+GPU+concurrent → vLLM (the 2026 default); prefix-heavy agent/RAG → A/B SGLang; NVIDIA-locked + 1–2wk budget → TensorRT-LLM; CPU/edge/≤1 user → llama.cpp; local dev → Ollama vllm-sop · R5, vllm-sop · OP-7. If calling a hosted API (OpenAI/Anthropic/…), skip L6 entirely.
+versioning in one box) and mixed-role teams (PM+ops+eng) co-author dify-sop · R5. Visual DAG with Code-node escape hatch.
beyond that dify-sop · R5.
and evolve (LangChain-bound) dify-sop · R5.
integrations) with AI sprinkled in, not AI-first dify-sop · R5.
HITL needs / >10 QPS/pod / extreme RAG / sub-second latency dify-sop · R5.
If the deliverable is code edits in a repo, gate through [[agentsop-repo-state-gating]] (Aider et al. are for existing repos; greenfield → plain LLM chat aider-sop · R5). Then: terminal + git-clean history + scriptable → Aider; per-tool-call approval in VS Code → Cline; visual/autocomplete + closed product → Cursor; cross-IDE → Continue; autonomous ticket→PR → OpenHands aider-sop · R5. This surface is orthogonal to L1–L7 — a coding agent uses L1–L6 internally.
Confirm chosen pieces compose. Additive (good): DSPy-in-node, LlamaIndex-retriever- as-tool, Dify-frontend + LangGraph-behind-HTTP, vLLM serving any of the above via its OpenAI-compatible API dspy-sop · R5, dify-sop · R5. Collisions (re-pick): two L1 prompt strategies; two L3 orchestrators owning the same control flow; a visual platform asked to do what its code-escape-hatch should.
Tension. Both are L3 orchestrators; they pick different first abstractions. LangGraph: "everything is a node in a state graph." CrewAI: "everything is a role on a team" crewai-sop · R5. The SOPs openly concede there is no clean rubric for the crossover — CrewAI itself recommends "prototype on Crew, port to LangGraph for production," which concedes the disagreement phase-b · open-questions.
Resolution. Decide on two axes:
handoffs and no branching/cycles, CrewAI Sequential is the faster path to a demo crewai-sop · R5.
threads, human-approval gate, time-travel debugging} is a hard requirement, go LangGraph — these are definitional there and absent/shallow in CrewAI langgraph-sop · R5.
a demo by Friday" → CrewAI crewai-sop · R5. The standard arc is prototype on CrewAI → port critical paths to LangGraph.
Tension. Framework gravity says "always use the framework." But every framework is a dependency surface and a learning curve, and on a trivial layer it is pure overhead dify-sop · R5 (Dify's own doc: "for teams whose bottleneck is expressive depth, Dify is overhead").
Resolution. Run G0 per layer. Raw SDK wins when: a single LM call with no cross-turn state and no metric (L1); a corpus under 100k tokens that fits in context with prompt caching (L2 llamaindex-sop · R5); control flow that fits in plain if/else with no HITL (L3 langgraph-sop · R5). The DSPy line-count table is instructive but not a reason to pick a framework — fewer lines on a task that doesn't need compilation is a false economy dspy-sop · R5. Pick the framework the moment you cross the threshold, not before.
Tension. Visual builders let PM/ops co-author and ship in days; code frameworks give expressive depth. Picking visual too early wastes the scaffolding savings; picking code too early excludes non-engineers dify-sop · R5.
Resolution. Start visual (Dify) when the bottleneck is scaffolding and a mixed-role team must operate the app; plan the code-escape hatch up front (Code nodes, or externalize logic behind HTTP). Migrate to a code framework when you hit Dify's stated ceilings: single graph >~40–50 nodes (canvas/comprehension collapse), need for pause-wait-resume / time-travel (Dify explicitly does not support HITL — issue #21455 "not planned"), sustained >10 QPS/pod, or extreme RAG experimentation dify-sop · R5, phase-b · open-questions. Note the threshold numbers are Dify-engine-specific and uncorroborated by other SOPs — treat as directional, not gospel (§6).
Tension. A "RAG agent" needs both L2 and L3; which framework do you build around? LlamaIndex frames itself as "the document agent platform" llamaindex-sop · R5; LangChain frames LangGraph as the production orchestrator langgraph-sop · R5. Both want to be the spine.
Resolution. Let the dominant difficulty lead. If the hard part is messy documents / retrieval quality, build around LlamaIndex (with LlamaParse) and add LangGraph only when agentic logic emerges. If the hard part is multi-step reasoning / many tools / durable state, build around LangGraph and embed LlamaIndex retrievers as one tool among many llamaindex-sop · R5. They are not competitors at the same layer — the error is forcing one to do the other's job.
articulating the problem ("let's build it in LangChain/CrewAI/Dify") and then bending the problem to fit. The fix is Pass A first: identify layers, then pick. The framework choice is downstream of the layer map, never upstream.
LangGraph to hand-roll retrieval, or DSPy to orchestrate, because it was the first tool installed. Each framework is strong on ~1 layer and mediocre off it dspy-sop · R5. Choose per layer; compose.
the same slot: DSPy + LangChain prompt-templates, two L3 orchestrators, or DSPy inside CrewAI agents (cultural mismatch — "prompt as config" vs "prompt as compiled artifact") dspy-sop · R5. Mixed same-layer adoption is "usually a smell."
~40 nodes, or demanding HITL / sub-second latency / extreme RAG from a visual platform that was never built for it dify-sop · R5. The fix is the planned code-escape hatch (DC-3), not more nodes.
different layer (L6); your LangGraph graph calls them through a model provider langgraph-sop · R5. Don't compare "LangGraph vs vLLM" — defer to [[agentsop-llm-engine-selection]].
(Microsoft pivoted to its Agent Framework); OpenAI Swarm and TGI are experimental / maintenance crewai-sop · R5, vllm-sop · R5. Adoption-risk is a first-class selection criterion, not a footnote.
Boundary — disagreements this skill does NOT resolve (surfaced honestly per phase-b · open-questions): the graph-vs-role crossover point (DC-1); Dify's specific node-count thresholds (DC-3, Dify-specific, uncorroborated); embeddings-vs-repo-map for code (OP-3 — likely "repo-map for code, embeddings for prose," but no single SOP states it); and whether JSON-tool-calls degrade non-code structured outputs (Aider's finding is code-specific — do not over-generalize).
The full layered map — which framework owns which layer, with interop notes:
| Layer | Primary owner(s) | Reach-past when… | Interop | |---|---|---|---| | L1 Modeling / compile | DSPy dspy-sop · R5 | grammar guarantees → Outlines/Guidance; single rapid call → raw | Additive into L2 (synthesizer) & L3 (in-node). Awkward with LangChain/CrewAI prompts (same-layer). | | L2 Retrieval | LlamaIndex llamaindex-sop · R5 | classical IR → Haystack; hard-doc RAG → RAGFlow; code → Aider repo-map | Retriever exposed as a tool to any L3 (LangGraph/CrewAI/AutoGen). | | L3 Orchestration | LangGraph (durable) / CrewAI (role) / Workflows (retrieval-native) langgraph-sop · R5, crewai-sop · R5, llamaindex-sop · R5 | single-agent suffices → drop to baseline; debate → AutoGen (maint-mode) | Calls L2 retrievers as tools; runs L1 (DSPy) inside nodes; served by L6. Gate via [[agentsop-agent-topology-selection]]. | | L6 Serving | vLLM (default) vllm-sop · R5 | prefix-heavy → SGLang; NVIDIA-locked → TensorRT-LLM; CPU/edge → llama.cpp; dev → Ollama | OpenAI-compatible API; any L1/L2/L3 above calls it transparently. Defer to [[agentsop-llm-engine-selection]]. | | L7 App platform | Dify dify-sop · R5 | single chatbot → Flowise; export-to-Python → LangFlow; automation-first → n8n | Hosts UI/API/auth; calls a code framework (LangGraph/CrewAI) or LlamaIndex behind HTTP for depth. | | Coding surface (cross) | Aider aider-sop · R5 | VS Code approval → Cline; visual → Cursor; cross-IDE → Continue; autonomous → OpenHands | Orthogonal product; uses L1–L6 internally. Gate via [[agentsop-repo-state-gating]]. |
Canonical additive stack (2026 consensus): DSPy compiles the LM calls → LlamaIndex retrieves → LangGraph orchestrates (with HITL + durable state) → vLLM serves the open-weights model → (optionally) Dify wraps the frontend/auth. Each piece is best-in-class on its layer and composes cleanly with the next dspy-sop · R5, llamaindex-sop · R5, dify-sop · R5.
The one-paragraph kickoff answer. Don't ask "which framework?" — ask "which layers does this project need, and what's the dominant difficulty on each?" Identify layers (Pass A), pick the best tool per layer with the §4 rubrics (Pass B), confirm they compose and that each layer actually clears the no-framework gate (Pass C). Defer serving to [[agentsop-llm-engine-selection]], multi-agent shape to [[agentsop-agent-topology-selection]], and coding-agent applicability to [[agentsop-repo-state-gating]]. The frameworks are layers; you are assembling a stack, not crowning a winner.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 22,611 | 33,922 | +50% | 1 | 1 | 0% | 3,813 | 9,621 | +152% | 0 | 0 | — |
case-02 | fail→pass | 26,267 | 23,324 | -11% | 1 | 1 | 0% | 4,085 | 10,338 | +153% | 0 | 0 | — |
case-03 | fail→fail | 16,911 | 19,342 | +14% | 1 | 1 | 0% | 2,878 | 9,608 | +234% | 0 | 0 | — |
case-04 | pass→pass | 11,618 | 11,936 | +3% | 1 | 1 | 0% | 2,276 | 8,792 | +286% | 0 | 0 | — |
case-05 | pass→pass | 10,005 | 8,231 | -18% | 1 | 1 | 0% | 1,832 | 8,026 | +338% | 0 | 0 | — |
case-06 | pass→pass | 7,279 | 5,677 | -22% | 1 | 1 | 0% | 1,402 | 7,581 | +441% | 0 | 0 | — |
case-07 | fail→fail | 15,745 | 12,663 | -20% | 1 | 1 | 0% | 2,418 | 8,441 | +249% | 0 | 0 | — |
case-08 | pass→pass | 16,948 | 14,109 | -17% | 1 | 1 | 0% | 2,650 | 8,649 | +226% | 0 | 0 | — |
case-09 | pass→pass | 12,830 | 12,252 | -5% | 1 | 1 | 0% | 2,056 | 8,435 | +310% | 0 | 0 | — |
case-10 | fail→fail | 29,576 | 7,754 | -74% | 1 | 1 | 0% | 2,314 | 7,717 | +233% | 0 | 0 | — |
case-11 | pass→pass | 12,045 | 9,962 | -17% | 1 | 1 | 0% | 2,040 | 8,106 | +297% | 0 | 0 | — |
case-12 | pass→pass | 16,117 | 9,207 | -43% | 1 | 1 | 0% | 2,459 | 7,878 | +220% | 0 | 0 | — |
case-13 | pass→pass | 12,268 | 8,687 | -29% | 1 | 1 | 0% | 1,974 | 7,867 | +299% | 0 | 0 | — |
case-14 | pass→pass | 20,240 | 13,640 | -33% | 1 | 1 | 0% | 3,035 | 8,556 | +182% | 0 | 0 | — |
case-15 | fail→pass | 30,990 | 7,910 | -74% | 1 | 1 | 0% | 1,394 | 7,807 | +460% | 0 | 0 | — |
case-16 | pass→pass | 15,486 | 8,718 | -44% | 1 | 1 | 0% | 2,280 | 7,881 | +246% | 0 | 0 | — |
case-17 | fail→pass | 16,752 | 11,776 | -30% | 1 | 1 | 0% | 2,508 | 8,426 | +236% | 0 | 0 | — |
case-18 | fail→pass | 22,591 | 16,738 | -26% | 1 | 1 | 0% | 3,559 | 9,270 | +160% | 0 | 0 | — |
case-19 | fail→pass | 18,480 | 11,823 | -36% | 1 | 1 | 0% | 3,027 | 8,367 | +176% | 0 | 0 | — |
case-20 | pass→pass | 14,462 | 10,825 | -25% | 1 | 1 | 0% | 2,270 | 8,237 | +263% | 0 | 0 | — |
case-21 | fail→pass | 20,106 | 13,568 | -33% | 1 | 1 | 0% | 3,122 | 8,610 | +176% | 0 | 0 | — |
case-22 | pass→pass | 17,238 | 7,073 | -59% | 1 | 1 | 0% | 2,512 | 7,562 | +201% | 0 | 0 | — |
case-23 | pass→pass | 16,247 | 15,047 | -7% | 1 | 1 | 0% | 2,567 | 8,853 | +245% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 23 cases were attempted, and 22 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +30 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.