Skip to main content
Sonzai Docs

ステート、ツール、ユーザーナレッジ

エージェントに状態をアタッチし、LLMが推論中に呼び出せるカスタムツールを定義し、 最初の会話前にユーザーにナレッジをプライミングします。

カスタムステート

チャット時にLLMコンテキストに注入される柔軟なキー・バリューストレージ。 環境状態、タスク進捗、リソース、その他のアプリケーションデータを すべてのAI応答に直接渡すために使用します。

スコーピングモデル

グローバルステート

インスタンス単位

インスタンス内のすべてのユーザーで共有。環境状態、設定、エージェントステータス、グローバルイベントに使用。

ユーザー別ステート

インスタンス+ユーザー単位

インスタンス内の1ユーザーにスコープ。割り当てタスク、ワークフロー進捗、ユーザー設定、アクティブツールに使用。

インスタンス

すべてのステートはinstanceIdにスコープされます。 エージェントの1つのデプロイメントコンテキスト(ワークスペースや 環境など)です。instanceIdを省略するとデフォルト インスタンスが使用されます。複数コンテキストの管理は インスタンス を参照してください。

ステートの作成

import { Sonzai } from "@sonzai-labs/agents";

const client = new Sonzai({ apiKey: "sk-..." });

// Global state (shared across all users)
await client.agents.customStates.create("agent-id", {
  key:         "current_status",
  value:       "Processing requests",
  scope:       "global",
  contentType: "text",
  instanceId:  "workspace-1",    // omit to use default instance
});

// Per-user state
await client.agents.customStates.create("agent-id", {
  key:         "assigned_tasks",
  value:       { reports: 1, reviews: 3 },
  scope:       "user",
  contentType: "json",
  userId:      "user-123",
  instanceId:  "workspace-1",
});

Upsert(作成または更新)

upsertはキーが存在しない場合はステートを作成し、 存在する場合は値を更新します。冪等で、毎回の更新サイクルで 安全に呼び出せます。

await client.agents.customStates.upsert("agent-id", {
  key:   "workflow_stage",
  value: "review_started",
  scope: "user",
  userId: "user-123",
});

キーで取得

複合キーで特定のステートを取得します。

const state = await client.agents.customStates.getByKey("agent-id", {
  key:    "assigned_tasks",
  scope:  "user",
  userId: "user-123",
});

console.log(state.value);     // { reports: 1, reviews: 3 }
console.log(state.updatedAt); // ISO timestamp

ステートの一覧

// All global states for an instance
const globals = await client.agents.customStates.list("agent-id", {
  scope:      "global",
  instanceId: "workspace-1",
});

// All per-user states for a specific user
const userStates = await client.agents.customStates.list("agent-id", {
  scope:  "user",
  userId: "user-123",
});

キーで削除

await client.agents.customStates.deleteByKey("agent-id", {
  key:    "assigned_tasks",
  scope:  "user",
  userId: "user-123",
});

ツール

ツールはLLMが推論中に関数を呼び出すことを可能にします。Sonzaiは sonzai_プレフィックスの組み込みツールを処理します。 カスタムツールはあなたが定義しバックエンドが実行します。Sonzaiは 呼び出しをサイドエフェクトとして表面化します。

組み込みツール(ケイパビリティ)

エージェントごとにプラットフォーム管理の機能を切り替えます。エージェント 作成時に有効化するか、ケイパビリティAPIで更新します。

sonzai_memory_recall常時オン

推論中に保存された記憶を検索します。コンテキストに自動注入されます。

sonzai_remember_name切り替え可

将来の会話のためにユーザーの名前を永続化します。デフォルトでオン。

sonzai_web_search切り替え可

Google経由のライブWeb検索。デフォルトでオン。

sonzai_inventory切り替え可

ユーザーリソースアイテムを読み取り、ナレッジベースデータと結合します。

// Set capabilities at agent creation
const agent = await client.agents.create({
  agentId: "your-stable-uuid",  // recommended — makes creation idempotent
  name: "Luna",
  big5: { openness: 0.75, conscientiousness: 0.6, extraversion: 0.8,
          agreeableness: 0.7, neuroticism: 0.3 },
  toolCapabilities: {
    webSearch:       true,
    rememberName:    true,
    imageGeneration: false,
    inventory:       true,
  },
});

// Or update capabilities on an existing agent
await client.agents.update("agent-id", {
  toolCapabilities: {
    webSearch: false,
    inventory: true,
  },
});

予約済みプレフィックス

sonzai_プレフィックスは予約済みです。カスタムツールでは 使用できません。APIが拒否します。

カスタムツール(エージェントレベル)

エージェントに保存される永続ツールで、セッションやインスタンスに 関係なくすべてのチャットで利用可能です。

// Create a custom tool
await client.agents.createCustomTool("agent-id", {
  name: "check_inventory",
  description: "Check the user's current tasks and their statuses",
  parameters: {
    type: "object",
    properties: {
      item_type: {
        type: "string",
        description: "Filter by category: active, pending, completed",
      },
    },
  },
});

// List all custom tools
const tools = await client.agents.listCustomTools("agent-id");

