記事一覧へ
あなたはプロダクションAIエージェントの構築方法を既に知っている。自分でそれと気づいていなかっただけだ。
先週スパイクを走らせた。同じCLAUDE.md、同じスキル、同じMCP、同じフック。毎日Claude Codeで編集しているものそのままで。午後一つで動くナレッジチャットボットを出荷した。新しいフレームワークゼロ。十数回書いていないファイルもゼロ。
皆はビルドやナレッジワークを支援するエージェントを取り上げている。誰も命名していないパターン: 同じプリミティブがプロダクションランタイムだ。
## 1. 欠けているパターン: 呼び出し可能コンポーネントとしてのエージェント
二つのナラティブが支配している:
- エージェント as プロダクト: Claude Code、Lovable、Cursor
- エージェント as インフラ: LangGraph、crewAI、Autogen
三つ目のカテゴリは誰も話していない: エージェント as 呼び出し可能コンポーネント。
Claude Codeで作業するとき、あなたは全く新しいクラスのオブジェクトを作っている。それは実行するだけでなく、コンポーネントを呼び出し、状態を保持し、構成可能で、決定論的に動作できる。
これがパターンだ:
- スキル = メソッドシグネチャ
- フック = ミドルウェア
- CLAUDE.md = システムプロンプト
- サブエージェント = 並列ワーカー
## 2. ビルドからランに移行する: 同じプリミティブ、異なるモード
違いは何か?モードだ。
ビルドモードでは、スキルを使ってClaude CodeにCLAUDE.mdを書かせる。ランモードでは、CLAUDE.mdをClaude Codeに読ませてユーザークエリを処理させる。
ビルドモードとランモードの両方で、私は次のものに触れている:
- 同じCLAUDE.md構造
- 同じスキルパターン
- 同じMCP設定
- 同じフックシステム
違いは意図だ。ビルドモードでは、私はClaudeと会話しながら作業する。ランモードでは、Claudeがエンドユーザーと会話する。ランタイムは同じだ。
## 3. スパイクが教えてくれたこと
午後中、私はClaude Codeに次のことをさせた:
1. Notionエクスポートをチャンク化する
2. セマンティックインデックスを作成する
3. クエリを受け取る
4. 関連チャンクを取得する
5. コンテキストウィンドウに合成する
6. 回答を生成する
使ったもの:
- CLAUDE.md: ドメインとトーンを定義
- スキル: チャンキングとランキングロジック
- MCP: 取得レイヤーのベクターDB
- フック: 送信前に回答をサニタイズ
新しいものは何もない。これが要点だ。
## 4. なぜこれが重要なのか
このパターンが重要な理由は三つある:
**移植性**: 同じスキルをビルドモードとランモードの両方で使える。プロジェクトが変わっても、プリミティブは変わらない。
**可観測性**: Claude CodeのフックとMCPログは完全な監査証跡を提供する。商用エージェントフレームワークよりも良い。
**コンポーザビリティ**: スキルは組み合わせられる。スキルAがスキルBを呼び出せる。ランモードも同じだ。
## 5. あなたへのチャレンジ
Claude Codeを開いて、自分の.claude/フォルダを見てほしい。
そこに何があるか?CLAUDE.md、スキル、MCP設定、フック。それが問いかけだ。これをプロダクションエージェントのランタイムに変換するために何が必要か?
予想よりも少ないはずだ。

