mcpField
D
Deep Agents Orchestration

Deep Agents Orchestration

github.com/jackjin1997エージェントワークフロー130 回インストール19 週間前に更新
リポジトリ

Deep Agents Orchestration について

Deep Agents Orchestrationは、複数ステップの作業を行うエージェントを構築する開発者向けに、deepagentsの3つのオーケストレーション機能を説明します。サブエージェントへの委任、ToDo管理、重要なツール操作への人間の承認を扱います。

主な機能

  1. 01taskによるサブエージェントへの委任
  2. 02複数ステップのToDo管理
  3. 03重要なツール操作への承認設定
  4. 04サブエージェントのツールとモデル設定
  5. 05チェックポイントによる中断後の再開

活用シーン

  1. 01専門作業をカスタムサブエージェントに委任
  2. 02複雑または長時間のタスク進捗を管理
  3. 03デプロイなどの重要操作前に承認を求める
  4. 04確認待ちで停止したワークフローを再開

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jackjin1997/clawforge --skill deep-agents-orchestration

インストール後、Claude Code で/deep-agents-orchestrationを入力して読み込まれたか確認します。

詳細

Deep Agents には、次の 3 つのオーケストレーション機能があります:
  1. SubAgentMiddleware:task ツールを介して、専門エージェントに作業を委任します
  2. TodoListMiddleware:write_todos ツールを介して、タスクを計画および追跡します
  3. HumanInTheLoopMiddleware:機密性の高い操作の前に承認を必須にします

これら 3 つはすべて、create_deep_agent() に自動的に含まれます。


サブエージェント(タスクの委任)

サブエージェントを使用する場合メインエージェントを使用する場合
タスクに専門的なツールが必要汎用ツールで十分
複雑な作業を分離したい1 ステップの操作
メインエージェントのコンテキストをクリーンに保ちたいコンテキストの肥大化を許容できる
メインエージェントが `task` ツールを持つ -> 新しいサブエージェントを作成 -> サブエージェントが自律的に実行 -> 最終レポートを返します。

デフォルトのサブエージェント:「general-purpose」— メインエージェントと同じツールおよび設定で自動的に利用できます。

学術論文の検索に特化したツールを持つカスタムの「researcher」サブエージェントを作成します。 ```python from deepagents import create_deep_agent from langchain.tools import tool

@tool def search_papers(query: str) -> str: """Search academic papers.""" return f"Found 10 papers about {query}"

agent = create_deep_agent( subagents=[ { "name": "researcher", "description": "Conduct web research and compile findings", "system_prompt": "Search thoroughly, return concise summary", "tools": [search_papers], } ] )

Main agent delegates: task(agent="researcher", instruction="Research AI trends")

</python>
<typescript>
学術論文の検索に特化したツールを持つカスタムの「researcher」サブエージェントを作成します。
```typescript
import { createDeepAgent } from "deepagents";
import { tool } from "@langchain/core/tools";
import { z } from "zod";

const searchPapers = tool(
  async ({ query }) => `Found 10 papers about ${query}`,
  { name: "search_papers", description: "Search papers", schema: z.object({ query: z.string() }) }
);

const agent = await createDeepAgent({
  subagents: [
    {
      name: "researcher",
      description: "Conduct web research and compile findings",
      systemPrompt: "Search thoroughly, return concise summary",
      tools: [searchPapers],
    }
  ]
});

// Main agent delegates: task(agent="researcher", instruction="Research AI trends")
機密性の高い操作に対する HITL 承認を伴うサブエージェントを設定します。 ```python from deepagents import create_deep_agent from langgraph.checkpoint.memory import MemorySaver

agent = create_deep_agent( subagents=[ { "name": "code-deployer", "description": "Deploy code to production", "system_prompt": "You deploy code after tests pass.", "tools": [run_tests, deploy_to_prod], "interrupt_on": {"deploy_to_prod": True}, # Require approval } ], checkpointer=MemorySaver() # Required for interrupts )

</python>
</ex-subagent-with-hitl>

<fix-subagents-are-stateless>
<python>
サブエージェントはステートレスです。1 回の呼び出しで完全な指示を渡してください。
```python
# WRONG: Subagents don't remember previous calls
# task(agent='research', instruction='Find data')
# task(agent='research', instruction='What did you find?')  # Starts fresh!

