---
title: "クイックスタート"
description: "Ankole をデプロイし、エンタープライズの identity とモデルを設定し、IM チャンネルを接続して、実際の Agent との会話を完了させます。"
url: "https://ankole.agentbull.com/ja-JP/docs/quickstart/"
lang: "ja-JP"
---

> AI Agent 向けドキュメント索引: https://ankole.agentbull.com/ja-JP/llms.txt

# クイックスタート

## Ankole のデプロイ方法

プライベートな Ankole デプロイメントインスタンスには、1 つの control plane と 1 つ以上の Agent Computer Worker があります。control plane は永続的なドメイン状態と監視を所有する管理プラットフォームです。Worker は Agent の実行環境を提供し、Agent の仕事用コンピュータとして機能します。

1 つの Worker が複数の Agent にサービスを提供できます。金融など厳格な分離が必要な環境では、各 Agent に専用の Worker を割り当ててください。仕事用コンピュータは複数のインターンで共有したり、1 人の同僚に割り当てたりできます。

> **💡 知っていましたか？**
>
> 複数の Agent が 1 つの Worker を共有していても、各 Agent は別々の sandbox で実行されます。sandbox は基本的なプロセスとファイルシステムの分離を提供し、Agent 間の干渉を減らします。これは軽量な分離レイヤーであり、絶対的なセキュリティ境界ではありません。

各インスタンスには PostgreSQL と永続ディスクストレージも必要です。シングルホストのデプロイメントでは、ローカルまたは仮想ディスクを使用できます。Kubernetes のデプロイメントには、ReadWriteMany をサポートする NFS または別の共有ボリュームが必要です。

<a id="terminology"></a>

### このガイドで使用する用語

このページは、Ankole のユーザードキュメントとインターフェースで使用される用語を定義します。括弧内の名前は、サードパーティのプラットフォーム、設定フィールド、API に対応します。以降のセクションでは短縮形を使用します。

| 正式用語 | 意味 | 短縮形 |
|---|---|---|
| **Private deployment instance** | 企業がデプロイして管理する、1 つの完全な Ankole システム | Instance |
| **Principal** | Ankole で identity と権限を持つことができる人、Agent、またはシステムサービス | Principal |
| **Identity Provider (IdP)** | Console の SSO を提供し、社員、連絡先、組織構造を同期する外部の identity ソース | IdP |
| **Chat platform** | Slack、Teams、Lark/Feishu、DingTalk、WeCom、Telegram、Discord、LINE、WhatsApp、メールボックスなどの外部の会話プラットフォーム | Platform |
| **Channel Provider** | メッセージを受信して Agent の返信を送信する 1 つのチャットアプリまたは bot 設定 | Channel Provider |
| **Signal Routing Rule (Signal Binding)** | signal ソースから Agent にメッセージまたはイベントを送信するルール | Routing rule |
| **LLM Provider** | モデルサービスのエンドポイント、credential、利用可能なモデルを保存する設定 | LLM Provider |
| **Background Agent Jobs profile (内部キー: `coding`)** | Background Agent Jobs の AIGateway provider とモデルを選択します。通常の会話はコード量によってこれを選択しません | Background Agent Jobs |

## Agent にセットアップを完了させる

このプロンプトを Codex、Claude Code、またはターミナルを操作できる別の Agent に送信できます。

```text
https://ankole.agentbull.com/ja-JP/docs/quickstart/index.md を使って、Ankole のプライベートデプロイメントインスタンスのデプロイと設定を手伝ってください。 まず、私の環境を調査し、Docker Compose、Kubernetes、またはソースからのインストールのいずれかを推奨してください。次に、Identity Provider（IdP）、LLM Provider、Agent、Channel Provider、Signal Routing Rule（Signal Binding）のセットアップを手伝ってください。IdP と IM プラットフォームを指定していない場合は、使用したい identity ソースとチャットプラットフォームを尋ねてください。勝手に選択しないでください。 chat やコマンドの出力に secret を露出しないでください。選択した IM で実際の Agent の返信を受け取ったときにだけ、作業は完了とみなします。
```

<a id="deployment"></a>

## 1. Ankole をデプロイする

1 台のホストには Docker Compose を、エンタープライズのデプロイメントには Kubernetes を使用してください。開発とデバッグにはソースからインストールしてください。

**デプロイ方法を選択**

- Docker Compose · シングルホスト推奨
- Kubernetes · エンタープライズ推奨
- ソースからインストールする

### Docker Compose · シングルホスト推奨

多くのチームに最適な出発点です。Docker を実行する Linux、macOS、Windows の 1 台のホストで、PostgreSQL、control plane、1 つの Agent Computer Worker、Caddy HTTPS を実行できます。

**始める前に**

- Linux amd64 または arm64 のコンテナを実行できる Linux、macOS、または Windows ホスト
- Compose プラグイン付きの Docker Engine、または Docker Desktop
- 永続ディスク、DNS 名、そして 80 と 443 のポート

#### 基本設定 · Docker Compose でインストールする

provider の API key はこのデプロイメントファイルに含めないでください。サインイン後に Console で追加します。

##### 1. デプロイメントパッケージを入手する

```bash
git clone https://github.com/AgentBull/ankole.git
cd ankole/tools/deploy/docker-compose
cp .env.example .env
chmod 600 .env
```

##### 2. 3 つの独立した secret を生成する

このコマンドをコピーして実行してください。その完全な出力を .env に貼り付けます。

```bash
printf '%s\n' \
  '# PostgreSQL database password' \
  "POSTGRES_PASSWORD=$(openssl rand -hex 32)" \
  '' \
  '# ANKOLE master encryption key' \
  "ANKOLE_SECRET_BASE=$(openssl rand -hex 32)" \
  '' \
  '# Authentication key shared by the ANKOLE control plane and Agent Workers' \
  "ANKOLE_RUNTIME_FABRIC_WORKER_AUTH_KEY=$(openssl rand -hex 32)"
```

##### 3. 公開ホストを設定する

ANKOLE_HOST に、このホストを指す DNS 名を設定してください。ACME_EMAIL には、証明書の通知を受信できるアドレスを設定してください。

- `ANKOLE_HOST`: `ankole.example.com` — ユーザーと provider の callback が使用する HTTPS ホスト。
- `ACME_EMAIL`: `ops@example.com` — Caddy の証明書管理用の連絡先アドレス。

##### 4. スタックを起動して確認する

Compose は PostgreSQL を待ち、migration を実行し、Worker key を保存した後、control plane、Worker、Caddy を起動します。

```bash
docker compose pull
docker compose up -d
docker compose ps
```

##### 5. 初回のセットアップを開く

https://<ANKOLE_HOST>/setup を開き、activation code を入力してください。

```bash
docker compose logs control-plane | grep "SETUP ACTIVATION CODE"
```

#### 詳細設定 · 本番運用の制御、バックアップ、ローカル証明書

最初のデプロイメントを本番に移す前に、これらの設定を使用してください。

##### 1. 検証済みのイメージペアを固定する

control-plane と Worker のタグは、RuntimeFabric の検証の後に一緒に移動します。管理された rollout のためには、両方のイメージを同じソースリビジョンの digest に固定してください。

- `ANKOLE_CONTROL_PLANE_IMAGE` — control plane のイメージ、または不変の digest。
- `ANKOLE_WORKER_IMAGE` — 同じ検証済みペアの Worker イメージ、または不変の digest。
- `ANKOLE_POSTGRESQL_IMAGE` — 同梱のデータベースイメージ用の、任意の不変 digest。

##### 2. アップグレードのたびにバックアップを取る

ankole_agents_data ボリュームのスナップショットも取ってください。データベースと Agent Home の復元を、別のホストで一緒にテストしてください。

```bash
docker compose exec -T postgresql \
  pg_dump -U ankole -d ankole -Fc \
  > "ankole-$(date +%Y%m%d).dump"
```

##### 3. 短い停止時間でのアップグレード

```bash
docker compose pull
docker compose down
docker compose up -d --force-recreate
docker compose ps
```

> docker compose down は名前付きボリュームを保持します。docker compose down -v は PostgreSQL、Agent Home、Caddy のデータを削除します。恒久的な削除を意図していて、テスト済みのバックアップが存在する場合以外は -v を使用しないでください。

##### 4. ローカル専用の HTTPS ホストを使用する

ローカルのテストには ANKOLE_HOST=ankole.localhost を設定してください。初回起動の後、Caddy のルート証明書をコピーし、すべてのクライアントで信頼してください。

```bash
docker compose cp \
  caddy:/data/caddy/pki/authorities/local/root.crt \
  ./ankole-local-ca.crt
```

