All Posts

Skills vs LangChain, LangGraph, MCP, and Tools: A Practical Architecture Guide

LangChain/LangGraph run workflows, MCP exposes capabilities, tools do actions, and skills package outcomes.

Abstract AlgorithmsAbstract Algorithms
ยทยท10 min read
Share
Share on X / Twitter
Share on LinkedIn
Copy link

TLDR: These are not competing ideas. They are layers. Tools do one action. MCP standardizes access to actions and resources. LangChain and LangGraph orchestrate calls. Skills package business outcomes with contracts, guardrails, and evaluation. Most production confusion comes from mixing these layers.


๐Ÿ“– The Layer Cake: What Each Term Actually Means

People often ask: "Are skills better than LangGraph?" That question is like asking whether APIs are better than databases. They solve different problems.

Use this mental model:

LayerMain question it answersTypical artifact
Tool"What single action can I execute?"Function or API adapter
MCP"How do I discover and call capabilities across systems?"Protocol server + typed schemas
LangChain"How do I compose prompts, tools, and model calls quickly?"Chains, agents, callbacks
LangGraph"How do I run stateful multi-step workflows reliably?"Graph nodes, edges, checkpoints
Skill"How do I deliver a stable product outcome?"Reusable capability contract

A skill is usually built on top of the other layers, not instead of them.

Example:

  • Tool: fetch_customer_profile(customer_id)
  • Tool: check_subscription_status(customer_id)
  • Tool: create_support_ticket(payload)
  • MCP: exposes those tools from remote services with common schemas
  • LangGraph: coordinates retries and branching
  • Skill: AccountRecoverySkill returns a structured, policy-safe resolution

If you skip the skill layer, your app can still run. But behavior often becomes prompt-heavy and hard to govern.


๐Ÿ” Where LangChain and LangGraph Fit, and Where They Do Not

LangChain and LangGraph are implementation frameworks. They help you execute reasoning and workflows. They do not automatically define product-level ownership, risk boundaries, or capability lifecycle.

ConcernLangChainLangGraphSkill layer
Fast prototypingStrongGoodMedium
Stateful executionLimited by design patternStrongDepends on runtime
Retry orchestrationBasicStrongPolicy-driven
Business contract (input/output guarantees)ManualManualFirst-class
Capability ownership/versioningExternal processExternal processFirst-class
Governance and risk-tier mappingExternal processExternal processFirst-class

Why teams get confused:

  1. They build one graph and call it a "skill".
  2. They add one tool description and assume governance is done.
  3. They treat protocol access (MCP) as business capability modeling.

Good architecture separates these concerns.

  • Frameworks run computation.
  • Skills define outcome boundaries.

โš™๏ธ End-to-End Execution Path: How the Layers Collaborate

Let us trace one request: "Investigate payment failure spikes and open an incident if needed."

flowchart TD
    A[User request] --> B[Router chooses PaymentIncidentSkill]
    B --> C[Skill validates input and policy]
    C --> D[LangGraph executes workflow state]
    D --> E[Node calls tools via MCP]
    E --> F[Collects logs metrics and ticket status]
    F --> G[Skill output validation]
    G --> H[Final structured response plus trace]

This flow exposes the distinction clearly:

  • LangGraph is the runtime engine for state transitions.
  • MCP is the interoperability channel for tools/resources.
  • Tools are atomic actions.
  • Skill wraps the whole thing as a reusable product capability.

Mini dataset for one run:

StepLayer activeInputOutput
1Skillservice=payments, window=15mValidated request object
2LangGraphSkill stateExecution path
3MCP + Toolfetch_error_rateerror_rate=8.7%
4MCP + Toolcreate_incident_ticketticket_id=INC-9012
5SkillAggregated stateStable JSON result

The skill result is what downstream products depend on. That is why skills should own output contracts.


๐Ÿง  Why Layer Confusion Breaks Production Systems

Internals: control plane vs execution plane

A useful split:

  • Control plane: registry, routing policy, risk gating, rollout rules
  • Execution plane: LangGraph graph run, MCP calls, tool invocation, retries

