Adding Agent Skills to LangChain/LangGraph: Engineering Trade-offs Between Context, Caching, and Artifacts

Three architectural decisions matter more than the skill loader itself when adding Agent Skills to LangChain/LangGraph.
This article summarizes three core architectural lessons from implementing Agent Skills in Cameron, an open-source financial agent built on LangChain/LangGraph. First, decouple instruction loading from tool loading — keep a stable tool set to benefit from Prompt Caching, but use evals to detect activation failures where the model skips skills. Second, route large display data (like charts) via LangChain Artifacts directly to the UI rather than through the model, and maintain that separation during conversation history replay. Third, when a skill is fundamentally a decision-guidance layer over existing tools, no new runtime infrastructure is needed. The post closes with an open question: how to optimally balance caching (requiring stable tools) against per-task tool minimization.
When building AI agents, figuring out how to let models load skills on demand — without sacrificing caching efficiency or response speed — is a challenge that most developers eventually run into. One open-source developer working on Cameron, a financial agent built on LangChain/LangGraph, documented three architectural decisions that turned out to matter far more than the skill loader code itself. These lessons are highly relevant to any team looking to implement a skill system within the LangChain ecosystem.

What Are Agent Skills and Why Do They Matter
The core idea behind Agent Skills is to decouple task-specific instructions from the model's fixed context, loading them only when needed. The benefit is clear: the model doesn't need to carry a large set of instructions it may never use in a given conversation, saving precious context window space.
But the real challenge isn't writing a skill loader — it's managing the trade-offs between loading strategy, data routing, and runtime control. In building Cameron, the author found that these three decisions directly determine the system's performance and reliability.
Decision 1: Load Instructions On Demand, But Make Tool Loading a Separate Choice
The first key insight is to decouple "instruction loading" from "tool loading." The author chose to maintain a small, stable tool set on the frontend. The immediate payoff: eligibility for Prompt Caching — stable, unchanging tool definitions can be cached, reducing redundant computation and token costs.
There's a clear trade-off here: unused tools still consume context space, and the model may attempt to execute tasks without first reading the corresponding skill instructions. This "skip the skill and just go" behavior is a classic activation failure.
To address this risk, the author wrote a dedicated eval to detect whether the model actually reads the skill when it should. This is a worth borrowing: rather than assuming the model will follow the intended flow, use measurable evaluations to verify that behavior matches design intent.
Prompt Caching refers to a feature offered by LLM providers (such as Anthropic Claude and OpenAI GPT-4o) that caches repeated prefix content in requests — subsequent requests that hit the cache see dramatically lower compute costs and latency. With Anthropic, for example, cached token costs are roughly 10% of uncached tokens, and time-to-first-token can drop by hundreds of milliseconds. For caching to trigger, prompt content must remain highly consistent across requests — which is exactly the technical motivation behind "maintaining a stable tool set." If tool definitions are dynamically added or removed on every request, the prefix hash changes and the cache is invalidated. A stable tool set is therefore not just an architectural simplicity choice; it's an explicit engineering decision to trade stability for performance and cost gains through caching.
Decision 2: Put Display Data in Artifacts — Don't Route It Through the LLM
The second lesson is about data routing efficiency. In a financial agent context, chart data can be substantial in volume. Routing raw data rows back and forth through the LLM wastes tokens and slows responses.
The author's approach: the agent is responsible only for providing the query and chart spec, while the tool sends chart data directly to the UI as a LangChain artifact — returning only a brief confirmation to the model. This way, hundreds or thousands of rows of data never need to "pass through" the model's context.
Going further, the author emphasizes maintaining this separation during replaying conversation history as well. This is an easy point to miss — if historical replay re-injects artifact data back into the model's context, all the savings are undone. Keeping a clear boundary between display data and model conversation is key to sustaining performance over long sessions.
LangChain Artifact is a mechanism in LangChain's message protocol that allows tools to pass structured data (such as chart datasets or binary file content) to the frontend UI through a separate channel, while returning only a text summary to the model — rather than serializing the full data into the model's context. This contrasts with the traditional pattern where tool return values go directly into conversation history. In a financial agent context, the underlying data for a candlestick chart might contain thousands of OHLCV records; injecting that fully into the context not only consumes large numbers of tokens but also accumulates into serious context bloat over multi-turn conversations. The Artifact mechanism decouples "rendering data for humans" from "decision summaries for the model" — an important pattern for handling rich media output.
Decision 3: Let the Workflow Determine the Runtime
The third decision reflects a deeper understanding of what skills actually are. In Cameron, the reporting skill teaches report decision logic built on top of existing tools — it doesn't introduce new execution capabilities.
Because there are already tested UI components responsible for rendering charts, supporting this skill doesn't require adding a sandbox or filesystem tools. In other words, the skill's job is to guide the model on "how to use existing tools well," not to extend the underlying runtime.
This "let the workflow determine the runtime" mindset is instructive: not every new skill requires new infrastructure. When a skill is fundamentally a layer of decision guidance, reusing validated components reduces complexity and lowers the risk of introducing new attack surfaces and bugs.
An Open Question for the Community
The author closes with an engineering trade-off worth deeper discussion: How do you balance maintaining a stable tool set for caching against exposing fewer tools per task?
This is a classic tension in agent design. A stable tool set benefits caching and consistency, but occupies context and may tempt the model to skip skills. A dynamically trimmed tool set reduces noise, but sacrifices caching gains. There's no single right answer — the optimal choice typically depends on the specific task distribution and latency/cost requirements.
The author has documented the full architecture, trade-off analysis, and activation failure cases, with example code in both TypeScript and Python. For developers building skill systems on LangChain/LangGraph, this kind of experience distilled from a real open-source project is more actionable than an abstract list of best practices.
This trade-off is sometimes called the Tool Selection Problem in academic and engineering circles, and has a structurally similar form to the "retrieval granularity" problem in RAG: retrieve too much and you introduce noise; retrieve too little and you risk missing critical capabilities. One middle-ground approach is a tiered tool set — maintaining a minimal "core tool set" that benefits from caching, while dynamically appending task-specific tool descriptions in the non-cached section of the system prompt via the skill loading mechanism, so the model has full instructional context before deciding whether to invoke a tool. However, this requires precise control over cache breakpoint positions within the prompt structure, which is complex to implement — and different model providers currently vary in their ability to control cache boundaries, so no universal best practice has emerged yet.
Related articles

Uber Deploys ChatGPT Work Company-Wide: AI in the Workplace Enters the Scaled Implementation Phase
Uber deploys ChatGPT Work to 30,000+ employees, extending it from engineering to all roles. We analyze its expert-engineer pairing, end-to-end automation, and questions of AI control and power concentration—insights for scaling AI in the workplace.

Shift at Midnight Hands-On: When "ID Verification" Becomes Alien Hunting
Shift at Midnight blends ID verification with horror survival in a four-player co-op game. We break down its inspection mechanics and chaotic humor.

Zelensky Recounts the Outbreak of War: I Need Ammunition, Not a Ride
Zelensky recalls the first day of war in a YouTube interview: farewell to family, rejecting Biden's evacuation offer with "I need ammunition, not a ride," and how Bucha shaped his stance on compromise and peace talks.