Building Custom AI Agents with OpenClaw: Developer Guide

Complete developer guide for building custom AI agents with OpenClaw. Architecture patterns, skill definitions, deployment strategies, and integration blueprints.

E
ECOSIRE Research and Development Team
|2026年3月19日4 分で読める880 語数|

OpenClaw を使用したカスタム AI エージェントの構築: 開発者ガイド

本番環境に対応した AI エージェントを構築することは、チャットボットを作成することと同じではありません。エージェントはコンテキストを認識し、不完全な情報を推論し、複数のステップからなる計画を実行し、障害から回復する必要があります。これらはすべて人間の監督なしで行われます。 OpenClaw は、このレベルの運用自律性のために特別に構築されたエンタープライズ AI エージェント プラットフォームであり、開発者に構造化されたランタイム、スキル構成モデル、および初日から最高の可観測性を提供します。

このガイドは、OpenClaw エージェントをゼロから展開して監視するようにしたいエンジニアを対象に書かれています。アーキテクチャの内部、スキルのオーサリング、メモリ管理、オーケストレーション フック、および運用負荷の下でエージェントの信頼性を維持する展開パターンについて説明します。

重要なポイント

  • OpenClaw エージェントは、スキル (アトミック機能)、メモリ層、および実行シーケンスを計画するオーケストレーターで構成されます。
  • エージェント マニフェスト ファイルは、実行前にすべての依存関係、権限、およびツール バインディングを宣言します。
  • スキルは、型指定された入力を受け入れ、型指定された出力を出力するステートレス関数です。テスト容易性が組み込まれています。
  • ワーキング メモリ、エピソード メモリ、および長期メモリ層は、さまざまな保持と取得のニーズに対応します。
  • フック (実行前、実行後、エラー時) を使用すると、コア スキル コードを変更せずに、モニタリング、レート制限、フォールバック ロジックを挿入できます。
  • OpenClaw のサンドボックス モードを使用すると、ライブ API 呼び出しを行わずに実稼働トレースをローカルで再生してデバッグできます。
  • マルチエージェントのハンドオフでは、型指定されたメッセージ バスが使用されます。エージェント間で生の文字列が渡されることはありません。
  • ECOSIRE は、マネージド OpenClaw 実装、カスタム スキル ライブラリ、および継続的な最適化をエンタープライズ チームに提供します。

OpenClaw エージェント モデルを理解する

すべての OpenClaw エージェントは、スキルメモリツールオーケストレーターの 4 つのプリミティブで構成されています。

スキル は、エージェントの機能の最小単位です。スキルは、型付き入力スキーマを受け入れ、型付き出力スキーマを返す関数です。スキルは同期または非同期にすることができ、外部依存関係を明示的に宣言します。例: ParseInvoiceSendSlackMessageQueryCRMContactGenerateReport

ツールは外部システム バインディングです。 OpenClaw には、REST API、データベース、ファイル システム、ブラウザ、メッセージ キュー用の組み込みツールが付属しています。エージェント マニフェストにツールを登録し、実行時に依存関係注入を通じてツールをスキルに注入します。

メモリは 3 つの層に構成されています。ワーキング メモリは、現在のタスクの状態、つまりエージェントのスクラッチパッドを保持します。エピソード メモリには、現在のセッション内のセマンティックの類似性によって取得できる完了したタスクの履歴が保存されます。長期記憶はセッション間で持続し、学習した事実、ユーザーの好み、およびドメインの知識を保存します。

オーケストレーター は推論の中核です。目標ステートメントを受け取り、利用可能なスキル レジストリをクエリし、実行計画を構築し、各ステップを監視します。スキルが失敗した場合、オーケストレーターは再試行するか、代替スキルに置き換えるか、人間にエスカレーションするかを決定します。

単一エージェントのアーキテクチャ図は次のようになります。

User Request
     ↓
[ Orchestrator ]
     ↓ plan
[ Skill Selector ] → [ Skill Registry ]
     ↓ execute
[ Skill Instance ]
     ↓ tool calls
[ Tool Layer ] → [ External Systems ]
     ↓ result
[ Memory Writer ]
     ↓ store
[ Working / Episode / Long-Term Memory ]
     ↓ next step or done
[ Orchestrator ] → response

このループは、オーケストレーターが目標が満たされたと判断するか、停止条件に達したと判断するまで続きます。


開発環境のセットアップ

最初のスキルを作成する前に、OpenClaw SDK とローカル エージェント ランタイムが必要です。

npm install @openclaw/sdk @openclaw/runtime @openclaw/cli
npx openclaw init my-agent --template=typescript

