Skip to main content
Sonzai Docs

インテグレーションガイド

アプリケーションをマインドレイヤーに接続します。REST APIと公式SDKの エンドツーエンドガイドとサンプルコード。

概要

あなたのバックエンドがビジネスロジックとユーザーセッションを管理します。 エージェントのインテリジェンスにはマインドレイヤーを呼び出します。 記憶、パーソナリティ、ムード、関係性、コンテキスト組み立てを管理します。

Go、TypeScript、Python用の公式SDKを使用してREST API経由で統合します。

公式SDK

Go、TypeScript、Python用の公式SDK。各SDKは型付きメソッド、 SSEストリーミング、自動リトライ、エラーハンドリングで完全なREST APIをラップします。

Go

go get github.com/sonz-ai/sonzai-go
GitHubリポジトリ →

TypeScript / JavaScript

bun add @sonzai-labs/agents  # or: npm install @sonzai-labs/agents
GitHubリポジトリ →

Python

pip install sonzai
GitHubリポジトリ →

REST API

JSONベースのエンドポイント。チャット応答はServer-Sent Events(SSE)でストリーミングされます。

認証

すべてのRESTリクエストはプロジェクトAPIキーによるBearer認証を使用します:

# All REST requests use Bearer auth with your project API key
curl -H "Authorization: Bearer sk_your_api_key" \
  https://api.sonz.ai/api/v1/agents/{agentId}/chat

コアインタラクションフロー(REST)

# Chat (SSE streaming response)
POST /api/v1/agents/{agentId}/chat
{ "messages": [{"role":"user","content":"Hello!"}], "user_id": "user-123" }

# Response: Server-Sent Events
# data: {"choices":[{"delta":{"content":"Hi"}}]}
# data: [DONE]

SSE解析

各行はdata: で始まります。プレフィックスを除去して 残りをJSON.parseしてください。ストリームは data: [DONE]で終了します。

利用可能なRESTエンドポイント

POST /api/v1/agents                              Create agent
GET  /api/v1/agents                              List agents
GET  /api/v1/agents/{agentId}                    Get agent
POST /api/v1/agents/{agentId}/chat               Chat (SSE streaming)
GET  /api/v1/agents/{agentId}/notifications       Pending notifications
POST /api/v1/agents/{agentId}/notifications/{id}/consume  Consume notification
GET  /api/v1/agents/{agentId}/notifications/history       Notification history

TypeScript SDK(サーバーサイド)

Node.jsバックエンド、サーバーレス関数、サーバーサイドフレームワーク用。 Node.js >= 18、Bun、Denoで動作します。 ブラウザ/クライアントサイドでは使用不可— APIキーが 露出します。

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

const client = new Sonzai({ apiKey: "sk_your_api_key" });

// Chat (non-streaming)
const response = await client.agents.chat("agent-id", {
  messages: [{ role: "user", content: "Hello!" }],
  userId: "user-123",
});
console.log(response.content);

// Chat (streaming)
for await (const event of client.agents.chatStream("agent-id", {
  messages: [{ role: "user", content: "Tell me a story" }],
  userId: "user-123",
  language: "en",
  timezone: "America/New_York",
})) {
  process.stdout.write(event.choices?.[0]?.delta?.content ?? "");
}

// Memory, personality, context engine data
const memory = await client.agents.memory.list("agent-id", { userId: "user-123" });
const personality = await client.agents.personality.get("agent-id");
const mood = await client.agents.getMood("agent-id", { userId: "user-123" });

Python SDK

Pythonバックエンド、データパイプライン、評価スクリプト用。 同期クライアントと非同期クライアントの両方をサポートします。

from sonzai import Sonzai

client = Sonzai(api_key="sk_your_api_key")

# Chat (non-streaming)
response = client.agents.chat(
    "agent-id",
    messages=[{"role": "user", "content": "Hello!"}],
    user_id="user-123",
)
print(response.content)

# Chat (streaming)
for event in client.agents.chat(
    "agent-id",
    messages=[{"role": "user", "content": "Tell me a story"}],
    user_id="user-123",
    language="en",
    timezone="America/New_York",
    stream=True,
):
    print(event.content, end="", flush=True)

