チャネルは、Think エージェントが会話するサーフェスです。ブラウザーの WebSocket、メッセンジャー webhook(Telegram、Slack など)、音声、独自のトランスポートが該当します。チャネルは メッセンジャー を共通の語彙にまとめるので、ターンがどのサーフェスから来ても、チャネルごとのポリシー(別のシステムプロンプト、絞り込んだツールセット、ステップ上限)を適用し、帯域外通知を配信できます。
すべての Think エージェントには、常に暗黙の web チャネルがあります(ブラウザークライアントが使う WebSocket チャットです)。追加チャネルの宣言と web ポリシーの上書きは、configureChannels() で行います。getMessengers() が返すメッセンジャーは、自動的に messenger チャネルとして取り込まれます。既存のメッセンジャーアプリはそのまま動きます。
configureChannels() をオーバーライドし、チャネル id から ChannelDefinition へのマップを返します。id は、ターンでチャネルを選ぶときの識別子です。
import { Think, messengerChannel } from "@cloudflare/think";
import { telegram } from "@chat-adapter/telegram";
export class Assistant extends Think {
configureChannels() {
return {
// Override policy for the built-in web channel.
web: {
kind: "web",
ingress: { transport: "websocket" },
instructions: "You are chatting in a web app. Use markdown freely.",
},
// A voice channel with tighter limits.
voice: {
kind: "voice",
ingress: { transport: "voice" },
instructions: "Keep replies short and speakable. No markdown.",
maxTurns: 3,
},
// A messenger channel (Chat SDK webhook).
telegram: messengerChannel(telegram({/* adapter config */})),
};
}
}import { Think, messengerChannel } from "@cloudflare/think";
import { telegram } from "@chat-adapter/telegram";
export class Assistant extends Think<Env> {
configureChannels() {
return {
// Override policy for the built-in web channel.
web: {
kind: "web",
ingress: { transport: "websocket" },
instructions: "You are chatting in a web app. Use markdown freely.",
},
// A voice channel with tighter limits.
voice: {
kind: "voice",
ingress: { transport: "voice" },
instructions: "Keep replies short and speakable. No markdown.",
maxTurns: 3,
},
// A messenger channel (Chat SDK webhook).
telegram: messengerChannel(
telegram({
/* adapter config */
}),
),
};
}
}ChannelDefinition には次のフィールドがあります。
| フィールド | 型 | 説明 |
|---|---|---|
kind |
"web" | "messenger" | "voice" | "custom" |
サーフェスの分類。 |
ingress |
{ transport: "websocket" | "voice" } または webhook メッセンジャー仕様 |
ターンの到着方法。messengerChannel() が webhook 形式を組み立てます。 |
instructions |
string | (ctx: ChannelContext) => string | Promise<string> |
このチャネルのターンで、システムプロンプトの先頭に付けます。 |
tools |
(all: ToolSet) => ToolSet |
このチャネル向けに組み立て済みツールセットを絞ります(フィルターのみ。追加はできません)。 |
maxTurns |
number |
1 ターンあたりのモデルステップ数の、チャネルごとの上限。 |
capabilities |
ChannelCapabilities |
サーフェスの能力(ストリーミング、メッセージ編集)。web には既定値があります。 |
conversation |
メッセンジャーの会話モードまたはリゾルバー | メッセンジャースレッドのルーティング(メッセンジャー を参照)。 |
delivery |
チャネルの配信ポリシー | メッセンジャーの配信ポリシー。 |
型推論には defineChannels() ヘルパーを使い、Chat SDK アダプター定義を kind: "messenger" チャネルとして包むには messengerChannel() を使います。
| 種類 | Ingress | 備考 |
|---|---|---|
web |
{ transport: "websocket" } |
常に存在します。ポリシー設定のためだけに configureChannels() で宣言します。削除はできません。 |
messenger |
webhook(messengerChannel(...)) |
メッセンジャーランタイムに渡されます。getMessengers() のエントリと同等です。 |
voice |
{ transport: "voice" } |
ポリシーとターンコンテキストを適用します。帯域外配信はまだ接続されていません。 |
custom |
アプリ定義 | 独自トランスポート向けです。現状の配信制限は voice と同じです。 |
チャネルポリシーは、beforeTurn の実行前に 上書き可能な既定値 として適用されます。そのため beforeTurn の上書きが優先されます。
instructionsは、そのターンのベースシステムプロンプトの先頭に付けます。toolsは組み立て済みツールセットをフィルターします(削除のみです。追加はgetTools()の接続点で行います)。maxTurnsはモデルステップを上限します。優先順は、beforeTurnのmaxSteps、次にチャネルのmaxTurns、最後にインスタンスのmaxSteps既定値です。
runTurn()(または chat())に channel を渡すと、指定チャネルでターンを実行します。チャネル id はユーザーメッセージに刻まれるので、継続や復旧のターンでも同じチャネルを再解決し、そのポリシーを再適用します。
export class Assistant extends Think {
async speak() {
await this.runTurn({ input: "Read this out loud", channel: "voice" });
}
}export class Assistant extends Think<Env> {
async speak() {
await this.runTurn({ input: "Read this out loud", channel: "voice" });
}
}ターン内では、アクティブなチャネルは this.activeChannel として参照できます(channelId、kind、該当時はメッセンジャー詳細を持つ ChannelContext です)。channel のないターンはチャネルコンテキストなしで動き、チャネルポリシーは適用しません。
deliverNotice() は、モデルターンを開始 せずに チャネルへメッセージを送ります。ステータス更新(「インポートが完了しました」)や、アクションの reply attachment の表示に使います。推論は走らず、ターンキューにも入らないので、ツールの execute 内から呼んでも安全です。
export class Assistant extends Think {
async notify() {
await this.deliverNotice("Your export is ready to download.");
await this.deliverNotice("Background research finished.", {
informModel: true, // also record it in the transcript so the next turn knows
});
}
}export class Assistant extends Think<Env> {
async notify() {
await this.deliverNotice("Your export is ready to download.");
await this.deliverNotice("Background research finished.", {
informModel: true, // also record it in the transcript so the next turn knows
});
}
}type DeliverNoticeOptions = {
channel?: string; // defaults to the active turn's channel, else "web"
informModel?: boolean; // also write to the model-visible transcript (default false)
kind?: "final" | "interim" | "notice" | "command"; // wire tag (default "notice")
thread?: string; // required for out-of-turn delivery to a multi-thread messenger
};動作は対象チャネルによって変わります。
web— 通知は必ずトランスクリプトに追記されます(それが唯一の描画経路です)。informModelは言い回しだけを制御します。messenger— 通知はプロバイダーへ投稿されます。ターン外では、会話を指定するためにthreadを渡します。informModel: trueの場合は、トランスクリプトにも書き込まれます。voice/custom— ターン外配信は例外を投げます。これらのサーフェスには、まだ配信先がないためです。
アクションの reply attachment を通知に変えるには、renderAttachment(attachment) をオーバーライドします。Think はターン終了時にこれを呼び、描画したテキストを末尾の interim 通知として配信します。その種類をスキップするには undefined を返します。
configureChannels() は getMessengers() を包みます。置き換えではありません。各 getMessengers() エントリは kind: "messenger" チャネルになり、メッセンジャー ガイドの内容(Telegram の設定、webhook ルーティング、会話ターゲット、配信と復旧)はそのまま適用されます。configureChannels() のチャネル id が getMessengers() の id と衝突するとエラーです。メッセンジャー専用アプリでは getMessengers() を使い続けてください。web / voice / custom のポリシーや帯域外通知も欲しいときは、configureChannels() を使います。
チャネルの活動は、channel 可観測性チャネルで報告されます。
import { subscribe } from "agents/observability";
const unsubscribe = subscribe("channel", (event) => {
// event.type is one of:
// "channel:resolved" — a turn resolved a registered channel
// "channel:delivered" — a turn's final reply was delivered
// "notice:delivered" — deliverNotice() succeeded
// "notice:failed" — deliverNotice() threw
});import { subscribe } from "agents/observability";
const unsubscribe = subscribe("channel", (event) => {
// event.type is one of:
// "channel:resolved" — a turn resolved a registered channel
// "channel:delivered" — a turn's final reply was delivered
// "notice:delivered" — deliverNotice() succeeded
// "notice:failed" — deliverNotice() threw
});| メンバー | 説明 |
|---|---|
configureChannels() |
チャネルマップを返します。既定は {}(暗黙の web チャネルのみ)です。 |
deliverNotice(text, options?) |
モデルターンなしで、チャネルへ帯域外メッセージを送ります。 |
activeChannel |
実行中ターンの ChannelContext。なければ undefined です。 |
renderAttachment(attachment) |
reply attachment をチャネル通知テキストに変換します(スキップは undefined)。 |
defineChannels(channels) |
チャネルマップの型推論用の恒等ヘルパーです。 |
messengerChannel(definition) |
Chat SDK アダプターを kind: "messenger" チャネルとして包みます。 |