init コマンドは、次の構造のプロジェクトを生成します。

my-agent/
  agent.manifest.json   # Agent declaration
  skills/               # Skill implementations
  tools/                # Tool registrations
  memory/               # Memory adapter config
  tests/                # Skill and integration tests
  .openclaw/            # Local runtime state

agent.manifest.json は最も重要なファイルです。 OpenClaw がエージェントをブートストラップするために必要なものすべてを宣言します。

{
  "name": "invoice-processor",
  "version": "1.0.0",
  "runtime": "node-20",
  "skills": [
    "skills/extract-line-items.ts",
    "skills/validate-vendor.ts",
    "skills/post-to-erp.ts"
  ],
  "tools": {
    "erp": { "type": "rest", "baseUrl": "${ERP_BASE_URL}", "auth": "bearer" },
    "storage": { "type": "s3", "bucket": "${DOCS_BUCKET}" }
  },
  "memory": {
    "working": { "ttl": 3600 },
    "episode": { "backend": "redis", "maxItems": 500 },
    "longTerm": { "backend": "postgres", "table": "agent_facts" }
  },
  "permissions": ["read:invoices", "write:erp", "read:vendors"]
}

環境変数は実行時に挿入され、マニフェストには保存されません。


初めてのスキルを書く

スキルは厳格な契約に従っています。これらは、宣言されたスキーマに一致する input オブジェクトを受け入れ、注入された tools および memory を受け取り、output オブジェクトを返すか、型指定された SkillError をスローします。

import { defineSkill, SkillError } from "@openclaw/sdk";
import { z } from "zod";

const ExtractLineItemsInput = z.object({
  documentUrl: z.string().url(),
  documentType: z.enum(["invoice", "receipt", "purchase-order"]),
});

const ExtractLineItemsOutput = z.object({
  lineItems: z.array(
    z.object({
      description: z.string(),
      quantity: z.number(),
      unitPrice: z.number(),
      total: z.number(),
    })
  ),
  confidence: z.number().min(0).max(1),
});

export const ExtractLineItems = defineSkill({
  name: "extract-line-items",
  description: "Extracts line items from a document using OCR and LLM parsing",
  input: ExtractLineItemsInput,
  output: ExtractLineItemsOutput,
  tools: ["storage"],
  async run({ input, tools, memory }) {
    const fileBuffer = await tools.storage.get(input.documentUrl);
    if (!fileBuffer) {
      throw new SkillError("DOCUMENT_NOT_FOUND", `No document at ${input.documentUrl}`);
    }

    // OCR + LLM extraction logic here
    const extracted = await runOcrPipeline(fileBuffer);

    await memory.working.set("lastExtraction", extracted);

    return {
      lineItems: extracted.items,
      confidence: extracted.confidence,
    };
  },
});

スキルの主な設計ルール:

  • 入力に副作用はありません: スキルは入力オブジェクトを変更してはなりません。
  • 入力エラー: 汎用の Error ではなく、機械可読コードを含む SkillError を常にスローします。
  • ツールの依存関係を宣言: tools 配列で宣言されたツールのみが挿入されます。宣言されていないツールは起動検証エラーの原因となります。
  • 明示的にメモリに書き込む: スキルは自動的に状態を保持しません。 memory.working.set() を意図的に呼び出します。

メモリ管理の実践

3 つのメモリ層は異なる目的を果たし、エージェントの正確性のためには適切な層を選択することが重要です。

ワーキング メモリ は、単一タスクの実行中存続するインプロセスのキーと値のストアです。これを使用して、出力チェーンを経由せずにスキル間の中間結果を渡します。オーケストレーターが完了するかタイムアウトになると、自動的にクリアされます。

// Skill A writes
await memory.working.set("vendorId", "VND-4521");

// Skill B reads
const vendorId = await memory.working.get("vendorId");

エピソード メモリ はセマンティック検索ストアです。タスクが完了すると、オーケストレーターはオプションで、エピソード メモリに埋め込まれた概要を書き込みます。今後のタスクは、同様の過去のエピソードを取得して推論を伝えることができます。

// Query past episodes
const relatedEpisodes = await memory.episode.search(
  "invoice from Acme Corp with disputed line items",
  { topK: 3, minScore: 0.75 }
);

長期記憶は、エージェントの永続的な知識ベースです。これは、ベンダーの分類ルール、ユーザーの好み、学習されたドメインの制約など、複数のセッションにわたって存続する必要がある事実に使用します。