# Memory, personality, context engine data
memory = client.agents.memory.list("agent-id", user_id="user-123")
personality = client.agents.personality.get("agent-id")
mood = client.agents.get_mood("agent-id", user_id="user-123")

client.close()

ブラウザ / フロントエンドアプリ

サーバーサイドプロキシが必要

Sonzai APIはブラウザ(クライアントサイド)リクエストを受け付けません。 APIキーをフロントエンドコードで公開してはいけません。これはOpenAI、 Anthropic、その他のAI APIプロバイダーと同じパターンです。

Webアプリ(React、Next.js、Vueなど)の場合、Sonzaiにプロキシする バックエンドAPIルートを作成します。フロントエンドはあなたのサーバーを 呼び出し、サーバーがAPIキーを使ってSonzaiを呼び出します。

Next.js APIルート

// app/api/chat/route.ts (runs on your server)
import { Sonzai } from "@sonzai-labs/agents";

const client = new Sonzai({ apiKey: process.env.SONZAI_API_KEY! });

export async function POST(req: Request) {
  const { agentId, messages, userId } = await req.json();
  const stream = client.agents.chatStream(agentId, { messages, userId });

  return new Response(
    new ReadableStream({
      async start(controller) {
        for await (const event of stream) {
          controller.enqueue(new TextEncoder().encode(
            `data: ${JSON.stringify(event)}\n\n`
          ));
        }
        controller.enqueue(new TextEncoder().encode("data: [DONE]\n\n"));
        controller.close();
      },
    }),
    { headers: { "Content-Type": "text/event-stream" } }
  );
}

フロントエンド(任意のフレームワーク)

// Calls YOUR server, not Sonzai directly
const res = await fetch("/api/chat", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    agentId: "agent-uuid",
    messages: [{ role: "user", content: "Hello!" }],
    userId: "user-123",
  }),
});

const reader = res.body.getReader();
const decoder = new TextDecoder();
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  // Parse SSE chunks from your proxy
  console.log(decoder.decode(value));
}

Express / Fastify

// server.ts
import express from "express";
import { Sonzai } from "@sonzai-labs/agents";

const app = express();
const client = new Sonzai({ apiKey: process.env.SONZAI_API_KEY! });

app.post("/api/chat", async (req, res) => {
  const { agentId, messages, userId } = req.body;
  res.setHeader("Content-Type", "text/event-stream");

  for await (const event of client.agents.chatStream(agentId, { messages, userId })) {
    res.write(`data: ${JSON.stringify(event)}\n\n`);
  }
  res.write("data: [DONE]\n\n");
  res.end();
});

Go SDK

バックエンドやパフォーマンス重視のアプリケーション向け。Go SDKは REST APIへの型付きアクセスを提供します。

接続セットアップ

import sonzai "github.com/sonz-ai/sonzai-go"

// Connects to api.sonz.ai by default — just provide your API key
client := sonzai.NewClient("sk_your_api_key")

// Override the base URL for local dev / self-hosted
client := sonzai.NewClient("sk_your_api_key",
    sonzai.WithBaseURL("http://localhost:8090"),
)

エージェントライフサイクル

エージェントの作成

ユーザーがアプリケーションで新しいエージェントを作成する場合、 パーソナリティ設定とともに CreateAgentを呼び出します:

resp, err := client.Agents.Create(ctx, sonzai.CreateAgentRequest{
    Name:   "Luna",
    Gender: "female",
    Big5: sonzai.Big5Scores{
        Openness:          0.75,
        Conscientiousness: 0.60,
        Extraversion:      0.80,
        Agreeableness:     0.70,
        Neuroticism:       0.30,
    },
    Language: "en",
})
// resp.AgentID is the platform-generated UUID
// Store this in your user record

エージェントの取得

agent, err := client.Agents.Get(ctx, agentId)
// agent includes: name, personality prompt, big5, mood, etc.

チャットセッションフロー

これがコアの統合ループです。チャットエンドポイントが1回の呼び出しで コンテキスト組み立て、AIストリーミング、状態更新を処理します:

ストリーミングチャット

チャットエンドポイントはコンテキストの組み立て、AI応答のストリーミング、 内部エージェント状態の更新を自動的に処理します:

stream, err := client.Agents.ChatStream(ctx, agentId, sonzai.ChatRequest{
    UserID:    userId,
    Messages: []sonzai.Message{
        {Role: "user", Content: "I had a great day hiking!"},
    },
    Language: "en",
})

