Back to blog
AI Trending May 31, 2026 · 6 min read

Deep Agent — What I Learned Building Agent Harnesses with LangChain's New Framework

A practical walkthrough of Deep Agent, the Agent Harness framework built on LangChain Core and LangGraph Runtime — covering planning, file systems, MCP integration, and RAG patterns.

#Deep Agent #LangChain #agent harness #MCP #RAG #AI agents #ChromaDB

I’ve been building agentic systems for a while — my second-brain and doppelganger projects both revolve around giving LLMs structured memory and tool access. Recently I came across a deep dive by mikelopster on Deep Agent, an Agent Harness framework built on LangChain Core and LangGraph Runtime. It clarified a lot of design decisions I’d been wrestling with.

Here’s what I learned.

What Deep Agent Is

Deep Agent sits on top of the LangChain ecosystem as the highest-level abstraction:

Deep Agent    ← Agent Harness (planning, skills, memory, MCP)

LangChain     ← Components (tools, prompts, document loaders)

LangGraph     ← Runtime (state, checkpointing, human-in-the-loop)

LangChain gives you the building blocks — tool definitions, prompt templates, document loaders. LangGraph handles state machines, checkpointing, and branching workflows. Deep Agent wraps both and adds built-in capabilities that you’d otherwise have to code yourself:

The key insight: Deep Agent comes with these capabilities built in. You don’t implement planning logic or file system tools from scratch — you configure them through system prompts and the agent orchestrates the rest.

Example 1: Basic Deep Agent

The simplest Deep Agent pattern is wrapping functions as tools and handing them to the agent:

from langchain_deep_agent import create_deep_agent

def search_database(query: str) -> str:
    """Search the internal database for information."""
    # ... implementation
    return results

agent = create_deep_agent(
    model="gemini-2.0-flash",
    tools=[search_database],
    system_prompt="You are a helpful assistant. Always plan before acting.",
)

The create_deep_agent function is the entry point. It accepts tools (just like LangChain tools), a system prompt, and a model. But unlike plain LangChain, Deep Agent automatically enables planning, file system operations, and step-by-step execution — you get them for free.

Example 2: Agents.md & Skills

This is where it gets interesting. Deep Agent supports a memory and skills system through structured markdown files. The concept is simple:

# agent.md

## Memory
- User prefers Python code examples over pseudocode
- Last project was about investment analysis
- Current focus: LLM tooling and agentic systems

## Skills
- database_query: skills/database.md
- file_analysis: skills/file-tools.md

When you ask the agent something, it checks its memory folder first. If it finds relevant agent.md files or skills, it loads them into context. This is exactly the pattern I used in my doppelganger agent — structured memory that persists across sessions.

The two key concepts are:

  1. memory — stores facts, preferences, and session context
  2. skills — loads specialized tools and behaviors on demand

This means you can build an agent that grows its capabilities over time by writing new skill files, without modifying the core agent code.

Example 3: MCP Integration

Model Context Protocol (MCP) is a standard for connecting LLMs to external tools. Deep Agent natively supports MCP through a MultiServerMCPClient adapter:

from langchain_deep_agent import create_deep_agent
from langchain_deep_agent.mcp import MultiServerMCPClient

# Wrap MCP servers as tools
client = MultiServerMCPClient()
mcp_tools = client.get_tools()

agent = create_deep_agent(
    model="gemini-2.0-flash",
    tools=[*mcp_tools],
    system_prompt="You are a web automation agent.",
)

The MultiServerMCPClient connects to MCP servers via stdio or HTTP, discovers their available tools, and presents them to Deep Agent as regular tool functions. This means any MCP server — Playwright for browser automation, filesystem access, database queries — becomes instantly available to your agent.

In the demo, the agent navigated a browser using Playwright MCP to scrape GitHub trending repos, taking snapshots before every action to check the DOM. Even when the initial attempt failed (the page had bot protection), the fallback to a simpler site showed the pattern clearly: the agent plans, navigates, snapshots, clicks, and summarizes — all orchestrated through MCP tools.

Example 4: RAG with ChromaDB

The last example showed how to combine Deep Agent with a vector database for retrieval-augmented generation. The setup was an animal image search using ChromaDB:

from chromadb import PersistentClient

def search_animal_images(query: str, n: int = 3) -> list:
    """Search for animal images by text description."""
    collection = client.get_collection("animal_images")
    results = collection.query(query_texts=[query], n_results=n)
    return results

agent = create_deep_agent(
    model="gemini-2.0-flash",
    tools=[search_animal_images],
    system_prompt="""You are an animal search assistant.
Use search_animal_image to find animals from text descriptions.
Always plan before taking action.""",
)

The key design decision here is letting the agent decide when to use RAG. Instead of a rigid retrieval → generation pipeline, the agent treats the vector search as just another tool. It plans whether to search, what query to use, and how to present the results — all guided by the system prompt.

This is more flexible than traditional RAG pipelines. If the agent’s memory already contains the answer, it can skip retrieval entirely. If it needs to disambiguate, it can try multiple queries. The system prompt acts as the controller, and the agent’s planning capability handles the orchestration.

Why This Matters for Agent Builders

Watching this deep dive confirmed several patterns I’ve been applying in my own work:

  1. Agent Harness as an abstraction — Deep Agent shows that the right level of abstraction for most agent work isn’t LangGraph’s state machines (too low-level) or LangChain’s tool chains (too simplistic). It’s the Agent Harness layer: planning + file system + sub-agents + memory, configured through prompts.

  2. File system as memory — Instead of complex vector databases for every use case, well-organized markdown files in folders can serve as perfectly good memory for many scenarios. The agent can read, write, and edit its own memory files — just like my doppelganger does.

  3. MCP is the universal plugin — The MCP integration pattern (wrap → discover → use) means your agent can connect to any tool ecosystem. I’m planning to expose my doppelganger’s memory layer as an MCP server so any client can consume it.

  4. RAG is a tool, not a pipeline — Making retrieval just another function call that the agent decides to use is more robust than forcing every input through a retrieval step.

If you’re building agentic systems, I’d recommend watching the full video (it’s in Thai with helpful visual walkthroughs). The Deep Agent framework is worth studying even if you don’t use LangChain — the patterns for planning, tool orchestration, and structured memory transfer across any agent stack.


← All posts dot8pixels.dev