claude-setupagent-opsharness-design
.claude/フォルダは本番AIエージェント
♥ 93↻ 8
原文を表示 / Show original
You already know how to build production AI agents. You just didn't know it counted.
Last week I ran a spike. Same CLAUDE.md, same skills, same MCPs, same hooks I edit every day in Claude Code. Shipped a working knowledge chatbot in an afternoon. Zero new framework. Zero files I hadn't written a dozen times.
Everyone's covering agents that help you build or do knowledge work. The pattern nobody's naming: the same primitives are the production runtime.
1. The Missing Pattern: Agent as A Callable Component
Two narratives dominate:
Agents as products. Claude Code, Lovable, Cursor.
Agents as infrastructure. LangGraph, Managed Agents, CrewAI.
The pattern sitting between them is agent as a callable component inside your app.
How does it work?
Agent as A Callable Component
Your web app handles routing, auth, CRUD, form validation. When a request needs reasoning, you call the agent. The agent runs in a sandbox with its own CLAUDE.md, skills, and MCP servers.
The surprise: the .claude/ folder I've been editing every day for months is the deployable unit. No translation layer between dev and prod. The CLAUDE.md that guides Claude Code in your terminal is the exact same format that runs in production.
2. The Five Primitives
You already know all of these.
CLAUDE.md. The agent's identity in markdown. Tone, rules, constraints. In dev it shapes Claude Code in your terminal. In prod it loads as the system prompt.
Skills (.claude/skills/). Reusable behaviors, also markdown. Same file format dev and prod. Same loader.
MCPs (.claude/mcp.json). Servers that extend the agent's tool surface. Your dev config talks to Chrome and filesystem. Your production config talks to your search API and database. Different servers, identical contract.
Hooks. Functions that fire on tool events. PreToolUse blocks dangerous ops (reading .env, path traversal). PostToolUse logs everything the agent read so you can show it in the UI.
Sub-agents (.claude/agents/<name>/). Each folder is a self-contained agent. Its own CLAUDE.md, its own skills, its own MCP config. Adding a second agent is a new folder.
Sub-agents in Claude Code
Everything is files. Everything version-controls. Everything diffs in a PR.
In case you wondered, here’s a bigger picture:
Claude Code projects
3. Why This Matters: Agent SDK vs. The Alternatives
Here’s how it stacks up against the alternatives:
Agent SDK vs. Managed Agents vs. LangGraph vs. n8n
Four things fall out of this that I didn't expect going into the spike.
Nothing new to learn. The CLAUDE.md you wrote in dev is the CLAUDE.md that ships. Your muscle memory is already the production runtime.
Skip Managed Agents if you already host. For request-response agents inside an app you already run, the SDK is a smaller dependency than a whole platform.
Full observability. Hooks give you live per-response metadata: cost, duration, files read. OTEL exports full traces to Langfuse or any OTLP backend.
Same loop, dev to prod. The config you tested in Claude Code is the config in production. If it worked in your terminal, it works in your app.
Now the part most people skip: how you actually wire it up.
4. The Architecture: One Function Replaces a Workflow
In n8n you wire it up node by node. A single agent has system prompt, LLM, model, tools, and memory.
A single Claude agent isn’t a workflow. Inside an app, you don’t need a node-by-node graph around it. A simple orchestration and guardrails can live in your hooks or your business logic.
In the Anthropic Agent SDK it's this:
javascript
for await (const msg of query({
prompt: question,
options: {
cwd: './.claude/agents/knowledge-agent',
settingSources: ['project'],
allowedTools: ['Read', 'Glob', 'Grep'],
maxTurns: 5,
maxBudgetUsd: 0.15,
model: 'claude-sonnet-4-6',
hooks: { /* guardrails */ },
},
})) {
// stream text, collect metadata
}
settingSources: ['project'] is the auto-loader. It reads the agent's CLAUDE.md, skills, and MCP config from cwd. Same behavior Claude Code has when it opens a session. You don't manually load anything.
Your app owns the request lifecycle, auth, storage. The agent owns reasoning, tool selection, iteration. One function sits on the seam. That's the orchestration layer.
One thing to watch out for. You’ll likely want a root CLAUDE.md - the one that helps Claude Code maintain the app in your IDE. It’s dev-only; it has nothing to do with the production agent. Remove it in postbuild.
5. The Demo: A Knowledge Chatbot
I built the smallest thing that shows the pattern. A web app with markdown files and a chatbot that answers questions from those files, with memory across turns.
The agent lives in its own directory. The app calls it with one function.
The knowledge agent in VS Code
Stack:
Next.js 15 standalone. Not serverless. The SDK spawns a full Claude Code runtime, not a lightweight API client.
SQLite for conversation memory because this is a prototype. Postgres, Redis, a JSON file on disk. All fine.
Adding a second agent? New folder in .claude/agents/. Give it a CLAUDE.md. Point cwd at the new directory. Same structure every time.
6. Closing
This is what lets you prototype and ship agent features without becoming a bottleneck. Changing the agent's behavior is editing a markdown file. Not a sprint. Not a code review. Not a redeploy cycle.
The gap between “I use Claude Code” and “I ship an AI agent” is one line:
bash
npm install @anthropic-ai/claude-agent-sdk
Every week there’s a new framework, a new orchestration platform, a new managed runtime. Meanwhile the primitives sitting in your .claude/ folder (the ones you’ve been editing for months) already do the job. You don’t need a new abstraction.
For those interested, in my newsletter I shared:
The full source code and a lib/agent.ts wrapper with the TypeScript pitfalls the SDK docs skip
Postbuild trick that stops production from inheriting your repo’s CLAUDE.md
The limitations I hit in the spike and the workarounds for each
How I host this in production (Railway configuration)