# CORRECT: Complete instructions upfront
# task(agent='research', instruction='Find data on AI, save to /research/, return summary')
サブエージェントはステートレスです。1 回の呼び出しで完全な指示を渡してください。 ```typescript // WRONG: Subagents don't remember previous calls // task research: Find data // task research: What did you find? // Starts fresh!

// CORRECT: Complete instructions upfront // task research: Find data on AI, save to /research/, return summary

</typescript>
</fix-subagents-are-stateless>

<fix-custom-subagents-dont-inherit-skills>
<python>
カスタムサブエージェントは、メインエージェントのスキルを継承しません。
```python
# WRONG: Custom subagent won't have main agent's skills
agent = create_deep_agent(
    skills=["/main-skills/"],
    subagents=[{"name": "helper", ...}]  # No skills inherited
)

# CORRECT: Provide skills explicitly (general-purpose subagent DOES inherit)
agent = create_deep_agent(
    skills=["/main-skills/"],
    subagents=[{"name": "helper", "skills": ["/helper-skills/"], ...}]
)

TodoList(タスク計画)

TodoList を使用する場合TodoList を省略する場合
複雑で複数のステップがあるタスク単純な単一アクションのタスク
実行時間の長い操作迅速な操作(3 ステップ未満)
``` write_todos(todos: list[dict]) -> None ```

各 ToDo 項目には、次の内容があります:

  • content:タスクの説明
  • status:"pending"、"in_progress"、"completed" のいずれか
複数ステップのタスクに対して、ToDo リストを自動的に作成するエージェントを呼び出します。 ```python from deepagents import create_deep_agent

agent = create_deep_agent() # TodoListMiddleware included by default

result = agent.invoke({ "messages": [{"role": "user", "content": "Create a REST API: design models, implement CRUD, add auth, write tests"}] }, config={"configurable": {"thread_id": "session-1"}})

Agent's planning via write_todos:

[

{"content": "Design data models", "status": "in_progress"},

{"content": "Implement CRUD endpoints", "status": "pending"},

{"content": "Add authentication", "status": "pending"},

{"content": "Write tests", "status": "pending"}

]

</python>
<typescript>
複数ステップのタスクに対して、ToDo リストを自動的に作成するエージェントを呼び出します。
```typescript
import { createDeepAgent } from "deepagents";

const agent = await createDeepAgent();  // TodoListMiddleware included

const result = await agent.invoke({
  messages: [{ role: "user", content: "Create a REST API: design models, implement CRUD, add auth, write tests" }]
}, { configurable: { thread_id: "session-1" } });
呼び出し後に、エージェントの最終状態から ToDo リストにアクセスします。 ```python result = agent.invoke({...}, config={"configurable": {"thread_id": "session-1"}})

Access todo list from final state

todos = result.get("todos", []) for todo in todos: print(f"[{todo['status']}] {todo['content']}")

</python>
</ex-access-todo-state>

<fix-todolist-requires-thread-id>
<python>
呼び出し間で状態を保持するには、ToDo リストの状態に `thread_id` が必要です。
```python
# WRONG: Fresh state each time without thread_id
agent.invoke({"messages": [...]})

# CORRECT: Use thread_id
config = {"configurable": {"thread_id": "user-session"}}
agent.invoke({"messages": [...]}, config=config)  # Todos preserved

Human-in-the-Loop(承認ワークフロー)

HITL を使用する場合HITL を使用しない場合
重大な操作(DB への書き込み、デプロイ)読み取り専用の操作
コンプライアンス上、人間による監督が必要完全に自動化されたワークフロー
実行前に人間による承認が必要なツールを設定します。 ```python from deepagents import create_deep_agent from langgraph.checkpoint.memory import MemorySaver

agent = create_deep_agent( interrupt_on={ "write_file": True, # All decisions allowed "execute_sql": {"allowed_decisions": ["approve", "reject"]}, "read_file": False, # No interrupts }, checkpointer=MemorySaver() # REQUIRED for interrupts )

</python>
<typescript>
実行前に人間による承認が必要なツールを設定します。
```typescript
import { createDeepAgent } from "deepagents";
import { MemorySaver } from "@langchain/langgraph";