// Update a tool's description or parameters
await client.agents.updateCustomTool("agent-id", "check_inventory", {
  description: "Check and summarize the user's tasks by category",
});

// Delete a tool
await client.agents.deleteCustomTool("agent-id", "check_inventory");
セッションレベルツール(一時的)

特定のセッション用にツールを動的に注入します。セッションツールは エージェントレベルツールとマージされます。同名のセッションツールが 優先されます。セッション終了時に破棄されます。

オプション1 - 既存セッションに設定

await client.agents.sessions.setTools("agent-id", "session-id", [
  {
    name: "execute_action",
    description: "Execute an action from the agent's capabilities",
    parameters: {
      type: "object",
      properties: {
        action_name: { type: "string" },
        target:      { type: "string" },
      },
      required: ["action_name"],
    },
  },
]);

オプション2 - チャット呼び出し時にインライン渡し

for await (const event of client.agents.chatStream({
  agent:    "agent-id",
  messages: [{ role: "user", content: "Check my tools" }],
  userId:   "user-123",
  toolDefinitions: [
    {
      name:        "check_inventory",
      description: "List the agent's active tools",
      parameters:  { type: "object", properties: {} },
    },
  ],
})) {
  // handle events...
}

ツール呼び出しの処理

LLMがカスタムツールを呼び出すことを決定すると、SSEストリームに サイドエフェクトとして表示されます。バックエンドがツールを実行し、 次のメッセージで結果を返します。

1. ツール呼び出しの受信

const toolCalls: { name: string; arguments: Record<string, unknown> }[] = [];

for await (const event of client.agents.chatStream({
  agent:    "agent-id",
  messages: [{ role: "user", content: "What tasks do I have?" }],
  userId:   "user-123",
})) {
  // Stream content to the user
  const content = event.choices?.[0]?.delta?.content;
  if (content) process.stdout.write(content);

  // Collect tool calls from side effects
  const calls = event.sideEffects?.externalToolCalls ?? [];
  toolCalls.push(...calls);
}

2. 実行して結果を返す

// Execute your tool calls on your backend
const toolResults: string[] = [];
for (const call of toolCalls) {
  const result = await myBackend.executeTool(call.name, call.arguments);
  toolResults.push(result);
}

// Return results in the next chat message
for await (const event of client.agents.chatStream({
  agent:    "agent-id",
  userId:   "user-123",
  messages: [
    { role: "user",  content: "What tasks do I have?" },
    { role: "tool",  content: toolResults.join("\n") },
  ],
})) {
  process.stdout.write(event.choices?.[0]?.delta?.content ?? "");
}

ツールスコーピングまとめ

タイプスコープ永続性管理方法
組み込み(sonzai_全インスタンスプラットフォーム管理SDKケイパビリティ、ダッシュボード
エージェントレベルカスタム全インスタンス永続的SDK、ダッシュボード
セッションレベルセッション単位一時的SDK(インラインまたはsetTools)

ユーザースコープナレッジ(プライミング)

最初の会話前にエージェントがユーザーについて知っていることをシードします。 CRMデータ、ユーザープロファイル、購入履歴、その他初日から利用可能で あるべきユーザー固有のナレッジに使用します。

ユーザーのプライミング

primeUserはユーザーに関するファクトを非同期でシードします。 抽出完了をポーリングで確認できるジョブIDを返します。

const job = await client.agents.priming.primeUser(
  "agent-id",
  "user-123",
  {
    display_name: "Jane Smith",
    metadata: {
      company: "Acme Corp",
      title:   "Product Manager",
      email:   "[email protected]",
      custom:  { tier: "premium", region: "us-west" },
    },
    content: [
      {
        type:    "text",
        content: "Jane joined in 2024 and prefers concise answers. She focuses on mobile growth.",
      },
    ],
    source: "crm_import",
  },
);

// Check when priming is complete
const status = await client.agents.priming.getPrimeStatus(
  "agent-id", "user-123", job.jobId
);
console.log(status.status); // "pending" | "processing" | "completed" | "failed"

ユーザーメタデータの取得と更新

// Get stored metadata for a user
const meta = await client.agents.priming.getMetadata("agent-id", "user-123");
console.log(meta.displayName, meta.company, meta.customFields);

// Update metadata (partial update — unspecified fields are preserved)
await client.agents.priming.updateMetadata("agent-id", "user-123", {
  custom: { tier: "enterprise", lastContact: "2026-03-28" },
});

バッチインポート(複数ユーザー)

多数のユーザーを一度にインポートします。進捗追跡用のジョブIDを返します。

const job = await client.agents.priming.batchImport("agent-id", {
  users: [
    {
      userId:      "user-1",
      displayName: "Alice",
      metadata:    { company: "Acme", custom: { tier: "pro" } },
      content:     [{ type: "text", content: "Alice is a power user." }],
    },
    {
      userId:      "user-2",
      displayName: "Bob",
      metadata:    { company: "Globex" },
    },
  ],
  source: "bulk_crm_sync",
});

// Poll import status
const status = await client.agents.priming.getImportStatus(
  "agent-id", job.jobId
);
console.log(status.processed, status.total, status.failed);

// List recent import jobs
const jobs = await client.agents.priming.listImportJobs("agent-id", 10);