// Read streaming events
for event := range stream {
    fmt.Print(event.Content)
}

ムードラベル

ラベル:Blissful(80-100)、Content(60-79)、Neutral(40-59)、 Melancholy(20-39)、Troubled(0-19)。ムードは時間とともに エージェントのパーソナリティベースラインに自然に戻ります。

プロアクティブ通知

エージェントは会話の合間にユーザーに連絡することができます。 トリガーされると、プラットフォームはエージェントの完全な状態を使用して 文脈に即したメッセージを生成し、「保留中」として保存します。 アプリがポーリングし、配信後に通知を消費済みとしてマークします。

RESTポーリング

# Poll for pending proactive messages
GET /api/v1/agents/{agentId}/notifications?status=pending&user_id=user-123

# Response
{
  "notifications": [{
    "message_id": "msg-uuid",
    "user_id": "user-123",
    "check_type": "check_in",
    "intent": "Ask about yesterday's hiking trip",
    "generated_message": "Hey! How was the hike at Mount Rainier?",
    "status": "pending",
    "created_at": "2026-03-07T10:00:00Z"
  }]
}

# After delivering to user, mark consumed
POST /api/v1/agents/{agentId}/notifications/{messageId}/consume

配信のベストプラクティス

30〜60秒ごとにポーリングしてください。再配信を防ぐために、 配信後は必ず消費済みとしてマークしてください。

Webhook統合

イベントコールバック(ウェイクアップ、統合、ブレイクスルー)用の Webhookを登録します:

// Register webhook endpoints
PUT /api/projects/{projectId}/webhooks/{eventType}
{
    "webhook_url": "https://your-server.com/platform/webhooks/wakeup",
    "auth_header": "Bearer YOUR_SERVER_KEY"
}

// Event types:
// - "wakeup"        : Agent wants to proactively reach out
// - "consolidation" : Memory consolidation completed
// - "breakthrough"  : Significant personality evolution

ウェイクアップWebhookペイロード

直接配信用の生成済みメッセージが含まれます:

{
  "event_type": "on_wakeup_ready",
  "agent_id": "agent-uuid",
  "user_id": "user-123",
  "generated_message": "Hey! How was the hike?",
  "wakeup_id": "wakeup-uuid",
  "check_type": "check_in"
}

ポーリングの代替手段

ポーリングをお好みですか?Webhookの代わりに通知APIを使用してください。

例:バックエンド統合フロー

3サービスアーキテクチャ:

Client App            Your Backend                 Mind Layer
     |                      |                              |
     |--- Authenticate --->|                              |
     |                      |                              |
     |--- Create agent ->|                              |
     |                      |--- REST: CreateAgent ------>|
     |                      |<-- Agent ID + Profile ------|
     |<-- Agent ready --|                              |
     |                      |                              |
     |--- Send message ---->|                              |
     |                      |--- REST: Chat (SSE) ------->|
     |<-- Streaming response <-- AI chunks + side effects -|

バックエンドがアプリケーションイベントをマインドレイヤーAPI呼び出しに 変換します。エージェントの動作を変えずにバックエンドを交換したり、 アプリケーション間でエージェントを再利用したりできます。

ナレッジベース(Go SDK)

ドキュメントをアップロードまたは構造化データをプッシュして、 プロジェクトスコープのナレッジグラフを構築します。エージェントは 会話中にこのグラフを検索します。

構造化データのプッシュ

// Insert entities and relationships
resp, err := client.Knowledge.InsertFacts(ctx, projectID, sonzai.InsertFactsOptions{
    Source: "product_catalog",
    Facts: []sonzai.InsertFactEntry{
        {
            EntityType: "product",
            Label:      "Widget Pro",
            Properties: map[string]any{"price": 29.99, "category": "tools"},
        },
    },
    Relationships: []sonzai.InsertRelEntry{
        {FromLabel: "Widget Pro", ToLabel: "Tools", EdgeType: "belongs_to"},
    },
})
fmt.Printf("Created: %d, Updated: %d\n", resp.Created, resp.Updated)

ナレッジグラフの検索