// Store a learned fact
await memory.longTerm.upsert({
  key: `vendor:${vendorId}:paymentTerms`,
  value: "NET-30",
  source: "invoice-2024-0312",
  confidence: 0.9,
});

よくある間違いは、長期記憶への上書きです。安定した信頼性の高い事実を得るために保管してください。一時的な推論は作業記憶に属します。


可観測性と制御のためのライフサイクル フック

OpenClaw は、スキルの実行ごとに 4 つのライフサイクル フック (preRunpostRunonError、および onTimeout) を公開します。フックをエージェント マニフェストに登録するか、ブートストラップ ファイルにプログラム的に登録します。

import { AgentRuntime } from "@openclaw/runtime";

const agent = new AgentRuntime({ manifest: "./agent.manifest.json" });

agent.useHook("preRun", async (ctx) => {
  ctx.metadata.startTime = Date.now();
  console.log(`[${ctx.skill}] starting with input keys: ${Object.keys(ctx.input)}`);
});

agent.useHook("postRun", async (ctx) => {
  const elapsed = Date.now() - ctx.metadata.startTime;
  metrics.record("skill.duration", elapsed, { skill: ctx.skill });
});

agent.useHook("onError", async (ctx) => {
  if (ctx.error.code === "RATE_LIMIT_EXCEEDED") {
    await sleep(ctx.error.retryAfterMs);
    return "retry";
  }
  alerting.send(`Skill ${ctx.skill} failed: ${ctx.error.message}`);
  return "escalate";
});

onError フックの戻り値は、オーケストレーターの動作を制御します。"retry" は再試行 (構成された最大値まで) をトリガーし、"escalate" はタスクを人間のキューにルーティングし、"fail" はタスクを即時に終了します。


単独でスキルをテストする

スキルには入力と出力が型付けされているため、単体テストは簡単です。 OpenClaw のテスト ユーティリティは、すべてのツール インターフェイスのモック実装を提供します。

import { testSkill } from "@openclaw/testing";
import { ExtractLineItems } from "../skills/extract-line-items";

describe("ExtractLineItems", () => {
  it("extracts items from a valid invoice", async () => {
    const result = await testSkill(ExtractLineItems, {
      input: {
        documentUrl: "s3://test-bucket/invoice-001.pdf",
        documentType: "invoice",
      },
      mocks: {
        storage: {
          get: jest.fn().mockResolvedValue(samplePdfBuffer),
        },
      },
    });

    expect(result.lineItems).toHaveLength(3);
    expect(result.confidence).toBeGreaterThan(0.8);
  });

  it("throws DOCUMENT_NOT_FOUND for missing file", async () => {
    await expect(
      testSkill(ExtractLineItems, {
        input: { documentUrl: "s3://test-bucket/missing.pdf", documentType: "invoice" },
        mocks: { storage: { get: jest.fn().mockResolvedValue(null) } },
      })
    ).rejects.toMatchObject({ code: "DOCUMENT_NOT_FOUND" });
  });
});

統合テストにはサンドボックス モードを使用します。サンドボックスは、記録された運用トレースを現在のスキル コードに対して再生し、本番システムに到達する前に回帰を検出します。

npx openclaw sandbox replay --trace=traces/invoice-20240315.json

実稼働環境へのデプロイメント

OpenClaw エージェントは、Docker コンテナ、サーバーレス関数、または長時間実行プロセスとしてデプロイできます。エンタープライズ展開に推奨されるパターンは、タスク キューの背後にコンテナ化されたエージェント プールを配置することです。

FROM openclaw/runtime:node-20
WORKDIR /agent
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN npx openclaw build
CMD ["npx", "openclaw", "serve", "--workers=4"]

高スループットのシナリオの場合は、自動スケーリング ルールを使用してエージェント プールを構成します。 OpenClaw ランタイムは、キューの深さ、スキル レイテンシのパーセンタイル、エラー率、メモリ使用量に関する Prometheus メトリクスを /metrics で公開し、これらをアラート スタックに接続します。

本番稼働前の本番チェックリスト:

  • すべての環境変数は、.env ファイルではなく、シークレット マネージャー (AWS Secrets Manager、HashiCorp Vault) にあります。
  • メモリ バックエンド (Redis、PostgreSQL) には接続プーリングが構成されています。
  • maxConcurrentTasks 設定はインフラストラクチャの容量と一致します。
  • 外部ツール呼び出しのレート制限はベンダー API 制限と一致します。
  • デッドレターキューは、再試行を使い果たすタスクに対して構成されます。
  • 分散トレース (OpenTelemetry) が有効になっており、トレースは可観測性プラットフォームに流れています。

よくある質問

