微信扫码
添加专属顾问
—— 兼论 Coze 的多 Agent 跳转为什么不可靠?兼论如何在多个 Agent 之间实现相对可靠的跳转?
Coze 最近新上了一个 Debug 日志功能,这个功能还挺牛的。
在 Debug 日志里你可以看到 Bot 在响应用户请求时背后完整的执行过程,包括每一次 LLM 调用的情况,每一个工作流的调用情况,甚至工作流内部每个节点调用的输入输出都可以查看到(图 1)。透过这个 Debug 日志,我们可以一窥 Coze 作为一个 Agent 平台的部分内部实现机制。
我之所以会花时间去剖析这些执行细节,也是为了解决一个实际问题:如何在多个 Agent 之间实现可靠的跳转?(见图 2)
以《谁是卧底》为例,它的标准流程是:【引导】→【游戏准备】→【人类玩家发言】→【AI 玩家发言】→【人类玩家投票】→【AI 玩家投票】→【报告本轮游戏结果】。
Coze 的多 Agent 跳转是一个老大难问题。几个月之前开发第一版《谁是卧底》的时候,就把我折腾得够呛。这段时间 Coze 经过几次迭代,把这个节点跳转功能整得越来越复杂了,但依然不可靠。
你在【切换节点设置】界面遍历完选择树的各种可能之后,会发现 Coze 为我们提供了三种 Agent 跳转模式(图 3):
Coze 的【切换节点设置】还支持你设置判断跳转的时机,有三个选项:“用户输入后”、“模型回复后”,以及“用户输入后&模型回复后”。这个判断时机乍一看很直白,但实际上很微妙,尤其是这个“用户输入后”。
接下来我会以《谁是卧底(优化版)》(https://www.coze.com/s/ZmFbLUtry/)为例(图 4),再结合 Debug 日志,深入解析一下三种 Agent 跳转方式。《卧底》里没有使用上述模式二的跳转模式,仅使用了模式一和模式二,但是有“用户输入后”和“模型回复后”两种判断时机的应用。
当用户在【引导】节点输入“开始游戏”之后,Coze 会执行如下流程(图 5):
我们先来看一下第一次 LLM 调用的输入(图 5):
{
"messages": [
{
"content": "# INSTRUCTION\nYou are an AI agent responsible for routing, and your job is to select the most suitable agent from the following agents based on user needs and lastest chat history.\n\n# AGENTS / BOTS LIST\n[\n {\n \"condition\": \"人类玩家进行发言。\",\n \"agent_id\": 1,\n \"agent_name\": \"人类玩家发言\"\n },\n {\n \"condition\": \"进行游戏准备。\",\n \"agent_id\": 2,\n \"agent_name\": \"游戏准备\"\n }\n]\n\n#USER REQUEST\nIf the last input from the user is \"开始\" or \"开始游戏\", select the agent with the name \"游戏准备\". \n\nOtherwise, output 0.\n\n# CONSTRAINT\nStrictly according to the above USER REQUEST, select the most suitable agent from the AGENTS LIST.\nYou must only reply the agent_id with nothing else. If you think there is no suitable agent, then output 0.\n**Note: You can only output the value of the agent_id or 0, your output should be pure numbers, do not output other content!**\n\n# PREVIOUS CONVERSATION HISTORY\nuser: 开始游戏\n",
"role": "system"
}
],
"model": "GPT-3.5 (16K)",
"model_meta": {
"format": "text",
"frequency_penalty": 0,
"max_tokens": 600,
"presence_penalty": 0,
"temperature": 0,
"top_p": 0
},
"tools": null
}忽略其他参数,我们关注 messages 列表。列表中只有一条消息,它的内容是:
# INSTRUCTION
You are an AI agent responsible for routing, and your job is to select the most suitable agent from the following agents based on user needs and lastest chat history.
# AGENTS / BOTS LIST
[
{
"condition": "人类玩家进行发言。",
"agent_id": 1,
"agent_name": "人类玩家发言"
},
{
"condition": "进行游戏准备。",
"agent_id": 2,
"agent_name": "游戏准备"
}
]
#USER REQUEST
If the last input from the user is "开始" or "开始游戏", select the agent with the name "游戏准备".
Otherwise, output 0.
# CONSTRAINT
Strictly according to the above USER REQUEST, select the most suitable agent from the AGENTS LIST.
You must only reply the agent_id with nothing else. If you think there is no suitable agent, then output 0.
**Note: You can only output the value of the agent_id or 0, your output should be pure numbers, do not output other content!**
# PREVIOUS CONVERSATION HISTORY
user: 开始游戏这是一段系统提示词,这就是 Coze 用来处理多 Agent 跳转的关键。提示词有 5 个部分:
agent_id 是一个序号,供 LLM 选择。agent_name 就是你给 Agent 节点设置的名字。condition 就是你在 Agent 节点设置的适用场景(Scenarios)(图 6)。前面说 Coze 的多 Agent 跳转总是不可靠,我们从这段短短的提示词中就可以找到几个导致不稳定的因素:
强力的模型有可能处理好这些导致跳转不稳定的因素,但是弱一点的模型就搞不定。然而这个场景用弱模型是有可能搞定的,比如 GPT3.5,或者 Gemini Flash 1.5,或者 Coze 那个专为切换节点训练的独立模型。现在的情况是,我只能在业务逻辑不太复杂的节点使用弱的模型来处理跳转。
我们来看一下第一次 LLM 调用的输出:
{
"model": "GPT-3.5 (16K)",
"choices": [
{
"message": {
"role": "assistant",
"content": "2"
},
"stop_reason": "stop"
}
],
"usage": {
"prompt_tokens": 263,
"completion_tokens": 1,
"total_tokens": 264
},
"generation_info": [
{
"PromptTokens": 0,
"CompletionTokens": 0,
"TotalTokens": 0
}
]
}我们可以看到,LLM 选择了 2 号 Agent,即【游戏准备】节点,实现了正确的跳转。
但是,接下来的 LLM 调用又是一个跳转判断,这次调用的是【游戏准备】节点的跳转判断模型(图 8)。
第二次 LLM 调用的输入:
{
"messages": [
{
"content": "# INSTRUCTION\nYou are an AI agent responsible for routing, and your job is to select the most suitable agent from the following agents based on user needs and lastest chat history.\n\n# AGENTS / BOTS LIST\n[\n {\n \"condition\": \"人类玩家进行发言。\",\n \"agent_id\": 1,\n \"agent_name\": \"人类玩家发言\"\n }\n]\n\n#USER REQUEST\nIf the last input from the user is *exactly* \"继续\", select the agent with the name \"人类玩家发言\".\n\nOtherwise, output 0.\n\n# CONSTRAINT\nStrictly according to the above USER REQUEST, select the most suitable agent from the AGENTS LIST.\nYou must only reply the agent_id with nothing else. If you think there is no suitable agent, then output 0.\n**Note: You can only output the value of the agent_id or 0, your output should be pure numbers, do not output other content!**\n\n# PREVIOUS CONVERSATION HISTORY\nuser: 开始游戏\n",
"role": "system"
}
],
"model": "GPT-3.5 (16K)",
"model_meta": {
"format": "text",
"frequency_penalty": 0,
"max_tokens": 600,
"presence_penalty": 0,
"temperature": 0,
"top_p": 0
},
"tools": null
}提示词模板与之前是一样的:
# INSTRUCTION
You are an AI agent responsible for routing, and your job is to select the most suitable agent from the following agents based on user needs and lastest chat history.
# AGENTS / BOTS LIST
[
{
"condition": "人类玩家进行发言。",
"agent_id": 1,
"agent_name": "人类玩家发言"
}
]
#USER REQUEST
If the last input from the user is *exactly* "继续", select the agent with the name "人类玩家发言".
Otherwise, output 0.
# CONSTRAINT
Strictly according to the above USER REQUEST, select the most suitable agent from the AGENTS LIST.
You must only reply the agent_id with nothing else. If you think there is no suitable agent, then output 0.
**Note: You can only output the value of the agent_id or 0, your output should be pure numbers, do not output other content!**
# PREVIOUS CONVERSATION HISTORY
user: 开始游戏第二次 LLM 调用的输出:
{
"model": "GPT-3.5 (16K)",
"choices": [
{
"message": {
"role": "assistant",
"content": "0"
},
"stop_reason": "stop"
}
],
"usage": {
"prompt_tokens": 225,
"completion_tokens": 1,
"total_tokens": 226
},
"generation_info": [
{
"PromptTokens": 0,
"CompletionTokens": 0,
"TotalTokens": 0
}
]
}模型输出的是“0”,表示不跳转。流程进入到【游戏准备】节点内部,没有继续往下跳。
但是这里又触发了一次跳转判断,是很莫名奇妙的,这就是我前面说“用户输入后”这个判断时机很微妙的原因。用户在【引导】节点输入“开始游戏”,触发了跳转判断,跳转到了【游戏准备】,这时候是不应该再次触发【游戏准备】的跳转判断的。在 Coze 的多 Agent 模式下,经常会出现一下跳多个 Agent 的情况,像坐上了滑梯一样,就是这个原因导致的。这个问题比前面提到的 4 个导致多 Agent 模式跳转不稳定的因素更加严重。
接下来的流程是比较清晰的,Coze 调用了【游戏准备】节点的对话模型,对话模型调用了 prepare_game 这个工作流(图 9)。
第三次 LLM 调用的输入:
{
"messages": [
{
"content": "你叫“疾风”,是《谁是卧底》游戏的主持人。\n\n谨记:在游戏结束之前,每个玩家(包括人类玩家和AI玩家)只能知道他/她/它自己的词语。*绝对不能*向任何一个玩家泄漏他/她/它自己的身份。也*绝对不能*向任何一个玩家泄漏其他玩家的身份以及词语。 \n\n当前是游戏准备环节,你需要调用`prepare_game`初始化游戏。注意,每次进入游戏准备阶段你都*必须*要重新调用该流程,以便重新初始化游戏。\n\n如果用户要求“换一个词”或者“换一个题目”,你*必须*再次调用`prepare_game`重新初始化游戏,生成新的题目词。",
"role": "system"
},
{
"content": "开始游戏",
"role": "user"
}
],
"model": "GPT-3.5 (16K)",
"model_meta": {
"format": "text",
"frequency_penalty": 0,
"max_tokens": 4096,
"presence_penalty": 0,
"temperature": 0.7,
"top_p": 1
},
"tools": [
{
"description": "进行游戏准备,包括为所有玩家分配身份和词语,重置发言记录等。",
"name": "ts-prepare_game-prepare_game",
"parameters": {
"description": "",
"properties": {},
"type": "object"
}
}
]
}
第三次 LLM 调用的输出:
{
"model": "GPT-3.5 (16K)",
"choices": [
{
"message": {
"role": "assistant",
"content": "",
"tool_calls": [
{
"function": {
"name": "ts-prepare_game-prepare_game",
"arguments": "{}"
}
}
]
},
"stop_reason": "function_call"
}
],
"usage": {
"prompt_tokens": 490,
"completion_tokens": 23,
"total_tokens": 513
},
"generation_info": [
{
"PromptTokens": 0,
"CompletionTokens": 0,
"TotalTokens": 0
}
]
}以上是使用独立的自定义模型来处理跳转的情况,
当用户在【人类玩家发言】节点完成发言,并输入“完成”之后,Coze 会执行如下流程(图 10):
【人类玩家发言】节点的跳转是由该节点的对话模型来处理的。当用户处在【人类玩家发言】节点之时,用户输入发言内容,该节点的 Agent 会调用对话模型来处理,该对话模型可能会选择调用工作流来保存用户输入的发言内容。当用户输入“完成”的时候,该节点的 Agent 同样会调用对话模型来处理,这时候它可能就会选择跳转。这里的跳转本质上其实也是调用了一个工具(见图 10)。
第一次 LLM 调用的输入:
{
"messages": [
{
"content": "你叫“疾风”,是《谁是卧底》游戏的主持人。\n\n谨记:在游戏结束之前,每个玩家(包括人类玩家和AI玩家)只能知道他/她/它自己的词语。*绝对不能*向任何一个玩家泄漏他/她/它自己的身份。也*绝对不能*向任何一个玩家泄漏其他玩家的身份以及词语。 \n\n当前是用户(人类玩家)发言的环节。你需要引导用户(人类玩家)进行发言。在该环节用户可以多次发言,直到用户说“完成”为止。\n\n如果在用户(人类玩家)发言为有效内容,你需要调用`save_speech_record`将玩家的发言内容保存起来。`speaker`参数为“人类玩家”,`speech_content`必须为准确的用户发言内容,不要做任何更改。保存完用户发言之后,你需要提醒用户,输入“完成”结束发言。\n\n如果用户说“完成”,请调用`SystemNextStep-7389898815346229253`,跳转到AI玩家发言环节。",
"role": "system"
},
{
"content": "是一名小说中的人物",
"role": "user"
},
{
"content": "",
"role": "assistant",
"tool_calls": [
{
"function": {
"arguments": "{\"speaker\":\"人类玩家\",\"speech_content\":\"是一名小说中的人物\"}",
"name": "save_speech_record"
}
}
]
},
{
"content": "{\"is_success\":true}",
"name": "save_speech_record",
"role": "tool"
},
{
"content": "已经保存你的发言:“是一名小说中的人物”。请继续描述,或者说“完成”结束发言。",
"role": "assistant"
},
{
"content": "完成",
"role": "user"
}
],
"model": "GPT-4o (8K)",
"model_meta": {
"format": "text",
"frequency_penalty": 0,
"max_tokens": 3739,
"presence_penalty": 0,
"temperature": 0.7,
"top_p": 1
},
"tools": [
{
"description": "保存玩家的发言记录。",
"name": "save_speech_record",
"parameters": {
"description": "",
"properties": {
"speaker": {
"description": "发言玩家的代号,如“人类玩家”,“1号AI玩家”,“2号AI玩家”,“3号AI玩家”",
"properties": {},
"type": "string"
},
"speech_content": {
"description": "发言玩家的发言内容",
"properties": {},
"type": "string"
}
},
"required": [
"speaker",
"speech_content"
],
"type": "object"
}
},
{
"description": "AI玩家进行发言。",
"name": "SystemNextStep-7390769467972272133",
"parameters": {
"description": "",
"properties": {},
"type": "object"
}
},
{
"description": "用户说“重新开始”或者“重新开始游戏”",
"name": "SystemNextStep-7390769467972239365",
"parameters": {
"description": "",
"properties": {},
"type": "object"
}
}
]
}这里需要注意的是在 tools 列表里有一个叫做 SystemNextStep-7390769467972272133 的工具,一旦 LLM 决定调用这个工具,就会跳转到这个工具指定的 Agent。工具名字后面那一串数字就是【AI 玩家发言】这个 Agent 的 ID,你可以在对应的 Agent 节点查看(图 11)。
第一次 LLM 调用的输出:
{
"model": "GPT-4o (8K)",
"choices": [
{
"message": {
"role": "assistant",
"content": "",
"tool_calls": [
{
"function": {
"name": "SystemNextStep-7390769467972272133",
"arguments": "{}"
}
}
]
},
"stop_reason": "tool_calls"
}
],
"usage": {
"prompt_tokens": 788,
"completion_tokens": 31,
"total_tokens": 819
},
"generation_info": [
{
"PromptTokens": 0,
"CompletionTokens": 0,
"TotalTokens": 0
}
]
}我们看到,这个 LLM 调用了 SystemNextStep-7390769467972272133 这个工具,实现了跳转到【AI 玩家发言】这个节点的效果。
以上是使用 Agent 自身的对话模型来处理跳转的情况,
跳转到【AI 玩家发言】后, Coze 调用了该 Agent 的对话模型(图 12),该对话模型调用了 ai_players_speak 这个工作流,获取所有 AI 玩家的发言。
因为该节点的跳转判断时机是“模型回复后”,所以它没有像之前【游戏准备】节点一样又触发一次跳转判断。该节点的跳转判断是在它执行完工作流之后触发的,即第三次 LLM 调用(图 13)。
第三次 LLM 调用的输入:
{
"messages": [
{
"content": "# INSTRUCTION\nYou are an AI agent responsible for routing, and your job is to select the most suitable agent from the following agents based on user needs and lastest chat history.\n\n# AGENTS / BOTS LIST\n[\n {\n \"condition\": \"人类玩家进行投票。\",\n \"agent_id\": 1,\n \"agent_name\": \"人类玩家投票\"\n },\n {\n \"condition\": \"人类玩家进行发言。\",\n \"agent_id\": 2,\n \"agent_name\": \"人类玩家发言\"\n },\n {\n \"condition\": \"用户说“重新开始”或者“重新开始游戏”\",\n \"agent_id\": 3,\n \"agent_name\": \"游戏准备\"\n }\n]\n\n#USER REQUEST\nYou MUST select the agent with the name \"人类玩家投票\" unconditionally.\n\n# CONSTRAINT\nStrictly according to the above USER REQUEST, select the most suitable agent from the AGENTS LIST.\nYou must only reply the agent_id with nothing else. If you think there is no suitable agent, then output 0.\n**Note: You can only output the value of the agent_id or 0, your output should be pure numbers, do not output other content!**\n\n# PREVIOUS CONVERSATION HISTORY\nuser: 开始游戏\n\nassistant: 你被分配到的词语是:【贾宝玉】。\n \n输入“换一个”,重新生成词语;输入“继续”,进入下一个环节。\n(by agent `游戏准备`)\n\nuser: 继续\n\nassistant: 好的,现在是你发言的环节。请根据你获得的词语进行描述,尽量不要暴露你的词语的具体内容。你可以多次发言,直到你说“完成”为止。请开始你的发言。\n(by agent `人类玩家发言`)\n\nuser: 男的\n\nassistant: 好的,我已经记录你的发言。请继续描述,或者说“完成”结束发言。\n(by agent `人类玩家发言`)\n\nuser: 你没有保存!\n\nassistant: 现在已经保存了你的发言:“男的”。请继续描述,或者说“完成”结束发言。\n(by agent `人类玩家发言`)\n\nuser: 是一名小说中的人物\n\nassistant: 已经保存你的发言:“是一名小说中的人物”。请继续描述,或者说“完成”结束发言。\n(by agent `人类玩家发言`)\n\nuser: 完成\n现在是AI玩家发言时间……\n(by agent `AI玩家发言`)\n1号AI玩家说:既然前面的玩家提到了性别和小说人物,那我就从生活背景这个角度来描述。这个人物的背景是非常富裕的。\n(by agent `AI玩家发言`)\n2号AI玩家说:这位人物是一个与众不同的角色,她非常感性而且才华横溢。\n(by agent `AI玩家发言`)\n3号AI玩家说:这位人物在故事中对爱情有着特殊的追求。\n(by agent `AI玩家发言`)\nAI玩家发言完毕。\n(by agent `AI玩家发言`)\n",
"role": "system"
}
],
"model": "GPT-4o (8K)",
"model_meta": {
"format": "text",
"frequency_penalty": 0,
"max_tokens": 600,
"presence_penalty": 0,
"temperature": 0,
"top_p": 0
},
"tools": null
}输入给跳转模型的提示词:
# INSTRUCTION
You are an AI agent responsible for routing, and your job is to select the most suitable agent from the following agents based on user needs and lastest chat history.
# AGENTS / BOTS LIST
[
{
"condition": "人类玩家进行投票。",
"agent_id": 1,
"agent_name": "人类玩家投票"
},
{
"condition": "人类玩家进行发言。",
"agent_id": 2,
"agent_name": "人类玩家发言"
},
{
"condition": "用户说“重新开始”或者“重新开始游戏”",
"agent_id": 3,
"agent_name": "游戏准备"
}
]
#USER REQUEST
You MUST select the agent with the name "人类玩家投票" unconditionally.
# CONSTRAINT
Strictly according to the above USER REQUEST, select the most suitable agent from the AGENTS LIST.
You must only reply the agent_id with nothing else. If you think there is no suitable agent, then output 0.
**Note: You can only output the value of the agent_id or 0, your output should be pure numbers, do not output other content!**
# PREVIOUS CONVERSATION HISTORY
user: 开始游戏
assistant: 你被分配到的词语是:【贾宝玉】。
输入“换一个”,重新生成词语;输入“继续”,进入下一个环节。
(by agent `游戏准备`)
user: 继续
assistant: 好的,现在是你发言的环节。请根据你获得的词语进行描述,尽量不要暴露你的词语的具体内容。你可以多次发言,直到你说“完成”为止。请开始你的发言。
(by agent `人类玩家发言`)
user: 男的
assistant: 好的,我已经记录你的发言。请继续描述,或者说“完成”结束发言。
(by agent `人类玩家发言`)
user: 你没有保存!
assistant: 现在已经保存了你的发言:“男的”。请继续描述,或者说“完成”结束发言。
(by agent `人类玩家发言`)
user: 是一名小说中的人物
assistant: 已经保存你的发言:“是一名小说中的人物”。请继续描述,或者说“完成”结束发言。
(by agent `人类玩家发言`)
user: 完成
现在是AI玩家发言时间……
(by agent `AI玩家发言`)
1号AI玩家说:既然前面的玩家提到了性别和小说人物,那我就从生活背景这个角度来描述。这个人物的背景是非常富裕的。
(by agent `AI玩家发言`)
2号AI玩家说:这位人物是一个与众不同的角色,她非常感性而且才华横溢。
(by agent `AI玩家发言`)
3号AI玩家说:这位人物在故事中对爱情有着特殊的追求。
(by agent `AI玩家发言`)
AI玩家发言完毕。
(by agent `AI玩家发言`)可以看到对话记录越来越长了,所以这里我不得不用 GPT-4o这样的强力模型。因为上下文干扰,弱的模型甚至连这种基本的无条件跳转都做不到。
第三次 LLM 调用的输出:
{
"model": "GPT-4o (8K)",
"choices": [
{
"message": {
"role": "assistant",
"content": "1"
},
"stop_reason": "stop"
}
],
"usage": {
"prompt_tokens": 827,
"completion_tokens": 1,
"total_tokens": 828
},
"generation_info": [
{
"PromptTokens": 0,
"CompletionTokens": 0,
"TotalTokens": 0
}
]
}模型输出“1”,表示选择【人类玩家投票】这个 Agent,因此它正确跳转到了【人类玩家投票】这个节点。
接下来 Coze 调用了【人类玩家投票】的对话模型,即第四次 LLM 调用(图 14)。
第四次 LLM 调用的输人:
{
"messages": [
{
"content": "你叫“疾风”,是《谁是卧底》游戏的主持人。\n\n谨记:在游戏结束之前,每个玩家(包括人类玩家和AI玩家)只能知道他/她/它自己的词语。*绝对不能*向任何一个玩家泄漏他/她/它自己的身份。也*绝对不能*向任何一个玩家泄漏其他玩家的身份以及词语。 \n\n当前是用户(人类玩家)投票环节,你需要引导用户(人类玩家)进行投票。在该环节用户可以修改投票目标,直到用户说“完成”为止。\n\n三位AI玩家的序号分别是1,2,3,提示用户回复数字即可投票。注意:人类玩家只能投票给*还未出局*的AI玩家。\n\n如果用户输入的投票目标有效,你需要调用`save_voting_result`将玩家的投票结果保存起来。`voter_idx`参数为当前投票玩家的序号,人类玩家的序号是0。`voted_player_idx`为被投票玩家的序号,三位AI玩家的序号分别是1,2,3。`reset`参数需要设置为true。保存完用户投票结果之后,你需要提醒用户,输入“完成”结束投票。\n\n如果用户说“完成”,请调用`SystemNextStep-7389898815346262021`,跳转到AI玩家投票环节。",
"role": "system"
},
{
"content": "是一名小说中的人物",
"role": "user"
},
{
"content": "已经保存你的发言:“是一名小说中的人物”。请继续描述,或者说“完成”结束发言。",
"role": "assistant"
},
{
"content": "完成",
"role": "user"
},
{
"content": "",
"role": "assistant",
"tool_calls": [
{
"function": {
"arguments": "{}",
"name": "ai_players_speak"
}
}
]
},
{
"content": "ai_players_speak directly streaming reply.",
"name": "ai_players_speak",
"role": "tool"
},
{
"content": "现在是AI玩家发言时间……",
"role": "assistant"
},
{
"content": "1号AI玩家说:既然前面的玩家提到了性别和小说人物,那我就从生活背景这个角度来描述。这个人物的背景是非常富裕的。",
"role": "assistant"
},
{
"content": "2号AI玩家说:这位人物是一个与众不同的角色,她非常感性而且才华横溢。",
"role": "assistant"
},
{
"content": "3号AI玩家说:这位人物在故事中对爱情有着特殊的追求。",
"role": "assistant"
},
{
"content": "AI玩家发言完毕。",
"role": "assistant"
}
],
"model": "GPT-4o (8K)",
"model_meta": {
"format": "text",
"frequency_penalty": 0,
"max_tokens": 3633,
"presence_penalty": 0,
"temperature": 0.7,
"top_p": 1
},
"tools": [
{
"description": "保存人类玩家和AI玩家的投票结果",
"name": "save_voting_result",
"parameters": {
"description": "",
"properties": {
"reset": {
"description": "是否重置保存的投票结果",
"properties": {},
"type": "boolean"
},
"voted_player_idx": {
"description": "被投票玩家的序号,人类玩家的序号是0,三位AI玩家的序号分别是1,2,3。",
"properties": {},
"type": "string"
},
"voter_idx": {
"description": "投票玩家的序号,人类玩家的序号是0,三位AI玩家的序号分别是1,2,3。",
"properties": {},
"type": "string"
}
},
"required": [
"voter_idx",
"voted_player_idx"
],
"type": "object"
}
},
{
"description": "AI 玩家进行投票。",
"name": "SystemNextStep-7390769467972304901",
"parameters": {
"description": "",
"properties": {},
"type": "object"
}
},
{
"description": "用户说“重新开始”或者“重新开始游戏”",
"name": "SystemNextStep-7390769467972239365",
"parameters": {
"description": "",
"properties": {},
"type": "object"
}
}
]
}第四次 LLM 调用的输出:
{
"model": "GPT-4o (8K)",
"choices": [
{
"message": {
"role": "assistant",
"content": "现在进入投票环节。请投票给你认为是卧底的AI玩家,回复对应的数字即可(1,2,3)。"
},
"stop_reason": "stop"
}
],
"usage": {
"prompt_tokens": 1080,
"completion_tokens": 42,
"total_tokens": 1122
},
"generation_info": [
{
"PromptTokens": 0,
"CompletionTokens": 0,
"TotalTokens": 0
}
]
}这一次对话模型没有调用任何工作流,而是回复了一条消息,引导人类玩家进行投票。
至此,我们已经介绍完《谁是卧底》里的三种典型的控制多 Agent 跳转的方式。目前卧底的这一套配置至少在多 Agent 跳转方面是相对稳定的(即便 Coze 本身的实现中有很多坑)。
在这个过程中,我们主要利用 Coze 的 Debug 日志深入剖析了 Coze 的多 Agent 模式的实现机制,找到了一些造成多 Agent 跳转不可靠的因素(希望 Coze 团队能尽快修复)。Coze 的 Debug 日志是个很好的工具,它让我们可以窥到 Coze 内部的一些实现机制,也可以一定程度破除大家对所谓 Agent 以及 Multiagent 这些上层概念的困惑。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业
2026-09-29
字节扣子的地板,为什么一直在塌
2026-09-07
把转录、纪要、配音串成一条流水线,我这么搞
2026-07-06
实测扣子3.0:把Claude Code、CodeX拉到一个项目群里干活,夯爆了
2026-07-05
Cozi 智能体 + 工作流组合拳:复杂场景下的 AI 应用搭建指南
2026-06-18
别再纠结Coze还是Dify还是n8n了
2026-06-01
扣子 3.0 正式上线:新一代 AI 团队,从扣子开始
2026-04-07
Agent有了身份证的第一天,但人类还没想清楚它是什么?
2026-04-07
刚刚,扣子搞了个大的:你的满配 AI 伙伴已就位!(附场景案例)
欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。
在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。
一、 定义
本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。
会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。
知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。
二、 账号注册与登录
登录方式:本网站支持以下登录方式,您可根据实际情况选择:
微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。
手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。
账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。
实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。
未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。
三、 服务内容与规范
知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。
服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。
禁止行为:您在使用服务时不得实施以下行为:
利用技术手段批量爬取、下载、转存知识库内容;
将知识库内容用于商业目的或未经授权地向第三方传播;
干扰本网站正常运行或侵犯其他用户合法权益;
发布违法违规信息或从事违反公序良俗的活动。
四、 知识产权声明
权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。
有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。
侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。
五、 个人信息保护
我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。
您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。
您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。
六、 免责声明
内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。
不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。
第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。
七、 违约责任
如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。
如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。
八、 法律适用与争议解决
本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。
因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。
九、 其他
本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。
本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。
我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。