If everything is put in execution code, every team ships its own hidden policy logic. That creates drift.

PlaneWhat changes oftenWhat should stay stable
Control planeRouting thresholds, risk policy, capability ownershipGovernance model
Execution planeNode logic, model choice, retries, tool adapter detailsSkill contract

Skills sit at the boundary and stabilize product expectations while execution internals evolve.

Mathematical model: route score vs policy eligibility

A practical routing pattern:

$$ Eligible(s, q) = PolicyAllow(s, q) \land PermissionAllow(s, q) $$

Then score only eligible skills:

$$ Score(s \mid q) = a \cdot Fit - b \cdot Latency - c \cdot Risk + d \cdot Reliability $$

And choose:

$$ s^* = \arg\max_{s \in S, Eligible(s,q)} Score(s \mid q) $$

This keeps policy decisions explicit and auditable.

Performance analysis: where latency is spent

ComponentTypical latency shareNotes
LLM reasoning callsHighPrompt and model dependent
Tool/MCP network I/OMedium to highDominant in API-heavy skills
Orchestration overheadLow to mediumUsually acceptable trade for reliability
Validation and output shapingLowWorth it for contract safety

A common mistake is optimizing graph overhead while ignoring remote tool latency. Measure the right bottleneck.


๐Ÿ“Š Sequence View: Tool-Only Agent vs Skill-Centric Agent

sequenceDiagram
    participant U as User
    participant A as Agent
    participant G as LangGraph Runtime
    participant M as MCP Server
    participant T as Tool API
    participant S as Skill Contract

    U->>A: "Investigate billing failures"
    A->>S: select(BillingIncidentSkill)
    S->>G: execute(skill_state)
    G->>M: call(fetch_metrics)
    M->>T: invoke tool
    T-->>M: metrics
    M-->>G: typed result
    G->>M: call(open_incident)
    M->>T: invoke tool
    T-->>M: ticket id
    M-->>G: typed result
    G-->>S: final state
    S-->>A: contract-valid output
    A-->>U: summary + ticket link

A tool-only approach may skip S and return free-form text. That is fast to demo, but risky for integrations that expect strict output fields.


๐ŸŒ Real-World Patterns That Make This Practical

Pattern 1: Product support copilot

  • Tools: CRM lookup, order API, refund API.
  • MCP: centralizes access to those systems.
  • LangGraph: executes decision branches (refund eligible or not).
  • Skill: RefundResolutionSkill returns decision, reason, next_action.

Pattern 2: Security triage assistant

  • Tools: SIEM query, IOC enrichment, ticketing.
  • LangGraph: handles iterative enrichment loop.
  • Skill: AlertTriageSkill enforces policy that high-risk actions require human approval.

Pattern 3: Data analyst copilot

  • Tools: SQL execution, chart rendering, metadata lookup.
  • MCP: gives one protocol for multiple data backends.
  • Skill: KPIExplainerSkill guarantees output schema with query, metric, confidence, limitations.
Use caseWhy tool-only strugglesWhy skill-centric works
Support automationInconsistent output fieldsStable contract for downstream workflow
Security operationsUnsafe autonomous actionsRisk policy encoded at skill boundary
Analytics Q&AHallucinated field namesValidated query and structured explanation

โš–๏ธ Trade-offs and Failure Modes

You should not force everything into skills. Keep the cost-benefit clear.

ChoiceBenefitCost
Tool-only for simple tasksFast implementationLow reuse and weak governance
Full skill contracts for critical tasksReliability and observabilityMore design and lifecycle work
Heavy graph abstraction everywhereUniform runtime patternsOverhead for trivial features

Common failure modes:

  1. Skill inflation: too many overlapping skills with unclear ownership.
  2. Framework lock-in confusion: capability modeled in framework internals only.
  3. Policy leakage: risk rules hidden in prompts instead of explicit control plane.
  4. Protocol overconfidence: assuming MCP alone gives governance.