OpenClaw オーケストレーターは次に実行するスキルをどのように決定しますか?

オーケストレーターは、目標の分解とスキルのマッチングを組み合わせて使用​​します。トップレベルの目標をサブ目標に分割し、各サブ目標の説明との意味的類似性を使用してスキル レジストリをクエリします。スキルは、関連性スコア、依存関係の可用性、および過去の成功率によってランク付けされます。オーケストレーターは、スキル実行の有向非循環グラフを構築し、開始前に依存関係を解決します。

スキルは別のスキルを直接呼び出すことができますか?

いいえ、スキルは他のスキルを直接呼び出してはいけません。スキル間の調整はオーケストレーターの責任です。スキル B を実行する前にスキル A の出力が必要な場合は、オーケストレーター プランで依存関係を宣言します。これにより、スキルがステートレスになり、個別にテスト可能になります。例外は、オーケストレーション プリミティブとして明示的にマークされている複合スキルです。

スキルの実行中に外部 API が停止するとどうなりますか?

onError フックは失敗をインターセプトします。フックが "retry" を返した場合、オーケストレーターは構成されたバックオフ間隔を待ってスキルを再試行します。再試行が完了すると、タスクは配信不能キューに移動します。同じ機能に対してフォールバック スキルが登録されている場合、オーケストレーターは諦める前にそれを試行します。部分的なタスクの状態はワーキング メモリに保存されるため、最後に成功したスキルからタスクを再開できます。

スキルが実行時に必要とするシークレットをどのように処理しますか?

エージェント マニフェストで宣言されたツールは、スキルごとではなく、起動時に認証情報を使用して初期化されます。 Secrets Manager は、コンテナーの起動時にマニフェストで参照される環境変数 (${ERP_BASE_URL}${DOCS_BUCKET} など) を設定します。スキルは未加工の資格情報を参照することはなく、ランタイムによって挿入された事前認証されたツール インスタンスと対話します。

エージェントが持つことができるスキルの数に制限はありますか?

スキル レジストリには厳密な制限はありませんが、重複する説明を含むスキルを何百も登録すると、実際のオーケストレーションの品質が低下します。関連するスキルをスキル パッケージにグループ化し、明確で明確な説明を使用します。非常に大規模なスキル ライブラリの場合は、専門のエージェントに分割し、マルチエージェント オーケストレーションを使用してタスクを適切なエージェントにルーティングすることを検討してください。

OpenClaw エージェントはクラウドに依存せずにオンプレミスで実行できますか?

はい。 OpenClaw はクラウドに依存しません。ランタイム、メモリ バックエンド、およびツール層はすべて、オンプレミス インフラストラクチャを使用するように構成できます。 Redis はローカルで実行でき、長期メモリ バックエンドはオンプレミスの PostgreSQL インスタンスをポイントでき、ツール統合は内部 API をターゲットにすることができます。唯一の外部呼び出しは、オーケストレーター推論のための LLM プロバイダーへの呼び出しです。必要に応じて、オンプレミス LLM を使用するようにこれを構成できます。

実行中のタスクを中断せずにエージェントのスキルをバージョン管理するにはどうすればよいですか?

スキルは、セマンティック バージョニングを使用してエージェント マニフェストでバージョン管理されます。ランタイムは、ローリング デプロイ中に複数のスキル バージョンの同時実行をサポートします。実行中のタスクは、開始時のスキル バージョンを引き続き使用します。新しいタスクでは最新バージョンが選択されます。スキルの入力/出力スキーマへの重大な変更には、メジャー バージョンのバンプと、そのスキルの出力を使用するエージェントの移行計画が必要です。


次のステップ

実稼働グレードの AI エージェントを構築するには、優れたコードだけではなく、障害モード、スケーリング パターン、開発と改良に数か月かかるドメイン固有のスキル ライブラリに関する運用経験が必要です。

ECOSIRE の OpenClaw Custom Skills サービス は、要件分析、スキル アーキテクチャ、既存システムとの統合、テスト、展開、継続的な最適化など、エンドツーエンドのエージェント開発を提供します。私たちのチームは、文書処理、ERP 自動化、顧客サポート、財務分析などのための OpenClaw エージェントを構築しました。

OpenClaw スペシャリストに相談 して自動化要件について話し合い、カスタム開発ロードマップを取得します。

E

執筆者

ECOSIRE Research and Development Team

ECOSIREでエンタープライズグレードのデジタル製品を開発。Odoo統合、eコマース自動化、AI搭載ビジネスソリューションに関するインサイトを共有しています。

WhatsAppでチャット