跳转到内容
搜索文档

渠道

最后更新 查看 MarkdownAgent 设置

渠道是 Think Agent 进行对话的界面:浏览器 WebSocket、messenger webhook(Telegram、Slack 等)、语音,或你自己的自定义传输。渠道将 messengers 泛化为统一词汇,以便应用按渠道策略(不同系统提示词、收窄工具集、步数上限)并投递带外通知,无论轮次从哪个界面到达。

每个 Think Agent 始终有隐式 web 渠道(浏览器客户端使用的 WebSocket 聊天)。用 configureChannels() 声明额外渠道 — 并覆盖 web 策略。getMessengers() 返回的 messenger 会自动吸收为 messenger 渠道,现有 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 messenger 规范 轮次如何到达。messengerChannel() 为你构建 webhook 形式。
instructions string | (ctx: ChannelContext) => string | Promise<string> 该渠道轮次的系统提示词前缀。
tools (all: ToolSet) => ToolSet 为该渠道收窄已组装工具集(仅过滤 — 不能添加工具)。
maxTurns number 该渠道每轮的模型步数上限。
capabilities ChannelCapabilities 界面能力(流式、消息编辑)。web 有默认值。
conversation messenger 对话模式或解析器 Messenger 线程路由(见 Messengers)。
delivery 渠道投递策略 Messenger 投递策略。

defineChannels() 辅助函数做类型推断,用 messengerChannel() 将 Chat SDK 适配器定义包装为 kind: "messenger" 渠道。

渠道种类

种类 入口 说明
web { transport: "websocket" } 始终存在。仅在 configureChannels() 中声明以设置策略;不能移除。
messenger webhook(messengerChannel(...) 输入 messenger 运行时。等价于 getMessengers() 条目。
voice { transport: "voice" } 应用策略与轮次上下文;带外投递尚未接入。
custom 应用自定义 自定义传输。今日与 voice 相同的投递限制。

按渠道策略

渠道策略在 beforeTurn 之前作为可覆盖的默认值应用,因此 beforeTurn 重写仍优先:

  • instructions 前缀到该轮次的基础系统提示词。
  • tools 过滤已组装工具集(只能移除 — getTools() 接口负责添加)。
  • maxTurns 限制模型步数:beforeTurnmaxSteps 优先,然后渠道 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.activeChannelChannelContext,含 channelIdkind,相关时有 messenger 详情)。无 channel 的轮次无渠道上下文,不应用渠道策略。

带外投递

deliverNotice() 向渠道 发送消息而不启动模型轮次。用于状态更新(「你的导入已完成」)或已呈现操作的 回复附件 — 不运行推理、不进入轮次队列,因此可在工具 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 — 带外投递会抛出异常,这些界面尚无投递目标。

重写 renderAttachment(attachment) 将操作回复附件转为通知;Think 在轮次结束时调用,并将渲染文本作为尾随 interim 通知投递。返回 undefined 跳过某附件类型。

与信使的关系

configureChannels() 包装 getMessengers() — 不替换。每个 getMessengers() 条目成为 kind: "messenger" 渠道,Messengers 指南中的内容(Telegram 设置、webhook 路由、对话目标、投递与恢复)继续适用。configureChannels() 中与 getMessengers() id 冲突的渠道 id 是错误。仅 messenger 的应用继续用 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) 将回复附件映射为渠道通知文本(或 undefined 跳过)。
defineChannels(channels) 渠道映射类型推断的恒等辅助函数。
messengerChannel(definition) 将 Chat SDK 适配器包装为 kind: "messenger" 渠道。

相关

  • Messengers — Chat SDK webhook 设置与投递详解。
  • 操作 — 为 renderAttachment() 记录回复附件。
  • 语音 — 实时语音界面。

这篇文档对您有帮助吗?