Mitigations:

  • maintain a capability taxonomy,
  • enforce input/output schemas,
  • version skills separately from graph internals,
  • keep policy checks outside prompt-only logic.

๐Ÿงญ Decision Guide: What to Build at Your Current Maturity

Your current stageRecommended next step
1 to 3 tools, single team prototypeStart with LangChain/LangGraph and basic telemetry
5 to 15 tools, repeated user journeysIntroduce explicit skill contracts
Multi-team platform with compliance needsAdd skill registry, policy gates, and evaluation loops
High-risk automation (finance/security/health)Skill-first design with human approval paths

Quick rule set:

QuestionIf yesIf no
Is the task multi-step with branching?Use LangGraphSimple chain/tool call may be enough
Does output feed another system?Define skill contractFree-form output may be acceptable
Are there risk or compliance constraints?Add policy-gated skill routingKeep lighter execution model
Will this capability be reused by many teams?Register as skillKeep as local orchestration

๐Ÿงช Practical Example: One Capability Across All Layers

Example 1: Tool and MCP-facing adapter

# Tool function signature

def fetch_payment_metrics(service: str, window_minutes: int) -> dict:
    return {
        "service": service,
        "window_minutes": window_minutes,
        "error_rate": 0.087,
        "p95_latency_ms": 1230,
    }

# In practice this tool may be exposed through an MCP server with typed schemas.

Example 2: LangGraph workflow plus skill boundary

from dataclasses import dataclass

@dataclass
class PaymentIncidentInput:
    service: str
    window_minutes: int

def payment_incident_skill(payload: PaymentIncidentInput) -> dict:
    # 1) Validate boundary
    if payload.window_minutes <= 0:
        raise ValueError("window_minutes must be positive")

    # 2) Graph execution would happen here
    metrics = fetch_payment_metrics(payload.service, payload.window_minutes)

    # 3) Policy gate
    must_open_incident = metrics["error_rate"] >= 0.05

    # 4) Stable contract
    return {
        "service": payload.service,
        "error_rate": metrics["error_rate"],
        "incident_required": must_open_incident,
        "reason": "error_rate_threshold_breached" if must_open_incident else "within_limits",
    }

This code is simple, but the design principle is important: output contract remains stable even if runtime internals change.


๐Ÿ“š Lessons Learned from Teams Shipping Agents

  • Tools, protocols, frameworks, and skills are complementary layers.
  • Framework quality does not replace capability modeling discipline.
  • MCP improves interoperability, not product governance by itself.
  • Skills reduce prompt sprawl by encoding reusable outcome contracts.
  • Keep control plane concerns explicit: ownership, risk tier, version, and evaluation.
  • Design for debuggability: capture route decisions and contract validation failures.

๐Ÿ“Œ Summary and Key Takeaways

  • Tool is an atomic action.
  • MCP is a standard way to expose and call capabilities.
  • LangChain and LangGraph orchestrate execution.
  • Skill is a product-level capability contract with policy and stable outputs.
  • Most production reliability gains come from adding skill boundaries, not from switching frameworks.
  • Build layers incrementally: execution first, then contract and governance as reuse and risk grow.

One-liner: LangGraph and MCP help you run workflows; skills help you ship dependable capabilities.


๐Ÿ“ Practice Quiz

  1. Which option best describes MCP? A) A replacement for tools B) A protocol for capability and resource access C) A model fine-tuning method

    Correct Answer: B

  2. Why is a skill different from a LangGraph workflow? A) Skills cannot call tools B) LangGraph is runtime orchestration, while skills define outcome contracts and policy boundaries C) Skills only work with one LLM provider

    Correct Answer: B

  3. You have one low-risk, single-step action. What is usually enough? A) Full skill registry and complex routing B) Simple tool call, optionally wrapped in a lightweight chain C) Two nested graphs

    Correct Answer: B

  4. Open-ended: Pick one workflow in your project and define where each layer belongs: tool, MCP, orchestration runtime, and skill contract.


Abstract Algorithms

Written by

Abstract Algorithms

@abstractalgorithms