const agent = await createDeepAgent({
  interruptOn: {
    write_file: true,
    execute_sql: { allowedDecisions: ["approve", "reject"] },
    read_file: false,
  },
  checkpointer: new MemorySaver()  // REQUIRED
});
割り込みを発生させ、状態を確認し、操作を承認して、実行を再開するまでのワークフロー全体です。 ```python from deepagents import create_deep_agent from langgraph.checkpoint.memory import MemorySaver from langgraph.types import Command

agent = create_deep_agent( interrupt_on={"write_file": True}, checkpointer=MemorySaver() )

config = {"configurable": {"thread_id": "session-1"}}

Step 1: Agent proposes write_file - execution pauses

result = agent.invoke({ "messages": [{"role": "user", "content": "Write config to /prod.yaml"}] }, config=config)

Step 2: Check for interrupts

state = agent.get_state(config) if state.next: print(f"Pending action")

Step 3: Approve and resume

result = agent.invoke(Command(resume={"decisions": [{"type": "approve"}]}), config=config)

</python>
<typescript>
割り込みを発生させ、状態を確認し、操作を承認して、実行を再開するまでのワークフロー全体です。
```typescript
import { createDeepAgent } from "deepagents";
import { MemorySaver, Command } from "@langchain/langgraph";

const agent = await createDeepAgent({
  interruptOn: { write_file: true },
  checkpointer: new MemorySaver()
});

const config = { configurable: { thread_id: "session-1" } };

// Step 1: Agent proposes write_file - execution pauses
let result = await agent.invoke({
  messages: [{ role: "user", content: "Write config to /prod.yaml" }]
}, config);

// Step 2: Check for interrupts
const state = await agent.getState(config);
if (state.next) {
  console.log("Pending action");
}

// Step 3: Approve and resume
result = await agent.invoke(
  new Command({ resume: { decisions: [{ type: "approve" }] } }), config
);
フィードバックを添えて保留中の操作を却下し、別の方法を試すようエージェントに促します。 ```python result = agent.invoke( Command(resume={"decisions": [{"type": "reject", "message": "Run tests first"}]}), config=config, ) ``` フィードバックを添えて保留中の操作を却下し、別の方法を試すようエージェントに促します。 ```typescript const result = await agent.invoke( new Command({ resume: { decisions: [{ type: "reject", message: "Run tests first" }] } }), config, ); ``` 実行を許可する前に、提案された操作の引数を編集します。 ```python result = agent.invoke( Command(resume={"decisions": [{ "type": "edit", "edited_action": { "name": "execute_sql", "args": {"query": "DELETE FROM users WHERE last_login < '2020-01-01' LIMIT 100"}, }, }]}), config=config, ) ``` ### エージェントが設定できる項目
  • サブエージェントの名前、ツール、モデル、システムプロンプト
  • 承認が必要なツール
  • ツールごとに許可される判断タイプ
  • TodoList の内容と構造
エージェントが設定できない項目
  • ツール名(task、write_todos)
  • HITL プロトコル(承認/編集/却下の構造)
  • 割り込みに必須のチェックポインター要件のスキップ
  • サブエージェントをステートフルにすること(サブエージェントは一時的な存在です)
HITL ワークフローで interrupt_on を使用する場合、チェックポインターが必要です。 ```python # WRONG agent = create_deep_agent(interrupt_on={"write_file": True})

CORRECT

agent = create_deep_agent(interrupt_on={"write_file": True}, checkpointer=MemorySaver())

</python>
<typescript>
HITL ワークフローで interruptOn を使用する場合、チェックポインターが必要です。
```typescript
// WRONG
const agent = await createDeepAgent({ interruptOn: { write_file: true } });

// CORRECT
const agent = await createDeepAgent({ interruptOn: { write_file: true }, checkpointer: new MemorySaver() });
中断されたワークフローを再開するには、一貫した thread_id が必要です。 ```python # WRONG: Can't resume without thread_id agent.invoke({"messages": [...]})

CORRECT

config = {"configurable": {"thread_id": "session-1"}} agent.invoke({...}, config=config)

Resume with Command using same config

agent.invoke(Command(resume={"decisions": [{"type": "approve"}]}), config=config)

</python>
<typescript>
中断されたワークフローを再開するには、一貫した thread_id が必要です。
```typescript
// WRONG: Can't resume without thread_id
await agent.invoke({ messages: [...] });

// CORRECT
const config = { configurable: { thread_id: "session-1" } };
await agent.invoke({ messages: [...] }, config);
// Resume with Command using same config
await agent.invoke(new Command({ resume: { decisions: [{ type: "approve" }] } }), config);
割り込みは実行中ではなく、invoke() の呼び出しと呼び出しの間に発生します。 ```python result = agent.invoke({...}, config=config) # Step 1: triggers interrupt if "__interrupt__" in result: # Step 2: check for interrupt result = agent.invoke( # Step 3: resume Command(resume={"decisions": [{"type": "approve"}]}), config=config, ) ```

コメント