如何在Dialogflow CX中为聊天组件实现部分响应功能?
在Dialogflow CX生产环境中实现分步部分响应的解决方案
问题背景
已创建Dialogflow CX代理,通过Webhook处理外部API调用,但API存在等待时间,希望先发送“我马上为您查询”这类提示消息,延迟后再发送API返回结果。Dialogflow测试环境中部分响应功能正常,但生产环境搭配Tiledesk聊天组件时,所有消息被一次性转发,未实现分步发送。
解决方案核心思路
普通的detectIntent方法会等待Dialogflow完成所有处理(包括Webhook调用)后返回完整响应,无法实时获取部分消息。需要改用流式检测意图(streamingDetectIntent),实时接收并发送部分响应,实现分步推送。
修改后的代码实现
// Import dependencies const functions = require('@google-cloud/functions-framework'); const { TiledeskChatbotClient } = require('@tiledesk/tiledesk-chatbot-client'); const { SessionsClient } = require('@google-cloud/dialogflow-cx'); const { createPool } = require('generic-pool'); // Set configuration constants for Dialogflow const dfProjectId = '___ProjectId___'; const dfLocationId = '___LocationId___'; const dfAgentId = '___AgentId___'; const dfLanguageCode = 'en'; // Create a connection pool for the Dialogflow client const dialogflowPool = createPool({ create: () => new SessionsClient({ apiEndpoint: `${dfLocationId}-dialogflow.googleapis.com` }), destroy: client => client.close(), max: 10, min: 2, idleTimeoutMillis: 30000, }); async function detectIntentText(userMessage, requestId, languageCode, tdClient) { let dialogflowClient; try { dialogflowClient = await dialogflowPool.acquire(); const sessionPath = dialogflowClient.projectLocationAgentSessionPath(dfProjectId, dfLocationId, dfAgentId, requestId); // 使用流式detectIntent替代普通方法 const stream = dialogflowClient.streamingDetectIntent(); // 发送初始请求,开启流式会话 stream.write({ session: sessionPath, queryInput: { text: { text: userMessage, }, languageCode, }, enablePartialResponse: true, }); // 监听流式响应数据 stream.on('data', async (response) => { const responseMessages = response.queryResult?.responseMessages; if (responseMessages && responseMessages.length > 0) { for (const responseMessage of responseMessages) { const texts = responseMessage.text?.text; if (texts && texts.length > 0) { for (const text of texts) { console.log(`发送部分响应: ${text}`); await tdClient.sendMessage({ text }); // 可根据需求调整消息间隔 await new Promise(resolve => setTimeout(resolve, 1500)); } } } } }); // 监听流结束事件 await new Promise((resolve, reject) => { stream.on('end', resolve); stream.on('error', reject); }); } finally { if (dialogflowClient) { await dialogflowPool.release(dialogflowClient); } } } functions.http('helloHttp', async (req, res) => { const tdClient = new TiledeskChatbotClient({ request: req, APIKEY: '__APIKEY__', }); const userMessage = tdClient.text; const requestId = tdClient.requestId; await detectIntentText(userMessage, requestId, dfLanguageCode, tdClient); res.status(200).send({ success: true }); })
关键修改说明
- 替换为流式API:使用
streamingDetectIntent替代detectIntent,该方法会在Dialogflow生成部分响应时立即推送,而非等待全部处理完成。 - 实时处理响应:通过
stream.on('data')监听实时返回的部分响应,收到消息后立即调用tdClient.sendMessage推送给用户。 - 保留连接池:继续使用连接池管理Dialogflow客户端,保证性能和资源复用。
- 消息间隔控制:保留
setTimeout实现消息间的延迟,避免一次性推送所有内容。
内容的提问来源于stack exchange,提问作者Johan1us
相关产品推荐
相关产品推荐

