模型驱动应用与自定义Copilot聊天界面的上下文传递问题咨询
模型驱动应用自定义Copilot聊天的上下文传递与状态维持方案
一、上下文传递的核心实现方式
1. 低代码方案:使用Power Apps全局变量
在左窗格文件列表的OnSelect事件中,将选中文件的信息存入全局变量:
Set(gblSelectedFile, ThisItem); // 可选:同步更新聊天界面的上下文提示 UpdateContext({chatSystemPrompt: "当前选中文件:" & gblSelectedFile.Name & ",请基于该文件回答问题"});
在自定义聊天界面(如自定义页面或组件)中,直接读取gblSelectedFile变量,将其注入Copilot的系统提示词,实现上下文关联。
2. 代码方案:JavaScript监听网格选择事件(适用于Web资源聊天界面)
如果聊天界面是嵌入的HTML/JS Web资源,可通过模型驱动应用的客户端API监听文件网格的选择变化:
// 注册网格选择事件 function initGridListener() { const fileGrid = Xrm.Page.getControl("file_grid_control_name"); // 替换为你的网格控件名称 if (fileGrid) { fileGrid.addOnSelectionChange(handleFileSelection); } } // 处理选中事件,传递上下文到聊天界面 function handleFileSelection() { const selectedRows = Xrm.Page.getControl("file_grid_control_name").getSelectedRows(); if (selectedRows.length === 0) return; const selectedFile = selectedRows[0].getData(); const fileContext = { id: selectedFile.getId().replace(/[{}]/g, ""), name: selectedFile.getAttribute("filename").getValue(), // 替换为你的文件名属性逻辑名 description: selectedFile.getAttribute("description")?.getValue() || "" }; // 通过postMessage传递给聊天界面的iframe const chatIframe = document.getElementById("custom_chat_iframe"); // 替换为你的聊天iframe ID if (chatIframe) { chatIframe.contentWindow.postMessage({ type: "FILE_CONTEXT_UPDATED", data: fileContext }, "*"); } } // 在页面加载时初始化监听 document.addEventListener("DOMContentLoaded", initGridListener);
聊天界面的JS接收上下文并更新Copilot提示:
window.addEventListener("message", (event) => { if (event.data.type === "FILE_CONTEXT_UPDATED") { const fileCtx = event.data.data; // 更新Copilot的系统提示 const systemPrompt = `用户当前选中文件:${fileCtx.name}\n文件ID:${fileCtx.id}\n请仅基于该文件的内容回答问题`; document.getElementById("copilot_system_prompt").value = systemPrompt; // 可选:重置聊天历史,确保上下文生效 resetChatHistory(); } });
二、状态维持的最佳实践
- 优先使用内置全局变量/集合:对于模型驱动应用内的组件交互,
Set/UpdateContext创建的全局变量是最轻量化的状态管理方式,无需额外代码,适合低代码场景。 - 跨组件使用Xrm全局上下文:如果聊天界面是Web资源,用
Xrm.Utility.setGlobalContext存储状态,确保页面刷新或导航后状态不丢失:// 存储状态 Xrm.Utility.setGlobalContext("selectedFileContext", fileContext); // 读取状态 const savedContext = Xrm.Utility.getGlobalContext().get("selectedFileContext"); - 自定义页面参数传递:若聊天界面是自定义页面,打开时直接传递选中文件ID作为参数:
在自定义页面的Navigate(CustomChatPage, ScreenTransition.None, { SelectedFileID: gblSelectedFile.ID })OnVisible事件中加载文件详情:Set(gblCurrentFile, LookUp(Files, ID = SelectedFileID)) - 本地存储持久化:如需在浏览器会话间保留状态,可使用
localStorage:// 存储 localStorage.setItem("selectedFile", JSON.stringify(fileContext)); // 读取 const persistedFile = JSON.parse(localStorage.getItem("selectedFile"));
三、Copilot上下文注入示例(Power Apps + Azure OpenAI)
在聊天发送按钮的OnSelect事件中,动态注入选中文件的上下文到对话历史:
// 添加用户提问到历史 Collect(chatHistory, { role: "user", content: ChatInput.Text }); // 注入系统上下文提示 Collect(chatHistory, { role: "system", content: "当前用户关注的文件是:" & gblSelectedFile.Name & "\n文件内容摘要:" & gblSelectedFile.ContentSummary & "\n请基于该文件内容回答问题,不要提及其他无关文件" }); // 调用Azure OpenAI获取回复 Set(chatResponse, AzureOpenAI.ChatCompletion("gpt-35-turbo", chatHistory)); // 添加助手回复到历史 Collect(chatHistory, { role: "assistant", content: chatResponse.choices[0].message.content }); // 清空输入框 Set(ChatInput.Text, "");
内容的提问来源于stack exchange,提问作者Rohith Korupalli
相关产品推荐
相关产品推荐