results, err := client.Knowledge.Search(ctx, projectID, sonzai.KBSearchOptions{
    Query: "widget price",
    Limit: 10,
})
for _, r := range results.Results {
    fmt.Printf("%s (%s): score=%.2f\n", r.Label, r.NodeType, r.Score)
}

エンティティスキーマ

// Define a schema so the LLM knows what fields to extract
schema, err := client.Knowledge.CreateSchema(ctx, projectID, sonzai.CreateSchemaOptions{
    EntityType: "product",
    Fields: []sonzai.KBSchemaField{
        {Name: "price", Type: "number", Required: true},
        {Name: "category", Type: "string"},
    },
})

分析ルール

// Create a recommendation rule
rule, err := client.Knowledge.CreateAnalyticsRule(ctx, projectID, sonzai.CreateAnalyticsRuleOptions{
    RuleType: "recommendation",
    Name:     "Similar products",
    Config:   map[string]any{"match_fields": []string{"category"}, "limit": 5},
    Enabled:  true,
})

// Get recommendations
recs, err := client.Knowledge.GetRecommendations(ctx, projectID, rule.RuleID, sourceNodeID, 5)
ユーザープライミング(Go SDK)

ユーザーのメタデータとコンテンツを事前にロードして、AIエージェントが 最初の会話からユーザーを把握できるようにします。メタデータ(名前、会社、 役職)は即座にファクトになり、コンテンツブロックはLLMを通じて 非同期で抽出されます。

単一ユーザーのプライミング

resp, err := client.Agents.Priming.PrimeUser(ctx, agentID, userID, sonzai.PrimeUserOptions{
    DisplayName: "Jane Smith",
    Metadata: &sonzai.PrimeUserMetadata{
        Company: "Acme Corp",
        Title:   "VP Engineering",
        Email:   "[email protected]",
        Custom:  map[string]string{"region": "APAC", "tier": "enterprise"},
    },
    Content: []sonzai.PrimeContentBlock{
        {Type: "text", Body: "Jane led the migration from AWS to GCP..."},
    },
    Source: "crm",
})
fmt.Printf("Job: %s, Facts created: %d\n", resp.JobID, resp.FactsCreated)

バッチインポート

resp, err := client.Agents.Priming.BatchImport(ctx, agentID, sonzai.BatchImportOptions{
    Users: []sonzai.BatchImportUser{
        {UserID: "user-1", DisplayName: "Jane", Metadata: &sonzai.PrimeUserMetadata{Company: "Acme"}},
        {UserID: "user-2", DisplayName: "Bob", Metadata: &sonzai.PrimeUserMetadata{Company: "Globex"}},
    },
    Source: "crm_sync",
})
fmt.Printf("Job: %s, Users: %d\n", resp.JobID, resp.TotalUsers)

メタデータの管理

// Get metadata
meta, err := client.Agents.Priming.GetMetadata(ctx, agentID, userID)

// Update metadata (partial — merges with existing)
updated, err := client.Agents.Priming.UpdateMetadata(ctx, agentID, userID, sonzai.UpdateMetadataOptions{
    Company: ptr("New Corp"),
    Custom:  map[string]string{"tier": "premium"},
})

非同期処理

メタデータファクト(名前、会社、役職)は同期的に作成されます。 コンテンツブロック(テキスト、チャットトランスクリプト)はLLM抽出を通じて バックグラウンドで処理されます。進捗を追跡するにはジョブステータスを ポーリングしてください。

ベストプラクティス

  • StreamChatを使用してください。1回の呼び出しで コンテキスト組み立て、AIストリーミング、状態更新を処理します。
  • アプリケーション状態は常にGameContext.custom_fields経由で 渡してください。プラットフォームはキャッシュしません。
  • ウェイクアップイベント用のWebhookを登録して、エージェントが コンタクトを開始できるようにしてください。
  • パーソナリティ、記憶、関係ロジックを重複させないでください。 エージェントデータの管理はエンジンに任せてください。
  • 通知は30〜60秒ごとにポーリングしてください。再配信を防ぐために、 配信後に消費してください。
  • すべての統合にREST APIを使用します。最高の開発者体験のためにGo、 TypeScript、またはPython用の公式SDKを使用してください。
  • ブラウザアプリはバックエンドを経由してプロキシする必要があります。 クライアントサイドコードでAPIキーを公開しないでください。 上記のブラウザ/フロントエンドアプリセクションを参照してください。