makers-migration について
AI エージェントプロジェクトを EdgeOne Makers に移行するためのガイドです。Python と Node/TypeScript のフレームワーク別変更点に加え、共通のプラットフォーム規約と検証手順を扱います。
主な機能
- 01フレームワーク別の移行手順
- 02Python と Node/TypeScript の解説
- 03環境変数と API の適応
- 04ツールと会話ストアの置き換え
- 05SSE レスポンスへの変換
活用シーン
- 01CrewAI プロジェクトの移行
- 02LangGraph エージェントの移行
- 03API ルートの Makers 対応
- 04デプロイ前の移行確認
MCP 対応
Claude Agent SDK プロジェクトの MCP ツールを `context.tools.toClaudeMcpServer()` で Makers に接続する方法を説明します。移行時に独自 MCP ツールを置き換える手順も扱います。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ tencentedgeone/ edgeone-makers-tools --skill makers-migrationインストール後、Claude Code で/makers-migrationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/api-route-to-makers.mdclaude-agent-sdk-to-makers.mdcrewai-to-makers.mddeepagents-to-makers.mdlanggraph-to-makers.mdopenai-agents-to-makers.md詳細
EdgeOne Makers 移行ガイド
既存の AI エージェントプロジェクトを EdgeOne Makers プラットフォーム形式に移行します。構造の変換、API の適応、プラットフォーム機能の注入を扱います。
移行判断ツリー
What type of project are you migrating?
├── Python project
│ ├── Using CrewAI → See §2 CrewAI
│ ├── Using LangChain/LangGraph/DeepAgents → See §3 LangGraph (Python)
│ ├── Using OpenAI Agents SDK → See §4 OpenAI Agents (Python)
│ └── Using Claude Agent SDK → See §5 Claude SDK (Python)
└── Node/TS project
├── Using Express/Next.js API routes → See §6 Express → Makers
├── Using LangGraph/DeepAgents → See §3 LangGraph (Node)
├── Using OpenAI Agents SDK → See §4 OpenAI Agents (Node)
└── Using Claude Agent SDK → See §5 Claude SDK (Node)
⚠️ 移行チェックリスト(すべてのフレームワーク共通)
フレームワーク固有の変更を始める前に、以下の共通項目を確認してください。
-
agents.frameworkとbuildCommand/outputDirectoryが正しく設定されたedgeone.jsonを作成する - バックエンドコードを Express のルート/Next.js の API ルートから
agents/ディレクトリに移動する -
process.env/os.environをcontext.env/ctx.envに置き換える -
req.headers.get('x')をcontext.request.headers['x'](Node)または通常の辞書アクセス(Python)に置き換える -
await req.json()をcontext.request.body(すでに解析済み)に置き換える - モデル API の直接呼び出し(OpenAI、Anthropic)を
AI_GATEWAY_*環境変数に置き換える - AI エンドポイントに SSE ストリーミングを追加する(
res.json()/return {"data": ...}を置き換える) - フロントエンドの fetch 呼び出しに
makers-conversation-idヘッダーを追加する - 独自のツール実装ではなく、
context.tools経由でプラットフォームツールを接続する - インメモリまたは独自の DB ではなく、
context.store経由で会話履歴を接続する - web_search を使用する場合は、
WSA_API_KEY環境変数を設定し、context.tools.get("web_search")を使用する - ローカル開発用に
edgeone makers devを設定する
§1. 標準 API ルート → Makers ハンドラー
これは最も一般的な移行パターンです。Express/Next.js の API ルート、通常の HTTP ハンドラーなどに適用されます。
Node(Express/Next.js → Makers)
// ❌ Before: Next.js API route (app/api/chat/route.ts)
export async function POST(req: Request) {
const body = await req.json();
const headers = req.headers;
const apiKey = process.env.OPENAI_API_KEY;
// ... LLM call ...
return Response.json({ data: result });
}
// ✅ After: Makers agent handler (agents/chat/index.ts)
export async function onRequest(context: any) {
const body = context.request.body; // already parsed
const conversationId = context.conversation_id; // auto-injected from header
const env = context.env; // context.env, never process.env
// ... LLM call via AI_GATEWAY_* ...
return new Response(JSON.stringify({ data: result }), {
headers: { 'Content-Type': 'application/json' },
});
}
Python(Flask/FastAPI → Makers)
# ❌ Before: Flask route
@app.route('/chat', methods=['POST'])
def chat():
body = request.get_json()
api_key = os.environ.get('OPENAI_API_KEY')
# ... LLM call ...
return jsonify({'data': result})
# ✅ After: Makers agent handler (agents/chat/index.py)
async def handler(ctx):
body = ctx.request.body
conversation_id = ctx.conversation_id
api_key = ctx.env.get("AI_GATEWAY_API_KEY")
# ... LLM call via AI_GATEWAY_* ...
return {"data": result}
§2. CrewAI(Python)
主な変更点
| 変更前 | 変更後 |
|---|---|
os.environ.get("OPENAI_API_KEY") | ctx.env.get("AI_GATEWAY_API_KEY") |
LLM(provider="openai", ...) — LiteLLM によるディスパッチ | LLM(provider="openai", base_url=ctx.env["AI_GATEWAY_BASE_URL"], ...) — LiteLLM を経由しない |
Crew で memory=True | memory=False + ctx.store を使用 |
verbose=True | verbose=False(イベントは crewai_event_bus 経由) |
crew.kickoff()(ブロッキング) | await asyncio.to_thread(crew.kickoff) |
| カスタム検索ツール | ctx.tools.to_crewai_tools(BaseTool) を使用 |
| Flask/FastAPI ハンドラー | async def handler(ctx): → ctx.utils.stream_sse(gen()) |
edgeone.json
{
"buildCommand": "",
"outputDirectory": "",
"agents": {
"framework": "crewai"
}
}
要件
crewai>=1.14.5
openai>=1.50.0
移行手順
- Flask/FastAPI のエントリーポイントを
async def handler(ctx):に置き換える - 環境変数は
ctx.envから読み取り、os.environは使用しない LLM(provider="openai", api_key=ctx.env["AI_GATEWAY_API_KEY"], base_url=ctx.env["AI_GATEWAY_BASE_URL"])を使用するCrew(memory=False, verbose=False)を設定するcrew.kickoff()をasyncio.to_thread()でラップする- カスタムツールを
ctx.tools.to_crewai_tools(BaseTool)に置き換える ctx.utils.stream_sse(gen())を介して SSE を返す
完全なパターンについては、makers-agents/skills/python-frameworks/crewai.md を参照してください。 変更前/変更後の詳細については、references/crewai-to-makers.md を参照してください。
§3. LangGraph / DeepAgents(Node + Python)
主な変更点
| 変更前 | 変更後 |
|---|---|
モデルを直接作成(new ChatOpenAI(...)) | apiKey/baseURL に AI_GATEWAY_* を使用 |
MemorySaver(インメモリのチェックポインター) | context.store.langgraphCheckpointer(永続化) |
| カスタムツール関数 | context.tools.toLangChainTools(tool) |
agent.stream() | createSSEResponse(gen, signal) による SSE(Node)、または ctx.utils.stream_sse(gen())(Python) |
thread_id の手動管理 | thread_id = context.conversation_id |
Node — edgeone.json
{
"agents": {
"framework": "langgraph"
}
}
Python — edgeone.json
{
"buildCommand": "",
"outputDirectory": "",
"agents": {
"framework": "langgraph"
}
}
移行手順
- ハンドラーを
agents/<name>/index.ts(または.py)に移動します - モデルの初期化を置き換えます。
AI_GATEWAY_API_KEYとAI_GATEWAY_BASE_URLを使用します - チェックポインターを置き換えます。
MemorySaverの代わりにcontext.store.langgraphCheckpointerを使用します - ストアを置き換えます。
context.store.langgraphStoreを使用します - ツールを置き換えます。カスタムツール関数の代わりに
context.tools.toLangChainTools(tool)を使用します thread_idを設定します。{ configurable: { thread_id: context.conversation_id } }- レスポンスを SSE ストリーミングのパターンに置き換えます
Node:makers-agents/skills/node-frameworks/langgraph.md Python:makers-agents/skills/python-frameworks/langgraph.md DeepAgents:makers-agents/skills/node-frameworks/deepagents.md 移行前後の詳細:references/langgraph-to-makers.md、references/deepagents-to-makers.md
§4. OpenAI Agents SDK(Node + Python)
主な変更点
| Before | After |
|---|---|
new OpenAI({ apiKey, baseURL }) | context.env / ctx.env から AI_GATEWAY_* を読み込みます |
Runner.run(agent, input, { tools }) | context.tools.all() からツールを取得します(OpenAI の関数形式に変換済み) |
| セッション管理 | context.store.openaiSession(convId)(Node) |
| Express ルートのレスポンス | createSSEResponse(gen, signal)(Node)または ctx.utils.stream_sse(gen())(Python)による SSE |
| モデル名のハードコード | `ctx.env.AI_GATEWAY_MODEL |
Node — edgeone.json
{
"agents": {
"framework": "openai-agents-sdk"
}
}
Python — edgeone.json
{
"buildCommand": "",
"outputDirectory": "",
"agents": {
"framework": "openai-agents-sdk"
}
}
移行手順
- ハンドラーを
agents/<name>/index.ts(または.py)に移動します process.envではなくcontext.envから OpenAI クライアントを作成します- ツールを
context.tools.all()に置き換えます(OpenAI の関数形式のツールを返します) - セッションには
context.store.openaiSession(conversationId)を使用します(Node) - ストリームイベントを SSE に対応付けます。
output_text_delta→ai_response、tool_called→tool_call
Node:makers-agents/skills/node-frameworks/openai-agents.md Python:makers-agents/skills/python-frameworks/openai-agents.md 移行前後の詳細:references/openai-agents-to-makers.md
§5. Claude Agent SDK(Node + Python)
主な変更点
| Before | After |
|---|---|
ANTHROPIC_API_KEY 環境変数 | collectGatewayEnv() によって AI_GATEWAY_* からマッピングされます |
process.env | query().options.env に注入される context.env |
| カスタム MCP ツール | context.tools.toClaudeMcpServer() |
| セッション | context.store.claudeSessionStore()(Node) |
| Stdout の EPIPE クラッシュ | process.stdout の EPIPE を無視します(Node) |
| 書き込み可能な設定ディレクトリがない | CLAUDE_CONFIG_DIR=/tmp/claude-agent-sdk、CLAUDE_CODE_TMPDIR=/tmp を設定します |
Node — edgeone.json
{
"agents": {
"framework": "claude-agent-sdk"
}
}
Python — edgeone.json
{
"buildCommand": "",
"outputDirectory": "",
"agents": {
"framework": "claude-agent-sdk"
}
}
移行手順
- ハンドラーを
agents/<name>/index.ts(または.py)に移動します collectGatewayEnv(context.env)を使ってAI_GATEWAY_*→ANTHROPIC_*にマッピングします- 環境変数を
query({ options: { env: collectGatewayEnv(...) } })に注入します - MCP ツールを置き換えます。
context.tools.toClaudeMcpServer('edgeone', { alwaysLoad: true }) - Node のみ:
process.stdoutのEPIPEを無視します - 書き込み可能な設定ディレクトリを設定します。
CLAUDE_CONFIG_DIR=/tmp/claude-agent-sdk、CLAUDE_CODE_TMPDIR=/tmp
Node:makers-agents/skills/node-frameworks/claude-sdk.md Python:makers-agents/skills/python-frameworks/claude-sdk.md 移行前後の詳細:references/claude-agent-sdk-to-makers.md
§6. Express / Next.js API Routes(Node)
Express ベースまたは Next.js API ルートを使用するエージェント向けの一般的な移行手順です。
7 ステップでの変換
| ステップ | 変換前 | 変換後 |
|---|---|---|
| 1. ファイルの場所 | app/api/chat/route.ts または server/routes/chat.ts | agents/chat/index.ts |
| 2. エントリーシグネチャ | export async function POST(req) または app.post('/chat', handler) | export async function onRequest(context) |
| 3. ボディの解析 | await req.json() | context.request.body(すでに解析済み) |
| 4. ヘッダー | req.headers.get('x-foo') | context.request.headers['x-foo'] |
| 5. 中断シグナル | req.signal | context.request.signal(AbortSignal) |
| 6. モデルへのアクセス | process.env.OPENAI_API_KEY → 直接呼び出し | context.env.AI_GATEWAY_* → AI Gateway |
| 7. レスポンス | res.json() または return Response.json() | createSSEResponse(gen, signal) による SSE ストリーム |
例:Next.js API ルートから Makers への移行
// ❌ Before: Next.js (app/api/chat/route.ts)
import { NextRequest } from 'next/server';
import OpenAI from 'openai';
export async function POST(req: NextRequest) {
const { message } = await req.json();
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const response = await client.chat.completions.create({
model: 'gpt-4o',
messages: [{ role: 'user', content: message }],
stream: true,
});
// ... stream back as Response
}
// ✅ After: EdgeOne Makers (agents/chat/index.ts)
import { createLogger, sseEvent, createSSEResponse } from '../_shared';
export async function onRequest(context: any) {
const { message } = context.request.body ?? {};
if (!message) return new Response('Missing message', { status: 400 });
const signal = context.request.signal as AbortSignal;
return createSSEResponse(async function* (sig) {
const response = await fetch(context.env.AI_GATEWAY_BASE_URL + '/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${context.env.AI_GATEWAY_API_KEY}`,
},
body: JSON.stringify({
model: context.env.AI_GATEWAY_MODEL || '@makers/deepseek-v4-flash',
messages: [{ role: 'user', content: message }],
stream: true,
}),
signal: sig,
});
// ... proxy SSE chunks ...
yield 'data: [DONE]\n\n';
}, signal);
}
§7. クライアント側の移行
フロントエンドの fetch 呼び出し
// ❌ Before: plain fetch without conversation-id
const response = await fetch('/api/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message }),
});
// ✅ After: with makers-conversation-id header
const conversationId = getOrCreateConversationId(); // crypto.randomUUID() + localStorage
const response = await fetch('/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'makers-conversation-id': conversationId, // ⭐ required for all AI endpoints
},
body: JSON.stringify({ message }),
});
/stop エンドポイント
// ✅ Always pass conversation_id in body for /stop
await fetch('/stop', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ conversation_id: conversationId }),
});
SSE の解析
const reader = response.body!.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n\n');
buffer = lines.pop() || '';
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') return;
try {
const event = JSON.parse(data);
if (event.type === 'ai_response') { /* display text */ }
if (event.type === 'tool_call') { /* show tool call */ }
if (event.type === 'ping') { /* ignore heartbeat */ }
} catch { /* skip non-JSON */ }
}
}
}
§8. 移行後の検証
移行後、デプロイする前に以下の項目を確認してください。
-
edgeone makers devがエラーなく起動する -
/chatエンドポイントが SSE ストリーム(JSON ではない)を返す - AI の応答がエンドツーエンドで動作する(フロントエンド → エージェント → モデル → フロントエンド)
- すべての箇所で
context.envが使用されている(process.env/os.environを grep し、残っていないことを確認する) -
edgeone.jsonのagents.frameworkが正しく設定されている - プラットフォームツール(
context.tools)が少なくとも 1 つのフレームワークで動作する - 会話履歴がリクエスト間で保持される(
context.store経由) -
/stopエンドポイントが実行中の処理をキャンセルする - フロントエンドが
makers-conversation-idヘッダーを送信する
関連項目
- エージェント開発ガイド:makers-agents/SKILL.md
- プラットフォームの規約:makers-agents/references/platform/
- CLI コマンド:makers-cli/SKILL.md
- デプロイガイド:makers-deploy/SKILL.md
変換前/変換後の詳細なリファレンスファイル
- references/api-route-to-makers.md — 一般的な API ルートから Makers ハンドラーへの移行(フレームワークなしの場合のフォールバック。Makers はフレームワークなしの
onRequest/handlerに対応しています) - references/langgraph-to-makers.md — LangGraph(Node + Python)
- references/deepagents-to-makers.md — DeepAgents(Node + Python)
- references/openai-agents-to-makers.md — OpenAI Agents SDK(Node + Python)
- references/claude-agent-sdk-to-makers.md — Claude Agent SDK(Node + Python)