- [Compose の完全な運用ガイド](https://github.com/AgentBull/ankole/blob/main/tools/deploy/docker-compose/README.md)

### Kubernetes · エンタープライズ推奨

既に Kubernetes を運用していて、クラスタスケジューリング、HTTPS Ingress、共有の Agent Home ストレージが必要な場合は、Helm chart を使用してください。

**始める前に**

- Kubernetes 1.27 以降と Helm 3 以降
- Linux amd64 または arm64 のノード
- Agent Home 用の HTTPS Ingress と ReadWriteMany ストレージ

#### 基本設定 · Helm chart をインストールする

最短経路は、pg_search と vector を含む同梱の PostgreSQL 18 イメージを使用します。

##### 1. chart を取得して namespace を作成する

```bash
git clone https://github.com/AgentBull/ankole.git
cd ankole
kubectl create namespace ankole
```

##### 2. bootstrap Secret を作成する

```bash
POSTGRES_PASSWORD="$(openssl rand -hex 24)"
ANKOLE_SECRET_BASE="$(openssl rand -hex 32)"
ANKOLE_WORKER_AUTH_KEY="$(openssl rand -hex 24)"

kubectl -n ankole create secret generic ankole-bootstrap \
  --from-literal="POSTGRES_PASSWORD=${POSTGRES_PASSWORD}" \
  --from-literal="ANKOLE_SECRET_BASE=${ANKOLE_SECRET_BASE}" \
  --from-literal="ANKOLE_RUNTIME_FABRIC_WORKER_AUTH_KEY=${ANKOLE_WORKER_AUTH_KEY}" \
  --from-literal="DATABASE_URL=ecto://ankole:${POSTGRES_PASSWORD}@ankole-postgresql:5432/ankole"

unset POSTGRES_PASSWORD ANKOLE_SECRET_BASE ANKOLE_WORKER_AUTH_KEY
```

##### 3. values-production.yaml を作成する

ホスト、Ingress の詳細、両方の StorageClass 名を置き換えてください。上記の DATABASE_URL を使用する場合は、fullnameOverride を維持してください。

```yaml
fullnameOverride: ankole

secrets:
  existingSecret: ankole-bootstrap

controlPlane:
  publicHost: ankole.example.com

worker:
  agents:
    persistence:
      storageClass: nfs-rwx
      size: 100Gi

postgresql:
  enabled: true
  persistence:
    storageClass: standard
    size: 50Gi

ingress:
  enabled: true
  className: nginx
  hosts:
    - host: ankole.example.com
      paths:
        - path: /
          pathType: Prefix
  tls:
    - secretName: ankole-tls
      hosts:
        - ankole.example.com
```

##### 4. インストールして待機する

```bash
helm upgrade --install ankole ./tools/deploy/helm/ankole-agent \
  --namespace ankole \
  --values values-production.yaml \
  --wait \
  --timeout 15m
```

##### 5. ワークロードを確認する

```bash
kubectl -n ankole get pods
kubectl -n ankole rollout status deployment/ankole-control-plane --timeout=10m
kubectl -n ankole rollout status deployment/ankole-worker --timeout=10m
```

##### 6. 初回のセットアップを開く

https://ankole.example.com/setup を開き、activation code を入力してください。

```bash
kubectl -n ankole logs deployment/ankole-control-plane \
  -c control-plane | grep "SETUP ACTIVATION CODE"
```

#### 詳細設定 · 外部 PostgreSQL、イメージポリシー、クラスタセキュリティ

管理された本番 rollout の前に、これらの項目を確認してください。

##### 1. 外部 PostgreSQL サーバーを使用する

そのサーバーは PostgreSQL 18 以降を実行し、pg_search を preload し、アプリケーションデータベースの所有者が pg_search と vector を使用できる必要があります。

- `postgresql.enabled`: `false` — 同梱のデータベースを無効にします。
- `DATABASE_URL` — 外部データベースの URL を ankole-bootstrap に保存します。

```sql
SHOW server_version_num;
SHOW shared_preload_libraries;

SELECT name, default_version, installed_version
FROM pg_available_extensions
WHERE name IN ('pg_search', 'vector')
ORDER BY name;
```

##### 2. Worker のセキュリティプロファイルを確認する

強力な bubblewrap 分離には、SYS_ADMIN、unconfined の seccomp プロファイル、そして unmask された /proc が必要です。chart はこれらを設定しますが、クラスタのアドミッションポリシーがそれらを許可する必要があります。

> Worker ノードは、信頼できるファーストパーティのコンピュート境界として扱ってください。クラスタポリシーがこのプロファイルを拒否する場合は、専用のノードプール、または承認された同等のサンドボックスを使用してください。

##### 3. 一致するイメージを固定してアップグレードする

同じ検証済みソースリビジョンの control plane と Worker の digest を固定してください。helm upgrade の前に PostgreSQL と Agent Home をバックアップしてください。

> Helm の rollback はデータベースの migration を元に戻しません。アプリケーションの rollback が古いスキーマも必要とする場合は、データベースのバックアップを復元してください。

##### 4. 完全な chart 契約を読む

- [Helm の完全なデプロイメントガイド](https://github.com/AgentBull/ankole/blob/main/tools/deploy/helm/ankole-agent/README.md)

### ソースからインストールする

開発、デバッグ、ローカル評価にはソースパスを使用してください。PostgreSQL、Phoenix、Console、フロントエンドアセット、そして管理された Docker Worker を 1 つ起動します。

**始める前に**

- macOS または Linux。Windows では WSL2 を使用してください
- システムパッケージをインストールできるアカウント
- Docker Desktop または Docker Engine

#### 基本設定 · 開発環境を実行する

##### 1. リポジトリをクローンする

残りのコマンドはリポジトリのルートから実行してください。

```bash
git clone https://github.com/AgentBull/ankole.git
cd ankole
git status --short
```

##### 2. 固定されたツールチェーンをインストールする

このスクリプトは、ビルドパッケージ、Docker、Rust、Elixir と Erlang、そしてリポジトリが固定する Bun バージョンをインストールします。

```bash
bash tools/devkit/scripts/env-setup.sh
```

##### 3. 新しいターミナルを開いてすべての境界を確認する

macOS では、先に Docker Desktop を起動してください。Linux では、インストーラがあなたのユーザーを docker グループに追加した場合は、サインアウトして再サインインしてください。

```bash
bun --version
elixir --version
rustc --version
cargo clippy --version
docker compose version
docker info
```

##### 4. 依存関係をインストールして PostgreSQL を初期化する

```bash
bun install
bun run services:start
bun run services:status
bun run control-plane:setup
```

##### 5. Ankole を起動する

このターミナルは開いたままにしてください。http://localhost:4000 を開き、開発サーバーが出力した activation code を使用してください。

```bash
bun dev
```

#### 詳細設定 · ローカルチェック、シャットダウン、転送された origin

これらのコントロールは、完全な runtime に対応して開発する場合や、リモートワークスペースを使用する場合に役立ちます。

##### 1. 別のターミナルで activation code を読む

```bash
bun run kit show bootstrap-activation-code
```

##### 2. 可視の runtime 境界を確認する

bun dev ターミナルで Ctrl+C を使い、control plane と Worker を停止してください。終了時に PostgreSQL も別途停止してください。

```bash
bun run services:status
curl -I http://localhost:4000/
docker ps --filter name=ankole-dev-agent-computer
```

```bash
bun run services:stop
```

##### 3. Codespaces または別の転送された origin を使用する

転送された HTTPS origin を IdP に登録してください。localhost の callback と転送された callback は異なる URL なので、ブラウザが使用する URL に対してサインインを確認してください。

> このパスは開発用です。本番デプロイメントには Docker Compose または Kubernetes を使用してください。

<a id="identity-providers"></a>

## 2. 最初に identity provider をセットアップする

Ankole はエンタープライズ内のプライベートデプロイメント用に設計されています。各エンタープライズは 1 つのインスタンスを運用します。そのインスタンス内では、Agent、社員、システムサービスが Principal として表現され、認可モジュールがそれらの権限を管理します。

Hermes Agent や OpenClaw と同様に、Ankole はチャットチャンネルに接続します。また、エンタープライズの identity ソースにも接続し、社員、ディレクトリの連絡先、組織構造を同期します。チャットチャンネルを設定する前に、Identity Provider（IdP）を設定してください。

| 設定 | 制御するもの | 設定場所 |
|---|---|---|
| **Identity Provider (IdP)** | Console の SSO、およびエンタープライズのディレクトリから同期される社員、連絡先、組織構造、権限グループ | 最初に `/setup`、その後 **Console → Identity Providers** |
| **Channel Provider** | メッセージを受信して Agent の返信を送信する IM アプリまたは bot | **Console → Signal Routing** |

identity ソースとチャットチャンネルには異なるプラットフォームを使用できます。社員は Google Workspace でサインインし、Slack で Agent と会話できます。Entra ID が identity を提供し、Lark、Slack、DingTalk、Teams、または WeCom が会話を運ぶこともできます。

### お使いの IdP のセットアップを完了する

エンタープライズが使用する identity ソースを選択してください。各タブは provider のコンソールから始まり、最初のサインインとディレクトリ同期で終わります。

アダプタを初めて有効にする場合は、最初のサインインの後に control plane を再起動してください。この再起動で、ディレクトリ接続や Graph サブスクリプションなどのプラグインのバックグラウンド作業が開始されます。

**identity provider を選択**

- Slack
- Microsoft Entra ID
- Google Workspace
- Lark / Feishu
- DingTalk
- WeCom

#### Slack

Console へのサインイン、ワークスペースメンバーとユーザーグループの同期に 1 つの Slack app を使用します。デフォルトのセットアップには、OAuth client、Bot Token、App Token が必要です。

**始める前に**

- Slack app を作成してインストールできるワークスペース管理者
- Ankole の公開 HTTPS アドレス
- 最初のサインイン用のワークスペースメンバーアカウント

##### 基本設定 · Slack IdP をセットアップする

###### 1. Ankole から callback URL をコピーする

https://<ANKOLE_HOST>/setup を開き、activation code を入力してください。プラグインページで Slack Adapter を選択し、選択を保存してから Slack を選択してください。

Configuration ID（Provider ID）は slack-main のままにしてください。Copy を使ってログイン callback URL をコピーしてください。この URL を手で入力したり変更したりしないでください。

###### 2. Slack app を作成する

Slack API の Your Apps を開き、Create New App → From scratch を選択してください。アプリ名を入力し、社員が所属するワークスペースを選択してください。

Basic Information → App Credentials を開いてください。Client ID と Client Secret をコピーしてください。

- [Slack Your Apps を開く](https://api.slack.com/apps)

###### 3. ログイン callback を登録する

OAuth & Permissions → Redirect URLs を開いてください。Add New Redirect URL を選択し、Ankole の完全な URL を貼り付けて保存してください。

Ankole はデフォルトで openid、profile、email のサインイン scope を要求します。それらを chat bot の scope に置き換えないでください。

- [Slack サインインガイド](https://api.slack.com/authentication/sign-in-with-slack)

###### 4. ディレクトリアクセスを許可して Bot Token を取得する

OAuth & Permissions で、下記の 3 つの scope を Bot Token Scopes に追加してください。その後、Install to Workspace を選択してインストールを承認してください。

- `users:read` — メンバープロファイルを読み取ります
- `users:read.email` — メンバーのメールアドレスを読み取ります
- `usergroups:read` — ユーザーグループとそのメンバーを読み取ります

> インストール後に Bot User OAuth Token をコピーしてください。xoxb- で始まる必要があります。scope を変更するたびにアプリを再インストールしてください。

###### 5. App Token を取得して Socket Mode を有効にする

Basic Information → App-Level Tokens を開いてください。Generate Token and Scopes を選択し、下記の scope を追加して、生成された xapp- token をコピーしてください。その後、Socket Mode を開き、Enable Socket Mode をオンにしてください。

- `connections:write` — App Token が Socket Mode 接続を開けるようにします

###### 6. ディレクトリイベントを購読する

Event Subscriptions を開いてイベントを有効にしてください。Subscribe to bot events で、下記の 5 つのイベントをすべて追加してください。

- `team_join` — メンバーがワークスペースに参加します
- `user_change` — メンバーのプロファイルが変更されます
- `subteam_created` — ユーザーグループが作成されます
- `subteam_updated` — ユーザーグループが変更されます
- `subteam_members_changed` — ユーザーグループのメンバーシップが変更されます

- [Slack Socket Mode ガイド](https://api.slack.com/apis/connections/socket)

###### 7. Slack の値を Ankole に入力する

Sync directory と Sync directory changes をオンにしたままにしてください。Validate configuration を選択してサインインしてください。その後、Slack の認可を完了してください。

- Client ID: Basic Information の Client ID
- Client Secret: 同じページの Client Secret
- Workspace ID: 任意。Slack の Web URL の /client/ の後に続く T… の値を入力すると、サインインするワークスペースを事前選択できます。ディレクトリ同期は制限されません
- Bot User OAuth Token: xoxb- token
- App-Level Token: xapp- token

###### 8. サインインと最初の同期を確認する

Slack が Ankole に戻ると、このユーザーが最初の root administrator になります。Console → Identity Providers を開き、slack-main を選択して Run full sync を選択してください。

同期が終わったら、Console → Principals と Principal groups で、ワークスペースのメンバーと Slack のユーザーグループを確認してください。

##### 詳細設定 · サインインのみ、リアルタイム同期、credential の更新

Slack のディレクトリが必要ない場合のみ、デフォルトのディレクトリ同期をオフにしてください。

###### 1. Slack をサインイン専用にする

Sync directory をオフにすると、Bot User OAuth Token は不要になり、リアルタイム同期もオフになります。Client ID と Client Secret は引き続き必要です。

###### 2. リアルタイムイベントなしでフル同期を使用する

Sync directory をオンにしたまま、Sync directory changes をオフにしてください。この設定には Bot User OAuth Token が必要ですが、App-Level Token は不要です。メンバーの変更は次のフル同期後に反映されます。

###### 3. scope または token を更新する

Slack の scope または Bot Token を変更した後は、アプリを再インストールし、Identity の token を更新してください。App Token はローテーション後に更新してください。更新しないと Socket Mode が接続できません。

#### Microsoft Entra ID

シングルテナントの Entra アプリを登録します。ユーザーを Console にサインインさせ、ユーザーとグループを読み取り、Microsoft Graph 経由でディレクトリの変更を受け取ります。

**始める前に**

- アプリを登録して管理者同意を付与できる Entra 管理者
- Ankole の公開 HTTPS アドレス
- 最初のサインイン用のテナントメンバーアカウント

##### 基本設定 · Microsoft Entra ID をセットアップする

###### 1. Ankole から callback URL をコピーする

https://<ANKOLE_HOST>/setup を開き、activation code を入力してください。プラグインページで Microsoft 365 Adapter を選択し、選択を保存してから Entra ID を選択してください。

Configuration ID（Provider ID）は entra-id-main のままにしてください。Copy を使ってログイン callback URL をコピーしてください。

###### 2. シングルテナントのアプリを登録する

Microsoft Entra 管理センターを開いてください。Entra ID → App registrations → New registration に進み、名前を入力し、Accounts in this organizational directory only を選択してください。

Redirect URI で Web を選択し、Ankole の完全な callback URL を貼り付けてください。その後、Register を選択してください。

- [Microsoft アプリ登録ガイド](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app)

###### 3. アプリの 3 つの値をコピーする

アプリの Overview ページで、Application (client) ID と Directory (tenant) ID をコピーしてください。

Certificates & secrets → Client secrets → New client secret を開いてください。作成したらすぐに Value をコピーしてください。Secret ID はコピーしないでください。ページを離れると Value は非表示になります。

###### 4. Microsoft Graph の権限を付与する

API permissions → Add a permission → Microsoft Graph を開いてください。下記の 3 つの権限を追加してください。その後、<organization> の Grant admin consent を選択してください。3 つすべてが granted ステータスになっていることを確認してください。

- `User.Read` — 委任された権限
- `User.Read.All` — アプリケーション権限
- `Group.Read.All` — アプリケーション権限

- [Microsoft Graph 権限リファレンス](https://learn.microsoft.com/en-us/graph/permissions-reference)

###### 5. Entra の値を Ankole に入力する

Sync directory と Sync directory changes をオンにしたままにしてください。Validate configuration を選択してサインインしてください。このテナントのアカウントを使用してください。

- Directory (tenant) ID: アプリの Overview ページの値
- Application (client) ID: アプリの Overview ページの値
- Client secret value: secret の Value
- Ankole public URL: https://<ANKOLE_HOST>。内部のコンテナやクラスタのアドレスではない

###### 6. サインインと最初の同期を確認する

サインインの後、このユーザーが最初の root administrator になります。Console → Identity Providers を開き、entra-id-main を選択して Run full sync を選択してください。

同期が終わったら、Principals と Principal groups で、テナントのユーザーとグループを確認してください。

##### 詳細設定 · Graph 通知、ゲスト、グループフィルタ

リアルタイム同期のためには、Microsoft Graph がパブリックインターネットから Ankole に到達できる必要があります。

###### 1. 通知エンドポイントに到達できるようにする

Sync directory changes がオンの場合、Ankole public URL は有効な公開 HTTPS アドレスでなければなりません。Ankole はその配下に /webhooks/v1/entra-id/entra-id-main/directory を作成し、Graph のサブスクリプションを管理します。

- [Microsoft Graph 変更通知ガイド](https://learn.microsoft.com/en-us/graph/change-notifications-overview)

###### 2. 公開の ingress なしでリアルタイム同期をオフにする

Graph がこのインスタンスに到達できない場合は、保存する前に Sync directory changes をオフにしてください。フル同期は引き続き動作し、Ankole public URL は不要になります。

###### 3. 必要な場合のみゲストを含めるかグループをフィルタする

Include guest users はデフォルトでオフです。Synced groups filter は Microsoft Graph の OData $filter を受け入れます。フィルタの結果を権限の失敗と誤認しないように、先にフィルタなしのフル同期を完了してください。

#### Google Workspace

Google のサインインとディレクトリアクセスは別々の credential を使用します。OAuth client がサインインを処理し、domain-wide delegation を持つサービスアカウントがユーザーとグループを同期します。

**始める前に**

- Google Workspace のスーパー管理者
- Google Cloud プロジェクトを管理できるアカウント
- Ankole の公開 HTTPS アドレス

##### 基本設定 · Google Workspace をセットアップする

###### 1. Ankole から callback URL をコピーする

https://<ANKOLE_HOST>/setup を開き、activation code を入力してください。プラグインページで Google Workspace Adapter を選択し、選択を保存してから Google Workspace を選択してください。

Configuration ID（Provider ID）は google-workspace-main のままにしてください。Copy を使ってログイン callback URL をコピーしてください。

###### 2. Google Cloud プロジェクトを準備する

Google Cloud Console を開き、組織が所有するプロジェクトを選択または作成してください。API Library で Admin SDK API を見つけて有効にしてください。

Google Auth platform を開いて、アプリ情報を完成させてください。Audience を Internal に設定すると、このアプリはこの Workspace の社員向けになります。

- [Google Cloud Console を開く](https://console.cloud.google.com/)

###### 3. サインイン用の OAuth client を作成する

Google Auth platform → Clients → Create client を開いてください。アプリケーションタイプとして Web application を選択してください。

Authorized redirect URIs で、Ankole の完全な callback URL を貼り付けてください。client を作成し、Client ID と Client Secret をコピーしてください。

- [Google OAuth client ガイド](https://developers.google.com/workspace/guides/create-credentials)

###### 4. ディレクトリ同期用のサービスアカウントを作成する

IAM & Admin → Service Accounts を開き、サービスアカウントを作成してください。その詳細を開いて、Google Workspace の domain-wide delegation を有効にし、数値の Client ID を記録してください。

Keys → Add key → Create new key を開き、JSON を選択してください。JSON ファイルの完全な内容を Ankole に貼り付けます。このファイルをリポジトリにコミットしないでください。

- [Google サービスアカウントガイド](https://developers.google.com/identity/protocols/oauth2/service-account)

###### 5. Workspace で domain-wide delegation を承認する

admin.google.com を開いてください。Security → Access and data control → API Controls → Manage Domain Wide Delegation に進み、Add new を選択してください。

サービスの数値 Client ID を入力してください。OAuth scopes は 1 つのフィールドなので、下記の完全な行をコピーして貼り付け、承認してください。

**OAuth scope をすべてコピー**

```text
https://www.googleapis.com/auth/admin.directory.user.readonly,https://www.googleapis.com/auth/admin.directory.group.readonly,https://www.googleapis.com/auth/admin.directory.group.member.readonly
```

- [Google Directory API 認可ガイド](https://developers.google.com/workspace/admin/directory/v1/guides/authorizing)

###### 6. Google の値を Ankole に入力する

Sync directory をオンにしたままにしてください。Validate configuration を選択してサインインしてください。許可されたドメインの Workspace アカウントを使用してください。

- OAuth client ID と OAuth client secret: Web application の OAuth client の credential
- Allowed Workspace domains: @ なしの Workspace ドメイン（例：example.com）
- Service account JSON key: JSON key ファイルの完全な内容
- Delegated administrator email: ユーザーとグループを読み取れる Workspace 管理者

###### 7. サインインと最初の同期を確認する

サインインの後、このユーザーが最初の root administrator になります。Console → Identity Providers を開き、google-workspace-main を選択して Run full sync を選択してください。

同期が終わったら、Principals と Principal groups で、Workspace のユーザー、グループ、メンバーシップを確認してください。

##### 詳細設定 · ドメイン境界、同期タイミング、サービスアカウント

Google Workspace はフル同期のみをサポートします。リアルタイムのディレクトリイベントをこのアダプタに送信しません。

###### 1. Allowed Workspace domains を狭く保つ

エンタープライズが使用する Workspace ドメインのみを入力してください。Ankole は Google 検証済みのメールと Workspace の hosted-domain claim も要求します。一般の gmail.com アカウントにはそのような claim がないため、Google が認証しても Ankole はそれを拒否します。

###### 2. ディレクトリの変更後に別のフル同期を実行する

Google Workspace アダプタはリアルタイム同期をサポートしていません。社員を追加した後、グループを変更した後、またはアカウントを停止した後は、Console → Identity Providers でフル同期を再度実行してください。

###### 3. サービスアカウントのアクセスを減らしてローテーションする

最初の検証の後、ユーザーとグループの読み取りアクセスを持つ専用の管理者を Delegated administrator email として使用できます。JSON key をローテーションするときは、Ankole の Service account JSON key を更新してください。

#### Lark / Feishu

カスタムの企業アプリを作成します。その App ID と App Secret が、サインイン、社員と部門の同期、そして長い接続経由のリアルタイムのディレクトリイベントを提供します。

**始める前に**

- カスタムの企業アプリを作成して公開できる管理者
- ディレクトリの権限を承認できるエンタープライズ管理者
- 最初のサインイン用の Lark または Feishu の社員アカウント

##### 基本設定 · Lark または Feishu IdP をセットアップする

###### 1. Ankole から callback URL をコピーする

https://<ANKOLE_HOST>/setup を開き、activation code を入力してください。プラグインページで Lark Adapter を選択し、選択を保存してから Lark or Feishu を選択してください。

Configuration ID（Provider ID）は lark-main のままにしてください。Copy を使ってログイン callback URL をコピーしてください。

###### 2. カスタムの企業アプリを作成する

Feishu テナントには Feishu Open Platform を、国際的な Lark テナントには Lark Developer を使用してください。カスタムの企業アプリを作成してください。

Credentials & Basic Info を開き、App ID と App Secret をコピーしてください。

- [Feishu Open Platform を開く](https://open.feishu.cn/app)
- [Lark Developer を開く](https://open.larksuite.com/app)

###### 3. ログイン callback を登録する

Development Configuration → Security Settings → Redirect URLs を開き、Ankole の完全な URL を追加してください。

callback は正確に一致する必要があります。scheme、host、port、または provider ID が異なると、サインインは失敗します。

- [Feishu Web サインインガイド](https://open.feishu.cn/document/sso/web-application-end-user-consent/guide)

###### 4. サインインとディレクトリの権限をインポートする

Permissions を開き、一括インポートまたはエクスポートのアクションを選択してください。下記の JSON を貼り付けて、インポートを確認してください。権限がエンタープライズの承認を必要とする場合は、そのステータスが active になるまで待ってください。

**JSON を一括インポート**

```text
{
  "scopes": {
    "tenant": [
      "contact:contact.base:readonly",
      "contact:department.base:readonly",
      "contact:department.organize:readonly",
      "contact:user.base:readonly",
      "contact:user.department:readonly",
      "contact:user.email:readonly",
      "contact:user.employee_id:readonly"
    ],
    "user": [
      "contact:user.employee_id:readonly"
    ]
  }
}
```

###### 5. 長い接続のディレクトリイベントを設定する

Events & Callbacks → Event Configuration を開き、long-connection または WebSocket の配信オプションを選択してください。下記の 7 つのイベントを追加してください。

- `contact.user.created_v3`
- `contact.user.updated_v3`
- `contact.user.deleted_v3`
- `contact.department.created_v3`
- `contact.department.updated_v3`
- `contact.department.deleted_v3`
- `contact.scope.updated_v3`

###### 6. 利用範囲を設定して公開する

最初の管理者と、同期する必要があるすべての部門をアプリの利用範囲に追加してください。アプリのバージョンを作成して公開してください。公開されていない callback、権限、イベントの変更は社員に適用されません。

###### 7. Lark または Feishu の値を Ankole に入力する

デフォルトのディレクトリ同期設定は、通常は変更する必要がありません。Validate configuration を選択してサインインしてください。その後、Console → Identity Providers を開き、lark-main のフル同期を実行してください。

Principals と Principal groups で、社員、部門、メンバーシップを確認してください。

- App ID と App Secret: Credentials & Basic Info の値
- Service region: Feishu には Feishu (Mainland China)、Lark には Lark (Global) を選択

##### 詳細設定 · 長い接続、アプリの利用範囲、チャットアプリ

control plane が長い接続を開きます。公開の Feishu webhook は不要です。

###### 1. リアルタイムイベントなしでフル同期を使用する

詳細設定（通常は変更不要）で、ディレクトリイベントが必要ない場合は Sync directory changes をオフにしてください。社員と部門の変更は、次のフル同期後に反映されます。

###### 2. アプリの利用範囲をサインインの境界として使用する

アプリの利用範囲が、誰がサインインできるかを制御します。部門または社員を追加したら、範囲を更新して新しいバージョンを公開してください。

###### 3. identity 用とチャット用に別々のアプリを使用する

1 つのカスタムアプリを両方の役割に使用できますが、通常の運用では別々のアプリの方が優れています。サインインとディレクトリの権限は IdP アプリに置いてください。bot の権限はチャットアプリに置いてください。両方のアプリで、同じ組織のために同じ platformSubjectNamespace を使用できます。

#### DingTalk

内部のエンタープライズアプリを作成します。同じ Client ID と Client Secret が、サインイン、組織ディレクトリへのアクセス、Stream 経由のリアルタイム変更を提供します。

**始める前に**

- 内部アプリを作成して公開できる DingTalk 管理者
- ディレクトリ API へのアクセスを承認できる管理者
- 最初のサインイン用の組織内の社員アカウント

##### 基本設定 · DingTalk IdP をセットアップする

###### 1. Ankole から callback URL をコピーする

https://<ANKOLE_HOST>/setup を開き、activation code を入力してください。プラグインページで DingTalk Adapter を選択し、選択を保存してから DingTalk を選択してください。

Configuration ID（Provider ID）は dingtalk-main のままにしてください。Copy を使ってログイン callback URL をコピーしてください。

###### 2. 内部のエンタープライズアプリを作成する

DingTalk 開発者コンソールを開いてください。App Development → Internal Enterprise Apps に進み、アプリを作成してください。

Basic Information → Credentials を開いてください。以前は AppKey と呼ばれていた Client ID と、以前は AppSecret と呼ばれていた Client Secret をコピーしてください。

- [DingTalk 開発者コンソールを開く](https://open-dev.dingtalk.com/)

###### 3. ログイン callback を登録する

Development Configuration → Security Settings → Redirect URL を開いてください。Ankole の完全な URL を貼り付けて保存してください。

サインイン scope は openid corpid のままにしてください。corpid の claim により、サインインが選択した DingTalk 組織に制限されます。

###### 4. サインインとディレクトリ API の権限をリクエストする

Permission Management → Contacts Management を開いてください。下記の操作の読み取りアクセスをリクエストしてください。ディレクトリの範囲を全社員に設定するか、サインインと同期が必要なすべての部門を含めてください。

- `Contact.User.Read` — 個人の連絡先情報を読み取ります
- `Get a user ID by unionId`
- `Get user details`
- `Get child department IDs`
- `Get department details`
- `Get basic department user information`

###### 5. Stream 経由でディレクトリの変更を購読する

Events & Callbacks を開き、Stream モードを選択してください。下記の 10 のイベントを追加してください。これらは社員、部門、管理者、組織の変更をカバーします。

- `user_add_org`
- `user_modify_org`
- `user_leave_org`
- `user_active_org`
- `org_dept_create`
- `org_dept_modify`
- `org_dept_remove`
- `org_admin_add`
- `org_admin_remove`
- `org_remove`

- [DingTalk 社員変更 Stream ガイド](https://open.dingtalk.com/document/orgapp/personnel-platform-employee-change-event-stream)

###### 6. 利用範囲を設定して公開する

最初の管理者と、同期する必要がある部門をアプリの利用範囲に追加してください。callback、権限、イベント設定を含むバージョンを作成して公開してください。

###### 7. DingTalk の値を Ankole に入力する

Sync directory と Sync directory changes をオンにしたままにしてください。Validate configuration を選択してサインインしてください。Ankole は DingTalk のサインインを開く前に credential を確認します。

サインインの後、Console → Identity Providers を開き、dingtalk-main のフル同期を実行してください。Principals と Principal groups で、社員と部門を確認してください。

- Client ID (AppKey): credential ページの Client ID
- Client Secret (AppSecret): 同じページの Client Secret

##### 詳細設定 · Stream、ディレクトリの範囲、ページサイズ

control plane が Stream 接続を開きます。公開の webhook は不要です。

###### 1. Stream イベントなしでフル同期を使用する

ディレクトリイベントが必要ない場合は Sync directory changes をオフにしてください。社員と部門の変更は、次のフル同期後に反映されます。

###### 2. ディレクトリの権限範囲を確認する

同期で人や部門が欠ける場合は、Permission Management のディレクトリ範囲を確認してください。承認された API 権限でも、範囲がそれを除外していると不完全なデータを返すことがあります。

###### 3. 最初はデフォルトのページサイズを維持する

デフォルトのページサイズは 50 で、許可される範囲は 1〜100 です。デフォルトでフル同期を 1 回完了させてください。測定されたレート制限またはレスポンスサイズの問題がある場合のみ変更してください。

#### WeCom

自建アプリが QR サインインを担い、専用の Contacts 同期 secret が定期的なフル同期でメンバーと部門をインポートします。サインインとディレクトリ API の呼び出しは、どちらも固定の出口 IP を必要とします。

**始める前に**

- WeCom 企業のスーパー管理者アカウント
- 固定の出口 IP を持つ Ankole デプロイメント
- 最初のサインイン用の企業内のメンバーアカウント

##### 基本設定 · WeCom IdP をセットアップする

###### 1. Ankole から callback URL をコピーする

https://<ANKOLE_HOST>/setup を開き、activation code を入力してください。プラグインページで WeCom Adapter を選択し、選択を保存してから WeCom を選択してください。

Configuration ID（Provider ID）は wecom-main のままにしてください。Copy を使ってログイン callback URL をコピーしてください。

###### 2. Corp ID を記録する

WeCom 管理コンソールを開いてください。My Company → Company information に進み、Corp ID をコピーしてください。

- [WeCom 管理コンソールを開く](https://work.weixin.qq.com/wework_admin/)

###### 3. 信頼ドメインと信頼 IP を持つ自建アプリを作成する

App Management → Self-built → Create app に進みます。アプリの詳細を開き、AgentId と Secret をコピーしてください。

同じページで 2 つの値を設定してください。Web 認可の信頼ドメインとして Ankole のドメインを追加し、デプロイメントの出口 IP を信頼 IP リストに追加してください。

> 信頼 IP のエントリが欠けていると、サインインと API 呼び出しがエラー 60020 で失敗します。信頼ドメインが欠けていると、QR スキャン後のリダイレクトがブロックされます。

###### 4. Contacts 同期を有効にして専用の secret を記録する

Security & Administration → Management tools → Contacts sync に進みます。API 同期を有効にし、専用の secret をコピーし、それ専用の信頼 IP を登録してください。

2022 年 6 月以降、通常のアプリ secret はメンバー名などのプロファイルフィールドを返さなくなりました。この専用の secret がないと、ディレクトリ同期は利用できず、サインインしたユーザーは素の user ID のままになります。

###### 5. WeCom の値を Ankole に入力する

Enable login と Sync directory をオンにしたままにしてください。Validate configuration を選択してサインインし、WeCom の QR サインインを完了してください。

- Corp ID: Company information の値
- 自建アプリの AgentId / Secret: アプリ詳細の 2 つの値
- Contacts 同期 Secret: Contacts 同期ページの専用の secret

###### 6. サインインと最初の同期を確認する

最初にサインインしたメンバーが最初の root administrator になります。Console → Identity Providers を開き、wecom-main を選択してフル同期を実行してください。

Principals と Principal groups で、メンバーと部門を確認してください。

##### 詳細設定 · 同期の頻度、信頼 IP、サインインのみ

WeCom はリアルタイムのディレクトリイベントを送信しません。変更は定期的なフル同期で収束します。

###### 1. ディレクトリの変更後にフル同期を実行する

WeCom はディレクトリの変更を Ankole にプッシュしません。メンバーを追加した後や部門を変更した後は、Console → Identity Providers でフル同期を実行するか、次の定期的な同期を待ってください。

###### 2. 出口 IP が変わったら両方の信頼 IP リストを更新する

自建アプリと Contacts 同期は、それぞれ独自の信頼 IP リストを持っています。移行または出口 IP の変更の後は、両方のリストを更新してください。更新しないと、サインインと同期の両方がエラー 60020 で失敗します。

###### 3. ディレクトリ同期なしでサインインを使用する

Sync directory をオフにすると、Contacts 同期の secret は任意になります。サインインした Principal は、名前や部門グループのない素の WeCom アカウント ID のままになります。

<a id="llm-providers"></a>

## 3. LLM Provider を追加して Agent を作成する

Agent のモデルプロファイルはモデル参照を保存するため、最初に LLM Provider を追加してください。Console にサインインし、**Providers → New provider** を開いて、provider の種類を選択し、安定した Provider ID を付け、エンドポイントと credential のフィールドを入力して保存してください。

provider の credential は control plane 内で暗号化されたまま保持されます。デプロイメントの環境ファイルや Agent ファイルに配置しないでください。

**Agents → New Agent** を開いてください。Agent に安定した UID、明確な表示名、そして何を所有し何が許容可能な結果とみなされるかを示す mission を与えてください。

次に、そのモデルプロファイルを設定します。

| プロファイル | 初回実行での用途 |
|---|---|
| `primary` | メインの推論モデル |
| `light` | 短く頻繁な仕事 |
| `heavy` | 難しい総合 |

Agent が実行できるようになるには、3 つすべてが必要です。最初の会話では、同じ既知の正常な provider とモデルを 3 つすべてにバインドできます。エンドツーエンドの経路が動作した後にのみ分割してください。

### 詳細設定 · 任意の Agent profile と Brain メンテナンス

Agent の能力 profile は必要な場合だけ設定します。Brain は検索モデルだけをインスタンス全体で保持します。

#### 1. 任意の Agent 能力 profile を追加する

- `Background Agent Jobs` — coding profile を使って、永続的な Background Agent Jobs を実行します。メッセージにコードが多くても、通常の会話はこの profile を選びません。
- `vision_fallback` — プライマリモデルが画像を検査できないときのフォールバック。
- `web_search / web_fetch` — Web の発見とページ取得用の provider。
- `image_generate` — 画像生成用のモデル。

#### 2. Brain メンテナンス Agent と検索モデルを選択する

Console → AppConfigure → Brain を開きます。有効な Brain メンテナンス Agent を選択します。Brain のすべてのモデル呼び出しは、この Agent の ID で実行され、使用量もこの Agent に帰属します。無効にすると、再度有効にするか変更するまで、モデル呼び出しとローカル URL 取得を停止します。リンク先の Agent ページでモデル profile を編集します。

- `brain.maintainer_agent_uid` — 選択した Agent の light profile で知識を抽出し、heavy profile で Dreaming を実行し、web_fetch profile で URL Source を取得します。web_fetch が未設定の場合はローカルの ankole-browser を使います。
- `brain.embedding_model` — ベクトル検索を有効にします。Provider とモデルを選び、embedding の次元数を入力します。
- `brain.rerank_model` — 融合した検索結果を rerank します。空の場合は融合後の順序を保ちます。

- [Brain ガイド](https://ankole.agentbull.com/ja-JP/docs/brain/index.md)
- [AppConfigure リファレンス](https://ankole.agentbull.com/ja-JP/docs/app-configuration/index.md)

<a id="chat-channels"></a>

## 4. チャットチャンネルを接続して signal routing ルールを作成する

Console でチャットプラットフォームの Control Plane Plugin を有効にし、そのプラットフォーム上で bot またはアプリケーションを作成してください。両方が同じプラットフォームを使用する場合でも、IdP とチャットの役割には別々のアプリを使用してください。この分離により、サインインとディレクトリの権限が bot の権限から離れます。また、credential のローテーションとアプリのリリースも分離されます。

通常、1 つのチャットアプリは 1 つの bot identity を表します。複数の Agent が異なる bot 名、アバター、または権限を必要とする場合は、そのプラットフォームで複数のアプリを作成してください。アプリを準備したら、Console でその routing ルールを作成し、意図する Agent に接続してください。

Slack、Teams、Lark/Feishu、DingTalk、WeCom はエンタープライズ向けプラットフォームです。そのユーザーは IdP が同期したディレクトリに由来します。Telegram、Discord、LINE、WhatsApp はコンシューマー向け IM です。そのユーザーには従業員レコードがないため、Agent が応答する前に、管理者が **アイデンティティ → 保留中のマッピング** で新しい送信者ごとにアカウントへマッピングします。WhatsApp では、既知のアカウントがすでにその電話番号を所有している場合、送信者は自動的にマッピングされます。Email は専用のメールボックスを接続し、送信者は明示的なメールの identity 紐付けによってのみ既知になります。

**channel provider を選択**

- Slack · デフォルト
- Microsoft Teams
- Lark / Feishu
- DingTalk
- WeCom
- Telegram
- Discord
- LINE
- WhatsApp
- Email

### Slack · デフォルト

Slack は Socket Mode を使用します。Ankole はアウトバウンドの WebSocket を開くため、チャットの経路に公開の Slack webhook は不要です。

**始める前に**

- Slack app を作成してインストールする権限
- テスト用のチャンネルまたはダイレクトメッセージ

#### 基本設定 · Slack app を準備する

##### 1. アプリを作成して Socket Mode を有効にする

Slack app をゼロから作成してください。Basic Information で App-Level Token を作成し、下記の scope を追加してから Socket Mode を有効にしてください。

- `connections:write` — App Token が Socket Mode 接続を開けるようにします

##### 2. チャットとチャンネル状態のイベントを購読する

Event Subscriptions → Subscribe to bot events を開いてください。下記の各イベントを追加してください。このセットは、Slack アダプタが実装するメッセージ、リアクション、チャンネル状態の機能に一致します。

- `app_mention` — チャンネルの @ メンションを受信します
- `message.channels` — パブリックチャンネルのメッセージを受信します
- `message.groups` — プライベートチャンネルのメッセージを受信します
- `message.im` — ダイレクトメッセージを受信します
- `message.mpim` — 複数人ダイレクトメッセージを受信します
- `reaction_added` — 追加されたリアクションを受信します
- `reaction_removed` — 削除されたリアクションを受信します
- `member_joined_channel` — チャンネルに参加したメンバーを同期します
- `member_left_channel` — チャンネルを離れたメンバーを同期します
- `channel_rename` — チャンネルの名称変更を同期します
- `group_rename` — プライベートチャンネルの名称変更を同期します
- `channel_deleted` — チャンネルの削除を同期します
- `channel_archive` — チャンネルのアーカイブを同期します

##### 3. ダイレクトメッセージを有効にする

App Home → Show Tabs を開いてください。Display Messages tab をオンにし、Allow users to send Slash commands and messages from the messages tab を選択してください。Messages タブだけでは表示領域が現れるだけで、ユーザーは Agent にダイレクトメッセージを送れません。

##### 4. Slack ネイティブの対話性を有効にする

Interactivity & Shortcuts を開き、Interactivity を有効にしてください。Socket Mode は既存の WebSocket 経由で Block Kit のボタンアクションを配信するため、公開の Request URL は不要です。

##### 5. 完全なチャット scope を付与してアプリをインストールする

OAuth & Permissions → Bot Token Scopes で、下記の各 scope を追加してください。このセットは Ankole が呼び出す Slack API のみをカバーします。未使用の assistant、workflow、document、meeting の scope は付与しないでください。

- `app_mentions:read` — bot に言及したメッセージを読み取ります
- `channels:read` — パブリックチャンネルとそのメンバーを同期します
- `channels:history` — パブリックチャンネルのメッセージを読み取り、返信を調整します
- `groups:read` — プライベートチャンネルとそのメンバーを同期します
- `groups:history` — プライベートチャンネルのメッセージを読み取り、返信を調整します
- `im:read` — ダイレクトメッセージの会話を同期します
- `im:history` — ダイレクトメッセージを読み取り、返信を調整します
- `mpim:read` — 複数人ダイレクトメッセージとそのメンバーを同期します
- `mpim:history` — 複数人ダイレクトメッセージを読み取り、返信を調整します
- `chat:write` — bot メッセージを送信、更新、削除します
- `reactions:read` — リアクションの変更を受信します
- `reactions:write` — リアクションを追加および削除します
- `files:read` — メッセージに添付されたファイルを読み取ります
- `files:write` — Agent が送信するファイルをアップロードします
- `users:read` — チャンネルメンバーを特定し、bot アカウントを除外します

> scope を変更した後は、アプリをワークスペースに再インストールし、新しい Bot Token を Ankole に書き込んでください。

##### 6. Console のフィールドを収集する

- `botToken`: `xoxb-…` — Bot User OAuth Token。xoxb- プレフィックスが必要です。
- `appToken`: `xapp-…` — Socket Mode 用の App-Level Token。xapp- プレフィックスが必要です。

#### 詳細設定 · メッセージポリシー、主体マッピング、Slack を IdP として使用

Slack はイベントを配信しますが、アドレス指定されていないメッセージを Ankole がどう処理するかは、やはり signal routing ルールが決定します。

##### 1. Agent に言及しないメッセージのポリシーを選択する

上記のイベントと scope により、Slack は完全な会話を配信できますが、Ankole の signal routing ポリシーを置き換えるわけではありません。最初は addressed_only から始めてください。Agent が直接の言及なしで観察または介入する必要がある場合のみ、observe_all または may_intervene を選択してください。

##### 2. 1 つのアプリが Slack IdP も兼ねる場合に identity の権限を追加する

本番では別の IdP アプリを使用してください。1 つのアプリが両方の役割を担う必要がある場合のみ、下記の Bot scope とディレクトリイベントを追加してください。

- `users:read.email` — メンバーのメールアドレスを同期します
- `usergroups:read` — ユーザーグループとそのメンバーを同期します
- `team_join` — メンバー参加イベントを受信します
- `user_change` — メンバープロファイルの変更を受信します
- `subteam_created` — ユーザーグループの作成を受信します
- `subteam_updated` — ユーザーグループの更新を受信します
- `subteam_members_changed` — ユーザーグループのメンバーシップ変更を受信します

##### 3. 主体の namespace を設定する

- `platformSubjectNamespace`: `slack-main` — Slack ワークスペースごとに 1 つの namespace を使用してください。Slack が両方の役割を担う場合は、Slack IdP 設定と共有してください。
- `userName`: `Slack` — アウトバウンドメッセージに使用する表示名。

##### 4. 別の Slack IdP アプリを作成する

通常の運用では、SSO とディレクトリ同期用に別の Slack app を作成してください。identity の権限は IdP アプリに、bot の権限はチャットアプリに置いてください。両方のレコードで、同じワークスペースのために 1 つの platformSubjectNamespace を使用できます。

### Microsoft Teams

Teams は Bot Framework の webhook を送信します。信頼された証明書を持つ公開の HTTPS エンドポイントが必須です。

**始める前に**

- Entra ID テナント
- 公開 HTTPS の Ankole ホスト
- Teams bot を登録してインストールする権限

#### 基本設定 · Teams bot を準備する

##### 1. アプリと bot を登録する

Entra のアプリ登録と Azure Bot リソースを作成してください。アプリケーションの client ID が appID になります。appPassword 用の client secret を作成してください。

##### 2. Bot Framework のメッセージングエンドポイントを設定する

appID のパスセグメントは、signal routing ルールの App ID と一致する必要があります。

```text
https://<ANKOLE_HOST>/webhooks/v1/teams/<appID>/messages
```

##### 3. テナントモードを選択する

- `botTenancy`: `single_tenant` — 1 つのエンタープライズテナント向けの推奨開始モード。
- `tenantID` — Entra テナントの GUID。シングルテナントの bot に必要です。

##### 4. Console のフィールドを収集する

- `appID` — Azure Bot 登録の Microsoft App ID。GUID である必要があります。
- `appPassword` — Microsoft App の client secret。

#### 詳細設定 · クロステナント bot、Entra identity、ディレクトリ webhook

bot が複数の Entra テナントにサービスを提供する場合、または Entra ID が SSO も供給する場合に拡張します。

##### 1. 1 つの Bot Framework アプリで複数の Entra テナントにサービスを提供する

Azure Bot の登録が複数の Entra テナントを許可する場合のみ、botTenancy を multi_tenant に設定してください。アダプタは bot の token テナントに botframework.com を使用します。この Microsoft のアプリ登録モードは、Ankole デプロイメントインスタンスの境界を変更しません。

##### 2. Entra が identity も供給する場合に主体の namespace を共有する

- `platformSubjectNamespace`: `entra-id-main` — Teams チャンネルと Entra ID provider が同じ組織を表す場合は、同じ namespace を使用してください。
- `userName`: `Teams` — アウトバウンドメッセージに使用する表示名。

##### 3. Graph のディレクトリ同期を IdP に保持する

Entra のフル同期とリアルタイムのディレクトリ同期は IdP レコードに属します。Graph 通知は別のディレクトリ webhook を使用し、公開の HTTPS ホストが依然として必要です。

### Lark / Feishu

Lark と Feishu はアウトバウンドの長い接続を使用します。チャットの経路にはインターネットアクセスが必要ですが、公開のインバウンド webhook は不要です。

**始める前に**

- エンタープライズのカスタムアプリを作成する権限
- アプリの利用範囲内のテストユーザー

#### 基本設定 · Lark または Feishu アプリを準備する

##### 1. アプリを作成して bot 機能を有効にする

エンタープライズのカスタムアプリを作成し、bot 機能を有効にし、テストユーザーを利用範囲に追加してください。

##### 2. 完全なチャット scope をインポートする

Permissions を開き、一括インポートまたはエクスポートのアクションを選択し、下記の JSON を貼り付けて、インポートを確認してください。このセットは、アダプタが呼び出す bot、メッセージ、リアクション、ファイル、カード、ルーム、メンバーシップの API に一致します。ディレクトリ書き込み、ドキュメント、ミーティング、緊急メッセージの権限をチャットアプリに追加しないでください。

**JSON を一括インポート**

```text
{
  "scopes": {
    "tenant": [
      "application:bot.basic_info:read",
      "cardkit:card:write",
      "im:chat:read",
      "im:chat.members:bot_access",
      "im:chat.members:read",
      "im:message:send_as_bot",
      "im:message:readonly",
      "im:message:update",
      "im:message:recall",
      "im:message.group_at_msg:readonly",
      "im:message.p2p_msg:readonly",
      "im:message.reactions:read",
      "im:message.reactions:write_only",
      "im:resource"
    ],
    "user": []
  }
}
```

##### 3. 長い接続を選択して実装済みのイベントを追加する

Events and Callbacks で、long connection を選択し、下記の各イベントを追加してください。プラットフォームがクライアントを検出する間、Ankole の control plane を起動したままにしてください。

- `im.message.receive_v1` — bot に送信されたメッセージを受信します
- `im.message.recalled_v1` — メッセージの撤回イベントを受信します
- `im.message.reaction.created_v1` — 追加されたリアクションを受信します
- `im.message.reaction.deleted_v1` — 削除されたリアクションを受信します
- `im.chat.member.bot.added_v1` — bot が追加されたルームを同期します
- `im.chat.member.bot.deleted_v1` — bot が削除されたルームを同期します
- `im.chat.member.user.added_v1` — ルームに参加したメンバーを同期します
- `im.chat.member.user.deleted_v1` — ルームを離れたメンバーを同期します
- `im.chat.updated_v1` — ルームの変更を同期します
- `im.chat.disbanded_v1` — ルームの削除を同期します
- `card.action.trigger` — インタラクティブカードのアクションを受信します

##### 4. バージョンを公開して Console のフィールドを収集する

- `appID` — エンタープライズのカスタムアプリ ID。
- `appSecret` — エンタープライズのカスタムアプリの secret。
- `domain`: `feishu or lark` — Feishu.cn には feishu、Larksuite.com には lark を使用してください。

#### 詳細設定 · フルルームの context、別の identity、主体マッピング

Agent がルームを観察する必要がある場合、または Lark が SSO も供給する場合に拡張します。

##### 1. Agent にアドレス指定されていないグループメッセージを観察させる

observe_all または may_intervene を使用する前に、下記の権限を追加してください。最初の会話を確認している間は addressed_only から始めてください。

- `im:message.group_msg` — bot に言及しないグループメッセージを読み取ります

##### 2. 別の Lark IdP アプリを作成する

通常の運用では、SSO とディレクトリ同期用に別のカスタムアプリを作成してください。サインインとディレクトリの権限は IdP アプリに、bot の権限はチャットアプリに置いてください。両方のレコードで、同じ組織のために 1 つの platformSubjectNamespace を使用できます。

##### 3. 共有のアダプタフィールドを設定する

- `platformSubjectNamespace`: `lark-main` — 両方のレコードが同じ組織を表す場合は、この値を Lark IdP 設定と共有してください。
- `userName`: `Lark / Feishu` — アウトバウンドメッセージに使用する表示名。

##### 4. 有効な binding ごとに 1 つの Lark アプリを使う

binding ごとに別の Lark または Feishu アプリを作成してください。無効な binding はそのアプリを解放します。

- 1 つの Agent で複数の Lark binding を有効にできます。
- 有効な binding ごとに異なる domain と appID の組み合わせが必要です。

### DingTalk

DingTalk は Stream モードを使用します。1 組の AppKey と AppSecret が robot を認証し、イベント接続を開きます。

> **DingTalk は Ankole の一部の機能を制限します**
>
> グループチャットでは、Agent は完全な会話履歴を読み取れません。明示的に @ メンションされたメッセージのみを受信します。DingTalk のカードはテンプレートでホストされるため、ストリーミングのカード返信にはカードプラットフォーム上で構築する AI カードテンプレートが 1 つ必要です。それがなければ、返信はプレーンな Markdown のままです。
>
> これらの制限は Ankole の機能とユーザーエクスペリエンスを低下させます。また、長期 memory システムに不完全な context を残します。可能であれば、別のチャットチャンネルを優先してください。

**始める前に**

- エンタープライズ内部の DingTalk アプリと robot を作成する権限
- テスト用の会話

#### 基本設定 · DingTalk robot を準備する

##### 1. エンタープライズ内部のアプリと robot を作成する

robot 機能を有効にし、アプリをテストユーザーが利用できるようにしてください。DingTalk は、ダイレクトメッセージと robot に @ するグループメッセージを配信します。

##### 2. Stream モードを有効にしてアプリを公開する

同じアプリケーションの credential が Stream 接続を開くため、公開のメッセージ webhook は不要です。

##### 3. Console のフィールドを収集する

- `clientId` — エンタープライズアプリの Client ID。AppKey とも呼ばれ、Stream の clientId として使用されます。
- `clientSecret` — エンタープライズアプリの Client Secret。AppSecret とも呼ばれ、Stream の clientSecret として使用されます。
- `group_message_mode`: `addressed_only` — DingTalk がグループメッセージで配信できる唯一のモード。
- `cardTemplateId` — ストリーミングのカード返信用の AI カードテンプレート ID。最初のテストでは空のままにしてください。テンプレートの構築方法は、下記の詳細セクションで説明します。

#### 詳細設定 · AI カードテンプレート、複数の Agent、identity 設定

ストリーミングの AI カード返信が必要な場合、複数の DingTalk Agent を計画している場合、または DingTalk を identity ソースとしても使用する場合に拡張します。

##### 1. AI カードテンプレートを作成して変数を追加する

DingTalk のカードはテンプレートでホストされます。レイアウトは DingTalk カードプラットフォーム上にあり、Ankole は固定された一連の変数に値を書き込むだけです。DingTalk 組織ごとに 1 つテンプレートを構築してください。最初の 1 つには約 20 分を想定してください。始める前に、Agent がプレーンテキストで返信できる状態であり、アプリがインタラクティブカードインスタンスの書き込みと AI カードのストリーミング更新の権限を持つ必要があります。

DingTalk 開発者コンソール → Card Platform → New template を開き、AI カードのカテゴリを選択してください。このカテゴリだけが AI カードコンテナを持ちます。これは入力中インジケータと完了・失敗の状態を描画します。下記の各変数を、まさにこの名前で追加してください。名前が一致しないと、その領域はすべての返信で空のままになります。

- `state` — テキスト。実行中の tool のラベルなどの 1 行のステータス。
- `answer` — Markdown（ストリーミング）。返信本文。各フレームで完全に書き換えられます。
- `thought` — Markdown。一時的な思考の下書き。返信が終わると消えます。
- `plan` — テキスト。計画と、その完了数／総数。
- `activity` — テキスト。実行中の tool 呼び出し。返信が終わると消えます。
- `results` — テキスト。構造化された結果ごとに 1 行。
- `receipts` — テキスト。記録された side effect ごとに 1 行。
- `actions` — テキスト。ボタンの JSON リスト。Agent が何も尋ねないときは空。
- `meta` — テキスト。トリガー、カード番号、カウント、経過時間。

##### 2. 各カード状態にコンポーネントを配置する

AI カードコンポーネントで入力中、完了、失敗のレイアウトを設定してください。返信を表示する各レイアウトに answer にバインドした Markdown コンポーネントを置き、入力中レイアウトではストリーミングを有効にしてください。meta と state は上部に、plan はテキストに、thought と activity は折りたたみ領域に、results と receipts はテキストに配置できます。決定ボタンを表示し続ける場合は、入力中と完了の両方のレイアウトに actions にバインドしたアクション領域を置き、各ボタンの値をそのまま渡してください。

DingTalk はネイティブの AI カードライフサイクルからレイアウトを選択します。Ankole は isFinalize で完了状態へ、isError で失敗状態へ移します。flowStatus や flowStatusVar を作成またはバインドしないでください。

> 現在の状態レイアウトに answer にバインドした Markdown コンポーネントがないと、カードは空白になります。レイアウトを変更するたびにテンプレートを再公開してください。

##### 3. テンプレートを公開し、ID を入力して確認する

テンプレートを robot が所有するエンタープライズ内部のアプリに関連付け、公開し、テンプレート ID をコピーして、ルーティングルールの cardTemplateId に貼り付けてください。この変更は次の返信に適用され、再起動するものはありません。

確認するには、複数の文を生成するメッセージを送信してください。Agent が書いている間にカードが表示されて成長し、返信が終わるとインジケータが止まり、思考とアクティビティの領域が消えるはずです。その後、意思決定が必要なことを尋ねてください。ボタンが表示され、押すと Turn が続行されます。もはや保留中の質問に答えられない古いボタンは無視されます。長い返信は約 2.5 KB でカードを封じ、新しいカードで続きます。各カードは会話の中の新しいメッセージであり、テーブルなどのリッチな構造はテキストとして描画されます。これらはすべてプラットフォームの制限下で期待される動作です。

- カードが空白： 現在の入力中、完了、または失敗レイアウトが answer にバインドされていないか、変更したテンプレートが公開されていません。
- ある領域が常に空： その変数名が表と一致していないか、コンポーネントがバインドされていません。
- answer が最後にだけ表示されるか、まったく表示されない： answer ブロックが Markdown のストリーミングブロックではありません。
- 返信終了後も入力中インジケータが残る： control plane のログを確認し、DingTalk が isFinalize または isError を含むストリーミング更新を受け入れたことを確認してください。
- 返信がプレーンな Markdown メッセージのまま： テンプレート ID が空か、テンプレートがこのアプリに公開されていないか、DingTalk がカードコンテンツを拒否しています。param.contentUnsafe または param.cardNotExist を control plane のログで確認してください。カードの経路が恒久的に失敗すると、返信は 1 回だけプレーンな Markdown に劣化しますが、それでも配信されます。
- ボタンは表示されるが押しても何も起きない： アクション領域が各ボタンの値をそのまま渡していません。

##### 4. 接続の所有権ルールを尊重する

追加の Agent ごとに、別の robot と credential のペアを作成してください。

- 1 つの Agent は、有効な DingTalk binding を最大 1 つ持てます。
- 1 つの clientId は 1 つの Agent にのみバインドできます。

##### 5. DingTalk の identity を分離したままにする

DingTalk は OIDC とディレクトリ同期も供給できますが、それは IdP レコードです。チャットの binding は DingTalk を Console のログイン provider にするわけではありません。

- `platformSubjectNamespace`: `dingtalk-main` — 両方のレコードが同じ組織を表す場合のみ、DingTalk IdP と共有してください。

### WeCom

WeCom の AI bot は 1 つのアウトバウンドの長い接続でメッセージを送受信するため、公開のメッセージ webhook は不要です。プラットフォームは bot ごとに正確に 1 つの長い接続を許可します。

> **WeCom は最も制限が多いチャットチャンネルです**
>
> グループでは、Agent は明示的に bot に @ するメッセージのみを受信します。画像、音声、ファイル、ビデオはダイレクトメッセージでのみ届き、音声メッセージはプラットフォームの文字起こしとしてのみ届きます。送信済みのメッセージは、撤回、編集、絵文字リアクションができません。Agent は新しい会話を開始できません。ユーザーが先に bot にメッセージを送る必要があり、インバウンドメッセージ後の返信ウィンドウは 24 時間です。ストリーミングの返信はユーザーへの返信時のみ機能し、1 つのストリーミングメッセージは 10 分以内に終了する必要があるため長い回答は分割され、送信は会話ごとに 1 分あたり約 30 メッセージに制限されます。カードボタンはクリック後 5 秒以内にのみ変更できます。リアルタイムのディレクトリ同期はありません。
>
> すべての制限はプラットフォーム自体に由来し、Ankole は回避できません。長期 memory システムも、Agent が受信するメッセージ断片からのみ context を構築します。可能であれば Lark/Feishu、Slack、Teams、または DingTalk を優先してください。

**始める前に**

- AI bot を作成できる WeCom 企業のスーパー管理者
- テスト用の会話

#### 基本設定 · WeCom bot を準備する

##### 1. 企業のスーパー管理者として AI bot を作成する

WeCom 管理コンソールを開き、API モードで AI bot を作成し、その隣に表示される Bot ID と Secret を記録してください。

> bot は企業のスーパー管理者が作成する必要があります。そうしないと、メッセージ内の user ID が暗号化され、ディレクトリやサインインの identity に決して参加できません。

##### 2. bot を他のプログラムと共有しない

プラットフォームは bot ごとに正確に 1 つの長い接続を許可します。別のプログラムが同じ Bot ID で接続すると、各接続がもう一方を切断します。Ankole が切断された場合、Ankole は回線を奪い合わずに待機します。

##### 3. Console のフィールドを収集する

- `botId` — AI bot の Bot ID。
- `secret` — Bot ID の隣に表示される長い接続の secret。
- `group_message_mode`: `addressed_only` — WeCom がグループメッセージで配信できる唯一のモード。

#### 詳細設定 · プロアクティブ配信、identity マッピング、複数の Agent

Agent が先に話す前に、ユーザーがその会話で 1 回は bot にメッセージを送る必要があります。

##### 1. プロアクティブ配信を有効にする

スケジュールされた Job の結果などのプロアクティブメッセージは、ユーザーがアクティブにした会話にのみ到達します。各ユーザーに先に bot へメッセージを 1 つ送らせてください。Agent は新しい会話を開始できません。プロアクティブ送信では、ストリーミングなしで 1 つの完全な Markdown メッセージを配信します。

##### 2. identity マッピングのフィールドを設定する

- `platformSubjectNamespace`: `wecom-main` — 両方のレコードが同じ企業を表す場合のみ、WeCom IdP と共有してください。
- `userName`: `企业微信 / WeCom` — アウトバウンドの bot メッセージに表示される名前。

##### 3. Agent ごとに別の bot を使用する

追加の Agent ごとに、別の AI bot を作成してください。

- 1 つの Agent は、有効な WeCom binding を最大 1 つ持てます。
- 1 つの Bot ID は 1 つの Agent にのみバインドできます。

### Telegram

Telegram は Bot API のロングポーリングを使用します。Ankole はアウトバウンド接続で getUpdates を呼び出すため、チャット経路に公開 webhook は不要です。Telegram はコンシューマー向け IM です。そのユーザーはディレクトリの従業員ではないため、最初のメッセージの前に identity マッピングを計画してください。

**始める前に**

- @BotFather と会話できる Telegram アカウント
- テスト用のプライベートチャットまたはグループ

#### 基本設定 · Telegram bot を準備する

##### 1. @BotFather で bot を作成する

@BotFather に /newbot を送信し、表示名と bot で終わるユーザー名を選び、BotFather が返す token をコピーしてください。この token は routing ルールに必要な唯一の credential です。

##### 2. bot にグループメッセージを読ませる

@BotFather で Bot Settings → Group Privacy を開き、プライバシーモードをオフにしてください。プライバシーモードがオンの場合、グループは /command@bot 形式のコマンドと bot への返信だけを配信するため、@ メンションが Agent に届かず、observe_all や may_intervene は他のメッセージを一切見られません。この設定の変更は、bot をグループから削除して再度追加した後に有効になります。

##### 3. 古い webhook を削除する

Ankole は Bot API をポーリングしますが、その token に webhook が設定されている間、Telegram はポーリングを拒否します。別のプログラムがこの token を webhook で使用していた場合は、ルールを有効にする前に削除してください。Ankole は webhook_configured を報告し、他のシステムが所有する webhook を削除しません。

```bash
curl -s "https://api.telegram.org/bot<botToken>/deleteWebhook"
```

##### 4. Console のフィールドを収集する

- `botToken`: `123456789:AA…` — @BotFather から取得した bot token。1 つの token は有効な routing ルール 1 つにのみ属せます。
- `group_message_mode`: `addressed_only` — ここから始めてください。ダイレクトメッセージ、@ メンション、/command@bot、または bot への返信が Agent 宛になります。

#### 詳細設定 · identity マッピング、フォーラムトピック、プラットフォームの制限

展開すると、Telegram ユーザーをアカウントにマッピングする方法と、Agent が使えない Telegram の機能を確認できます。

##### 1. Telegram ユーザーをアカウントにマッピングする

Telegram ユーザーには従業員レコードがないため、新しい送信者ごとにアカウントの自動マッピングは失敗します。アカウントの自動マッピングに失敗した場合 を 手動レビュー のままにしてください。送信者は固定の通知を 1 回受け取り、アイデンティティ → 保留中のマッピング に表示され、管理者が Telegram の identity を既存のアカウント（たとえばローカルパスワードのアカウント）に紐付けます。その後、ユーザーはメッセージを再送信します。独立アカウントを自動作成 は、誰でも Agent と話せるオープンな bot の場合にだけ選択してください。

##### 2. 会話がセッションにどう対応するかを知る

- プライベートチャット、グループ、スーパーグループは、それぞれ 1 つの Agent セッションを形成します。
- スーパーグループ内の各フォーラムトピックは、別のセッションです。
- チャンネル投稿、他の bot からのメッセージ、匿名またはゲストの送信者は無視されます。

##### 3. プラットフォームの制限を守る

- Bot API は 20 MB を超えるファイルをダウンロードできません。Agent はファイル名とサイズを見られますが、内容は読めません。
- ユーザーがメッセージを削除しても Telegram はイベントを送信しないため、削除されたテキストはセッションの context に残ります。
- 接続が失われた送信を Telegram が受け付けた可能性がある場合、Ankole は送信を自動的に繰り返しません。2 つ目の返信を投稿する代わりに、重複の可能性のフローを適用します。

##### 4. Agent ごとに別の bot を使用する

1 つの bot token は有効な routing ルール 1 つにのみバインドできます。追加の Agent ごとに @BotFather で別の bot を作成してください。

### Discord

Discord はアウトバウンドの WebSocket 経由で bot Gateway を使用するため、チャット経路に公開 webhook は不要です。Discord はコンシューマー向け IM です。そのユーザーはディレクトリの従業員ではないため、最初のメッセージの前に identity マッピングを計画してください。

**始める前に**

- Developer Portal でアプリケーションを作成できる Discord アカウント
- bot を招待できるサーバー、またはテスト用のダイレクトメッセージ

#### 基本設定 · Discord bot を準備する

##### 1. アプリケーションとその bot を作成する

Discord Developer Portal を開き、New Application を作成し、Bot ページを開いて Reset Token を選択してください。token はすぐにコピーしてください。Discord はそれを 1 回しか表示しません。

##### 2. メッセージ内容の intent を有効にする

Bot ページの Privileged Gateway Intents で Message Content Intent をオンにしてください。これがないと、Discord は bot にメンションしないサーバーメッセージを空の内容で配信するため、Agent はダイレクトメッセージと自分にメンションするメッセージだけを読み、observe_all や may_intervene は会話を見られません。Ankole は接続前にアプリケーションのフラグを読み取り、アプリケーションがこの intent を持つ場合にだけ要求します。

> Server Members Intent と Presence Intent は不要です。100 を超えるサーバーに参加しているアプリケーションは、メッセージ内容の intent を維持するために Discord の認証が必要です。

##### 3. bot をサーバーに招待する

OAuth2 → URL Generator を開き、bot scope を選択し、以下の権限を追加してください。生成された URL を開いてサーバーを選択します。このセットは、Ankole が呼び出す Discord API だけをカバーします。

- `View Channels` — bot が許可されたチャンネルを見る
- `Send Messages` — Agent の返信を投稿する
- `Send Messages in Threads` — スレッド内で返信する
- `Read Message History` — 以前のメッセージに返信し、編集する
- `Attach Files` — Agent が送信するファイルをアップロードする
- `Add Reactions` — リアクションを追加および削除する

##### 4. Interactions Endpoint URL を空のままにする

General Information ページで、Interactions Endpoint URL を空のままにしてください。設定されていると、Discord はボタンのクリックを Gateway ではなくその URL に投稿するため、Agent の返信にあるボタンが Ankole に届きません。

##### 5. Console のフィールドを収集する

- `botToken` — Bot ページから取得した bot token。1 つの token は有効な routing ルール 1 つにのみ属せます。
- `group_message_mode`: `addressed_only` — ここから始めてください。ダイレクトメッセージ、@ メンション、または bot への返信が Agent 宛になります。

#### 詳細設定 · identity マッピング、スレッド、プラットフォームの制限

展開すると、Discord ユーザーをアカウントにマッピングする方法と、Agent が使えない Discord の機能を確認できます。

##### 1. Discord ユーザーをアカウントにマッピングする

Discord ユーザーには従業員レコードがないため、新しい送信者ごとにアカウントの自動マッピングは失敗します。アカウントの自動マッピングに失敗した場合 を 手動レビュー のままにしてください。送信者は固定の通知を 1 回受け取り、アイデンティティ → 保留中のマッピング に表示され、管理者が Discord の identity を既存のアカウント（たとえばローカルパスワードのアカウント）に紐付けます。その後、ユーザーはメッセージを再送信します。独立アカウントを自動作成 は、誰でも Agent と話せるオープンなサーバーの場合にだけ選択してください。

##### 2. 会話がセッションにどう対応するかを知る

- ダイレクトメッセージと各サーバーチャンネルは、それぞれ 1 つの Agent セッションを形成します。
- 各スレッドは別のセッションです。
- 他の bot からのメッセージ、webhook の投稿、システム通知、テキストも添付ファイルもないメッセージは無視されます。
- Agent のテキストがユーザー、ロール、または everyone に通知することはありません。Ankole は送信するすべてのメッセージでメンションの解析を無効にします。

##### 3. プラットフォームの制限を守る

- Ankole がダウンロードする添付ファイルは最大 25 MB です。それより大きいファイルは、Agent が名前とサイズを見られますが、内容は読めません。
- ユーザーがメッセージを削除しても、Discord は Ankole が使用するイベントを送信しないため、削除されたテキストはセッションの context に残ります。
- 返信は 2,000 文字で分割されます。1 つのカードに表示できるボタンは最大 25 個です。
- 接続が失われた送信を Discord が受け付けた可能性がある場合、Ankole は送信を自動的に繰り返しません。2 つ目の返信を投稿する代わりに、重複の可能性のフローを適用します。

##### 4. Agent ごとに別の bot を使用する

1 つの bot token は有効な routing ルール 1 つにのみバインドできます。追加の Agent ごとに別のアプリケーションを作成してください。

### LINE

LINE は Messaging API の webhook を Ankole に投稿します。信頼された証明書を持つ公開 HTTPS エンドポイントが必須です。LINE はコンシューマー向け IM です。そのユーザーはディレクトリの従業員ではないため、最初のメッセージの前に identity マッピングを計画してください。

> **LINE は Ankole の一部の機能を制限します**
>
> LINE の reply token は webhook の 1 分後に期限切れになり、Agent の Turn は通常それより長いため、Agent のすべての返信はプッシュメッセージです。プッシュメッセージは Official Account の月間メッセージプランに計上されるため、プランは想定されるトラフィックをカバーする必要があります。LINE bot はメッセージの編集、送信取消、リアクションができず、ファイルを送信できず、最終回答の前にリアルタイムの進行状況を表示しません。
>
> すべての制限はプラットフォーム自体に由来し、Ankole は回避できません。

**始める前に**

- LINE Developers の provider と、Messaging API channel を作成する権限
- 公開 HTTPS の Ankole ホスト
- テスト用の LINE アカウント

#### 基本設定 · LINE Official Account を準備する

##### 1. Messaging API channel を作成し、その credential を収集する

LINE Developers Console で、自分の provider の下に Messaging API channel を作成してください。Basic settings から Channel ID と Channel secret をコピーし、Messaging API タブで長期の channel access token を発行してください。

##### 2. webhook を検証する前に routing ルールを作成する

まず Console で routing ルールを保存して有効にしてください。Ankole は不明な Channel ID への webhook にステータス 404 で応答するため、ルールが存在するまで LINE Developers Console の Verify ボタンは失敗します。

##### 3. webhook URL を設定して検証する

Messaging API タブでこの URL を入力し、Use webhook をオンにして Verify を選択してください。パスの channelId セグメントは、routing ルールの Channel ID と一致する必要があります。Ankole はすべてのリクエストの x-line-signature を channel secret で検査し、誤った署名をステータス 401 で拒否します。

```text
https://<ANKOLE_HOST>/webhooks/v1/line/<channelId>/events
```

##### 4. bot だけが応答するようにする

LINE Official Account Manager で Response settings を開いてください。応答方法を bot に設定し、自動応答とあいさつメッセージをオフにして、アカウントが Agent と並んで応答しないようにします。グループチャットの場合は、LINE Developers Console で Allow bot to join group chats を有効にしてください。

##### 5. Console のフィールドを収集する

- `channelId` — Messaging API の Channel ID。1 つの channel は有効な routing ルール 1 つにのみ属せます。
- `channelSecret` — Basic settings の Channel secret。Ankole は webhook の署名検証に使用します。
- `channelAccessToken` — Messaging API タブで発行した長期の channel access token。
- `group_message_mode`: `addressed_only` — ここから始めてください。LINE はすべてのグループメッセージを配信するため、observe_all と may_intervene も追加の権限なしで機能します。

#### 詳細設定 · identity マッピング、グループでの返信、プラットフォームの制限

展開すると、LINE ユーザーをアカウントにマッピングする方法と、グループでの Agent の動作を確認できます。

##### 1. LINE ユーザーをアカウントにマッピングする

LINE ユーザーには従業員レコードがないため、新しい送信者ごとにアカウントの自動マッピングは失敗します。アカウントの自動マッピングに失敗した場合 を 手動レビュー のままにしてください。送信者は固定の通知を 1 回受け取り、LINE の表示名とともに アイデンティティ → 保留中のマッピング に表示され、管理者が LINE の identity を既存のアカウント（たとえばローカルパスワードのアカウント）に紐付けます。その後、ユーザーはメッセージを再送信します。LINE のユーザー ID は channel を所有する LINE Developers の provider に属するため、異なる provider の下にある channel には別々のマッピングが必要です。

##### 2. グループでの Agent の動作を知る

- 1 対 1 のチャット、グループ、複数人チャットは、それぞれ 1 つの Agent セッションを形成します。LINE にはスレッドがありません。
- グループでは、bot への @ メンション、または bot のメッセージの引用が Agent 宛になります。グループでの返信は質問者を引用します。
- ユーザーが送信取消したメッセージは、セッションの context から削除されます。

##### 3. プラットフォームの制限を守る

- 返信は 5,000 文字で分割され、1 つのリクエストで送信できるメッセージは最大 5 件です。確認の質問に表示できるボタンは最大 4 個です。
- Ankole がダウンロードする受信ファイルは最大 25 MB です。それより大きいファイルは、Agent が名前とサイズを見られますが、内容は読めません。
- Agent はファイルを送信できません。テキストの返信は引き続き配信されます。
- 月間プランを使い切ると、LINE はステータス 429 で応答します。プランの変更または翌月になるまで解消されません。

##### 4. Agent ごとに別の channel を使用する

1 つの Messaging API channel は有効な routing ルール 1 つにのみ属せます。追加の Agent ごとに別の channel を作成してください。

### WhatsApp

WhatsApp は Cloud API の webhook を Ankole に投稿します。信頼された証明書を持つ公開 HTTPS エンドポイントが必須です。WhatsApp はコンシューマー向け IM ですが、電話番号がすでに既知の人物に属している送信者は、管理者の操作なしにマッピングされます。

> **WhatsApp は Ankole の一部の機能を制限します**
>
> Meta は、ユーザーの最新のメッセージまたはボタン応答から 24 時間後にカスタマーサービスウィンドウを閉じます。その後の返信（たとえばスケジュールされたレポート）は明確な失敗で停止し、ユーザーには届きません。ユーザーが再度メッセージを送った後、オペレーターは Signal Routing ページから再試行できます。グループチャット、テンプレートメッセージ、メッセージの編集、メッセージの削除、リアルタイムの進行状況表示は利用できません。
>
> すべての制限はプラットフォーム自体に由来し、Ankole は回避できません。

**始める前に**

- WhatsApp product を追加した Meta App と、電話番号を所有する WhatsApp Business Account
- 公開 HTTPS の Ankole ホスト
- テスト用の WhatsApp アカウント

#### 基本設定 · WhatsApp Business の電話番号を準備する

##### 1. WhatsApp product を接続し、識別子を収集する

Meta App Dashboard で、App に WhatsApp product を追加し、電話番号を所有する WhatsApp Business Account を接続してください。App settings → Basic から App ID と App secret を、WhatsApp → API Setup から Phone number ID をコピーしてください。

##### 2. 無期限の System User token を発行する

Meta Business Suite で System User を作成し、App に対する whatsapp_business_messaging 権限を付与して、有効期限なしの token を生成してください。ユーザー token は期限切れになり、Agent を停止させます。

##### 3. コールバックを検証する前に routing ルールを作成する

verify token を決め、それと他のフィールドを Console に入力して、routing ルールを保存して有効にしてください。Meta はコールバック URL を Ankole に対して検証するため、ルールが先に存在する必要があります。

##### 4. コールバック URL を設定し、messages を購読する

WhatsApp → Configuration を開き、この URL と同じ verify token を入力して、Verify and save を選択してください。次に、App を messages webhook フィールドに購読させてください。他のフィールドは使用しません。Ankole はすべてのリクエストの x-hub-signature-256 を App secret で検査し、誤った署名をステータス 401 で拒否します。

```text
https://<ANKOLE_HOST>/webhooks/v1/whatsapp/<appId>/events
```

##### 5. Console のフィールドを収集する

- `appId` — Meta App ID。1 つの App の複数の電話番号がそれぞれ別の Agent を担当できます。それらのルールは同じ App secret と verify token を共有する必要があります。
- `appSecret` — App settings → Basic の App secret。Ankole は webhook の署名検証に使用します。
- `verifyToken` — 自分で決める値。Meta のコールバック設定に同じ値を入力してください。
- `phoneNumberId` — WhatsApp → API Setup の Phone number ID。1 つの番号は有効な routing ルール 1 つにのみ属せます。
- `accessToken` — 無期限の System User access token。
- `group_message_mode`: `addressed_only` — 唯一のモードです。WhatsApp は 1 対 1 のチャットのみを配信し、すべてのメッセージが Agent 宛になります。

#### 詳細設定 · identity マッピング、返信、プラットフォームの制限

展開すると、WhatsApp ユーザーがアカウントになる方法と、Agent が使用できない WhatsApp の機能を確認できます。

##### 1. WhatsApp ユーザーがアカウントになる方法を知る

送信者の WhatsApp ID は、Meta が検証した電話番号です。既存のアカウントがその携帯番号を所有している場合（たとえばディレクトリ同期による場合）、送信者は即時にマッピングされます。そうでない場合、アカウントの自動マッピングは失敗します。アカウントの自動マッピングに失敗した場合 を 手動レビュー のままにしてください。送信者は固定の通知を 1 回受け取り、WhatsApp のプロフィール名と電話番号とともに アイデンティティ → 保留中のマッピング に表示され、管理者がその identity を既存のアカウントに紐付けます。独立アカウントを自動作成 は、誰でも Agent と会話できる公開番号の場合にのみ選択してください。

##### 2. Agent の返信方法を知る

- 返信はユーザーのメッセージを引用します。長い返信は 4,096 文字で分割されます。
- 選択肢が 3 つまでの確認の質問は返信ボタンを表示し、それより多い選択肢は 1 つのリストを表示します。各選択肢は番号で始まります。
- Agent は、種類ごとの Meta のサイズ制限内で画像、動画、音声、ドキュメントを送信できます。Meta が受け付けないファイルは明確なエラーで停止し、テキストは引き続き送信されます。
- ユーザーが WhatsApp で削除したメッセージは Ankole に届かないため、そのテキストはセッションの context に残ります。

##### 3. カスタマーサービスウィンドウを守る

Ankole は送信ごとにウィンドウを確認します。ユーザーの最新のメッセージまたはボタン応答から 24 時間を超えた返信は customer_service_window_closed で停止し、Meta にはリクエストが送られません。新しいウィンドウを開く唯一の方法である有料のテンプレートメッセージは、現在の contract の対象外です。ユーザーが再度メッセージを送ったら、Signal Routing ページの 再試行 を使用して、停止した返信を送信してください。

##### 4. ルールをその電話番号に固定する

チャットは、それを受信した電話番号に紐付けられます。ルールを別の番号に移すと、以前のチャットへの返信は、ユーザーが一度も書き込んでいない番号から送信されるのではなく、binding_phone_number_mismatch で停止します。元の番号に戻すと解消されます。

### Email

Ankole は専用のメールボックスを IMAP で読み取り、Agent の返信を SMTP で送信します。各メールスレッドが 1 つの会話です。メールボックスは Agent に属します。他のメールクライアントで人が読んではいけません。

> **Email は Ankole の一部の機能を制限します**
>
> 他のメールクライアントが既読にしたメッセージは Agent に届かないため、メールボックスは専用である必要があります。Agent の返信は 1 通のプレーンテキストメールで、リアルタイムの進行状況、編集、ボタンはありません。確認の質問は番号付きのテキストとして届き、人は通常の返信で回答します。パスワードとアプリパスワードによるログインのみをサポートしているため、Gmail にはアプリパスワードが必要で、OAuth を必須とする Exchange Online のメールボックスは使用できません。
>
> control plane は IMAP サーバーと SMTP サーバーに直接到達する必要があります。HTTP egress proxy はこれらを対象としません。

**始める前に**

- IMAP と SMTP でアクセスでき、パスワードまたはアプリパスワードを持つ専用のメールボックス
- DMARC の結果を含む Authentication-Results ヘッダーを追加するメールサーバー、または外部からのメールを受け付けないプライベートなメールサーバー

#### 基本設定 · 専用のメールボックスを準備する

##### 1. メールボックスとそのパスワードを作成する

Agent だけが使用するメールボックスを作成し、IMAP と SMTP を有効にしてください。プロバイダーが要求する場合は、アカウントのパスワードではなく Ankole 用のアプリパスワードを作成してください。

> このメールボックスを他のメールクライアントで開かないでください。他のクライアントが既読にしたメッセージは Agent から見えません。

##### 2. サーバー設定を収集する

Ankole は IMAP に implicit TLS（通常はポート 993）で接続します。SMTP は STARTTLS（通常はポート 587）または implicit TLS（通常はポート 465）を使用します。Ankole はサーバー証明書をシステムの CA ストアに対して検証します。

##### 3. Console のフィールドを収集する

- `address`: `agent@example.com` — メールボックスのアドレス。返信はここから送信されます。
- `displayName`: `Ankole Agent` — 送信メールの送信者名。
- `imapHost`: `imap.example.com` — IMAP サーバーのホスト。
- `imapPort`: `993` — IMAP のポート。Ankole は implicit TLS を使用します。
- `smtpHost`: `smtp.example.com` — SMTP サーバーのホスト。
- `smtpPort`: `587` — SMTP のポート。STARTTLS では 587、TLS では 465 を使用してください。
- `smtpSecurity`: `starttls` — SMTP のポートに合わせて starttls または tls。
- `username` — ログイン名。通常はメールボックスのアドレスです。1 組の IMAP ホストとユーザー名は有効な routing ルール 1 つにのみ属せます。
- `password` — メールボックスのパスワードまたはアプリパスワード。Ankole は暗号化して保存します。
- `senderAuthentication`: `dmarc` — dmarc のままにしてください。none は、外部からのメールを受け付けないプライベートなメールサーバーの場合にのみ設定してください。

##### 4. テストメールを送信する

自分のアドレスからメールボックスにメールを送ってください。自分のアドレスがまだアカウントに紐付けられていない場合は、返信としてマッピングの通知を受け取ります。アイデンティティ → 保留中のマッピング でアドレスを紐付けて、メールを再送信してください。

#### 詳細設定 · 送信者の identity、送信者認証、スレッド

展開すると、メールの送信者が既知のアカウントになる方法と、Ankole がスレッドと一括メールを扱う方法を確認できます。

##### 1. メールの送信者がアカウントになる方法を知る

インターネット上の誰でもメールボックスに書き込めて、From アドレスはそれ自体では何も証明しないため、Ankole はメールの送信者をプロフィールのメールアドレスやローカルサインインのメールアドレスで照合することはありません。送信者は、明示的なメールの identity 紐付けによってのみ既知になります。ディレクトリ同期とプロバイダーのサインインは、プロバイダーが報告するアドレスを紐付けるため、同期されたディレクトリの社員は手動の手順なしに受け入れられます。それ以外のアドレスは、管理者が アイデンティティ → 保留中のマッピング から紐付けます。独立アカウントを自動作成 は、そのアドレスを識別子とするアカウントを作成します。公開メールボックスの場合にのみ使用してください。

##### 2. 送信者認証を理解する

senderAuthentication が dmarc の場合、Ankole は受信側のメールサーバーが追加する Authentication-Results ヘッダーを読み取り、From アドレスのドメインについて dmarc=pass を報告している場合にのみメッセージを受け入れます。失敗したメッセージは通知なしに無視されます。none は、メールサーバーがプライベートネットワーク上にあり、外部からのメールを受け付けない場合にのみ設定してください。

##### 3. スレッドと一括メールの扱いを知る

- スレッドは件名ではなく、In-Reply-To ヘッダーと References ヘッダーで判定されます。Agent の返信には、メールクライアントが使用するスレッドヘッダーが付きます。
- 参加者が送信者とメールボックスだけのスレッドは 1 対 1 の会話です。他の受信者がいるとグループの会話になり、メールボックスを Cc にのみ含むメッセージは Agent 宛になりません。
- 既知のスレッド内のメッセージでは、返信区切りの下の引用テキストが削除されます。スレッドの最初のメッセージと転送されたメッセージは、本文全体を保持します。
- メールボックス自身からのメール、自動送信メールと一括メール、メーリングリストのメールは通知なしに無視されます。
- 25 MB を超えるメッセージはヘッダーのみが届きます。送信する添付ファイルは 1 通あたり 20 MB までです。

### Console で接続を完了する

現在のリリースは直接接続を使用します。1 つの routing ルールが 1 つの Channel Provider を 1 つの Agent に接続します。これは、アダプタ、アプリの credential、ターゲット Agent、グループメッセージの動作を記録します。bot ごとに別のルールを作成してください。

Console で、**Signal Routing → New routing rule** を開き、設定してください：

| フィールド | 選択するもの |
|---|---|
| **Target Agent** | ステップ 3 で作成した Agent |
| **Adapter** | Slack、Teams、Lark/Feishu、DingTalk、WeCom、Telegram、Discord、LINE、WhatsApp、または Email |
| **Rule name** | `slack-main` や `lark-main` などの安定した名前 |
| **Group message mode** | `addressed_only` から始める |
| **Channel settings** | チャンネルタブの credential と値を貼り付ける |

ルールを保存してください。リストに enabled として表示される必要があります。フォームが credential を拒否した場合は、IM をテストする前にそのエラーを修正してください。アダプタはまだ接続を開いていません。

> **💡 知っていましたか？**
>
> 現在、1 つの routing ルールは 1 つの signal ソースを 1 つの Agent に送信します。チャットアプリが最も一般的なソースです。将来のルールは、チャンネル、会話、または別の条件で Agent を選択できます。Salesforce などの外部システムも、Agent が行動できるイベントを送信できるようになります。このモジュールが Signal Routing と呼ばれるのは、チャットチャンネルだけでなく、Agent の仕事を開始できるすべての signal を処理するためです。

#### 詳細設定 · グループでの動作と identity mapping

最初の設定では、Agent 宛のメッセージだけに返信させてください。

##### 1. Agent がアドレス指定されていないグループメッセージをどう処理するかを選択する

- `addressed_only` — Agent にアドレス指定しないグループメッセージを無視します。最初のテストにはこれを使用してください。
- `observe_all` — Agent の Turn を開始せずに、アドレス指定されていないメッセージを context として保存します。
- `may_intervene` — Agent が、アドレス指定されていない議論に参加するかどうかを決定できるようにします。

> provider がそれらのメッセージを配信する必要があります。DingTalk と WeCom は addressed_only のみをサポートします。Slack と Lark は、部屋全体を観察できるようになる前に追加のイベントまたは scope が必要です。

##### 2. namespace を identity マッピングのキーとして扱う

provider 組織ごとに 1 つの platformSubjectNamespace を使用してください。両方が同じ組織を指す場合のみ、IdP と Channel Provider のレコードの間で再利用してください。

## 5. IM で Agent と話す

bot をテスト用の会話に追加してください。グループチャットでは、明示的な @ メンションから始めます：

> @Ankole 何ができますか。どのチームにサービスを提供していますか？

最初の実際のモデル返信の後、Agent の mission、モデル、グループチャットポリシーをチーム用に調整してください。

<a id="agent-not-replying"></a>

### Agent が返信しない場合

次の順序で、一度に 1 つの境界を確認してください：

1. 最新の provider アプリのバージョンが公開され、テストユーザーが利用できる。
2. bot がチャンネル、チーム、または会話にインストールされている。
3. 必要なメッセージイベントと scope がアクティブである。
4. routing ルールが有効で、意図する Agent を指している。
5. Agent が `primary`、`light`、`heavy` のモデルプロファイルを持っている。
6. LLM Provider の credential とモデルセレクタが有効である。
7. 少なくとも 1 つの Worker が準備完了である。

Compose の場合は、`docker compose logs -f control-plane worker` を調べてください。Kubernetes の場合は、control plane と Worker の pod ログを調べてください。関連するエラーのみを読み、環境変数や secret を出力しないでください。

返信を受け取ったら、[Agents](https://ankole.agentbull.com/ja-JP/docs/agents/index.md)、[Signal Routing ルール](https://ankole.agentbull.com/ja-JP/docs/signal-bindings/index.md)、または [Background Agent Jobs](https://ankole.agentbull.com/ja-JP/docs/background-jobs/index.md) に進んでください。
