发布代理到实时或演示网站

将智能体发布到 Web 中时,可以发布到预生成的演示网站(可用于与队友和利益干系人共享智能体)。 您也可以发布到自己的活动网站。

小费

何时应该使用演示网站?何时应该使用我自己的网站?
演示网站仅应用于试用智能体和与要试用智能体的队友或其他利益干系人共享。 不应用于生产,例如,不应直接将其与客户使用。
应该在生产方案中在活动网站发布和使用智能体,如帮助网页上的帮助智能体用于与客户交互。

重要提示

本文包含 Microsoft Copilot Studio 预览版文档,有可能会有变动。

预览功能不适合生产使用且功能可能受限。 这些功能在正式发布之前已经可用,以便您可以及早使用并提供反馈

如果您在构建生产就绪型智能体,请参阅 Microsoft Copilot Studio 概述

当您发布智能体时,会自动为您创建一个预构建的演示网站。 您的团队成员和利益干系人可以在您构建智能体时使用演示网站来试用智能体。 您可能希望自定义演示站点以指导队友的测试工作。 准备好供客户使用时,将智能体发布到您的实时网站。

何时应该使用演示网站?何时应该使用您自己的网站?

演示网站仅应用于试用智能体和与要试用智能体的队友或其他利益干系人共享。它不适用于生产用途。 您不应将 URL 提供给客户。 在您的实时网站上发布智能体供客户使用。

自定义演示网站

根据需要经常编辑演示网站的欢迎消息和触发短语。 欢迎消息可以解释测试的目的,并提示您的团队成员向智能体询问什么。

  1. 打开智能体,在顶部菜单栏选择设置

  2. 在侧导航面板中,选择“ 安全性”。

  3. 选择身份验证,然后选择无身份验证,然后选择保存

  4. 退出设置,并在顶部菜单栏上选择渠道

  5. 渠道下,选择演示网站

  6. “演示网站 ”面板的 “欢迎消息”下,输入希望团队成员看到的消息。

  7. 对话开场白下面,输入触发短语列表。

    触发短语用于启动特定主题,因此您可以针对希望队友测试的主题输入触发短语。

  8. 选择保存

  9. 复制演示网站 URL 并与您的队友共享。

将智能体添加到网站

当您的智能体准备好迎接客户时,将其作为 iframe 代码片段添加到您的网站。 您的活动网站可以是外部或内部网站,如 SharePoint 站点。 您还可以将智能体添加到 Power Platform 管理中心。

  1. 复制以下 HTML 代码并将其保存到名为 index.html 的文件。 将代码复制并粘贴到 w3schools.com HTML 尝试编辑器中。

    
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <meta name="description" content="Contoso Web Chat Assistant" />
      <title>Contoso Sample Web Chat Test</title>
      <script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
      <script>
        let webChatInstance = null;
        let directLineUrl = null;
    
        // Replace with your token endpoint
        const tokenEndpoint = "<YOUR TOKEN ENDPOINT>";
        const styleOptions = {"accent":"#0078D4","autoScrollSnapOnPage":true,"autoScrollSnapOnPageOffset":0,"avatarBorderRadius":"7%","avatarSize":31,"backgroundColor":"#e8e9eb","botAvatarBackgroundColor":"#ffffff00","botAvatarImage":"https://powercatexternal.blob.core.windows.net/creatorkit/Assets/ChatbotLogoBlue.png","botAvatarInitials":"B","bubbleAttachmentMaxWidth":480,"bubbleAttachmentMinWidth":250,"bubbleBackground":"#f0eded","bubbleBorderColor":"#f5f5f5","bubbleBorderRadius":41,"bubbleBorderStyle":"solid","bubbleBorderWidth":1,"bubbleFromUserBackground":"#ebefff","bubbleFromUserBorderColor":"#f5f5f5","bubbleFromUserBorderRadius":41,"bubbleFromUserBorderStyle":"solid","bubbleFromUserBorderWidth":1,"bubbleFromUserNubOffset":0,"bubbleFromUserNubSize":0,"bubbleFromUserTextColor":"#242424","bubbleImageHeight":10,"bubbleImageMaxHeight":240,"bubbleImageMinHeight":240,"bubbleMessageMaxWidth":480,"bubbleMessageMinWidth":120,"bubbleMinHeight":50,"bubbleNubOffset":0,"bubbleTextColor":"#242424","emojiSet":true,"fontSizeSmall":"70%","hideUploadButton":false,"messageActivityWordBreak":"break-word","monospaceFont":"Consolas","paddingRegular":10,"paddingWide":10,"primaryFont":null,"sendBoxBackground":"#e8e9eb","sendBoxBorderTop":"solid 1px #808080","sendBoxButtonColor":"#0078d4","sendBoxButtonColorOnHover":"#006cbe","sendBoxButtonShadeBorderRadius":40,"sendBoxButtonShadeColorOnHover":"","sendBoxHeight":60,"sendBoxPlaceholderColor":"#171616","sendBoxTextColor":"#2e2d2d","showAvatarInGroup":"status","spinnerAnimationHeight":16,"spinnerAnimationPadding":12,"spinnerAnimationWidth":16,"subtleColor":"#000000FF","suggestedActionBackgroundColor":"#006FC4FF","suggestedActionBackgroundColorOnHover":"#0078D4","suggestedActionBorderColor":"","suggestedActionBorderRadius":10,"suggestedActionBorderWidth":1,"suggestedActionLayout":"flow","suggestedActionTextColor":"#FFFFFFFF","typingAnimationBackgroundImage":"url('https://wpamelia.com/wp-content/uploads/2018/11/ezgif-2-6d0b072c3d3f.gif')","typingAnimationDuration":5000,"typingAnimationHeight":20,"typingAnimationWidth":64,"userAvatarBackgroundColor":"#222222","userAvatarImage":"https://avatars.githubusercontent.com/u/8174072?v=4&size=64","userAvatarInitials":"U"};
        const backgroundImage = "";
        document.addEventListener('DOMContentLoaded', () => {
          const root = document.documentElement;
          root.style.setProperty('--primary-color', createGradient(styleOptions.accent));
          root.style.setProperty('--header-textColor', styleOptions.suggestedActionTextColor);
          if (backgroundImage) {
            const webchatElement = document.getElementById('webchat');
            webchatElement.style.backgroundImage = `url(${backgroundImage})`;
            webchatElement.style.backgroundSize = 'cover';
            webchatElement.style.backgroundPosition = 'center';
            webchatElement.style.backgroundRepeat = 'no-repeat';
            const overlay = document.createElement('div');
            overlay.className = 'webchat-overlay';
            webchatElement.appendChild(overlay);
          }
        });
        function createGradient(baseColor) {
          const r = parseInt(baseColor.slice(1,3), 16);
          const g = parseInt(baseColor.slice(3,5), 16);
          const b = parseInt(baseColor.slice(5,7), 16);
          const lighterColor = `#${Math.min(255, r+30).toString(16).padStart(2,'0')}${Math.min(255, g+30).toString(16).padStart(2,'0')}${Math.min(255, b+30).toString(16).padStart(2,'0')}`;
          const darkerColor = `#${Math.max(0, r-30).toString(16).padStart(2,'0')}${Math.max(0, g-30).toString(16).padStart(2,'0')}${Math.max(0, b-30).toString(16).padStart(2,'0')}`;
          return `linear-gradient(135deg, ${lighterColor}, ${baseColor}, ${darkerColor})`;
        }
        const environmentEndPoint = tokenEndpoint.slice(
          0,
          tokenEndpoint.indexOf("/powervirtualagents")
        );
        const apiVersion = tokenEndpoint
          .slice(tokenEndpoint.indexOf("api-version"))
          .split("=")[1];
        const regionalChannelSettingsURL = `${environmentEndPoint}/powervirtualagents/regionalchannelsettings?api-version=${apiVersion}`;
        function showChat() {
          const popup = document.getElementById("chatbot-popup");
          const openButton = document.getElementById("open-chat");
          popup.classList.add("visible");
          openButton.classList.add("hidden");
        }
        function hideChat() {
          const popup = document.getElementById("chatbot-popup");
          const openButton = document.getElementById("open-chat");
          popup.classList.remove("visible");
          openButton.classList.remove("hidden");
        }
        function createCustomStore() {
          return window.WebChat.createStore(
            {},
            ({ dispatch }) =>
              (next) =>
              (action) => {
                if (action.type === "DIRECT_LINE/CONNECT_FULFILLED") {
                  dispatch({
                    type: "DIRECT_LINE/POST_ACTIVITY",
                    meta: { method: "keyboard" },
                    payload: {
                      activity: {
                        channelData: { postBack: true },
                        name: "startConversation",
                        type: "event",
                      },
                    },
                  });
                }
                return next(action);
              }
          );
        }
        async function restartConversation() {
          try {
            if (!directLineUrl) {
              console.error("DirectLine URL not initialized");
              return;
            }
            const response = await fetch(tokenEndpoint);
            const conversationInfo = await response.json();
            if (!conversationInfo.token) {
              throw new Error("Failed to get conversation token");
            }
            const newDirectLine = window.WebChat.createDirectLine({
              domain: `${directLineUrl}v3/directline`,
              token: conversationInfo.token,
            });
            const webchatElement = document.getElementById("webchat");
            webChatInstance = window.WebChat.renderWebChat(
              {
                directLine: newDirectLine,
                styleOptions,
                store: createCustomStore(),
              },
              webchatElement
            );
          } catch (err) {
            console.error("Failed to restart conversation:", err);
          }
        }
        async function initializeChat() {
          try {
            const response = await fetch(regionalChannelSettingsURL);
            const data = await response.json();
            directLineUrl = data.channelUrlsById.directline;
            if (!directLineUrl) {
              throw new Error("Failed to get DirectLine URL");
            }
            const conversationResponse = await fetch(tokenEndpoint);
            const conversationInfo = await conversationResponse.json();
            if (!conversationInfo.token) {
              throw new Error("Failed to get conversation token");
            }
            const directLine = window.WebChat.createDirectLine({
              domain: `${directLineUrl}v3/directline`,
              token: conversationInfo.token,
            });
            webChatInstance = window.WebChat.renderWebChat(
              {
                directLine,
                styleOptions,
                store: createCustomStore(),
              },
              document.getElementById("webchat")
            );
          } catch (err) {
            console.error("Failed to initialize chat:", err);
          }
        }
        initializeChat();
      </script>
      <style>
        :root {
          --primary-gradient: var(--primary-color);
          --chat-width: 450px;
          --chat-height: 520px;
          --header-height: 56px;
          --border-radius: 16px;
          --transition-speed: 0.3s;
        }
        * {
          margin: 0;
          padding: 0;
          box-sizing: border-box;
          font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
            Roboto, sans-serif;
        }
        body {
          min-height: 100vh;
          background-color: #f3f4f6;
        }
        #chatbot-popup {
          display: none;
          position: fixed;
          bottom: 32px;
          right: 32px;
          width: var(--chat-width);
          height: var(--chat-height);
          background: white;
          border-radius: var(--border-radius);
          box-shadow: 0 18px 40px -5px rgba(0, 0, 0, 0.2),
            0 15px 20px -5px rgba(0, 0, 0, 0.1);
          overflow: hidden;
          opacity: 0;
          transform-origin: bottom right;
          transform: scale(0.95);
          transition: all var(--transition-speed) ease-in-out;
          z-index: 999;
        }
        #chatbot-popup.visible {
          display: block;
          opacity: 1;
          transform: scale(1);
        }
        #chatbot-header {
          background: var(--primary-color);
          padding: 16px 20px;
          height: var(--header-height);
          display: flex;
          justify-content: space-between;
          align-items: center;
          color: var(--header-textColor);
        }
        .header-title {
          display: flex;
          align-items: center;
          gap: 12px;
          font-size: 16px;
          font-weight: 500;
        }
        .header-buttons {
          display: flex;
          gap: 12px;
          align-items: center;
        }
        .icon-button {
          background: none;
          border: none;
          color: var(--header-textColor);
          cursor: pointer;
          padding: 8px;
          border-radius: 8px;
          display: flex;
          align-items: center;
          justify-content: center;
          transition: all 0.2s ease;
        }
        .icon-button:hover {
          color: var(--header-textColor);
          background: rgba(255, 255, 255, 0.1);
        }
        .icon-button:focus {
          outline: 2px solid rgba(255, 255, 255, 0.5);
          outline-offset: 2px;
        }
        #webchat {
          height: calc(100% - var(--header-height));
          background-color: #f9fafb;
          position: relative;
        }
        .webchat-overlay {
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          background: rgba(255, 255, 255, 0.85);
          pointer-events: none;
          z-index: 1;
        }
        #webchat > div {
          position: relative;
          z-index: 2;
        }
        #webchat .webchat__basic-transcript__content {
          white-space: pre-wrap !important;
          word-break: break-word !important;
        }
        #webchat .webchat__bubble__content {
          padding: 8px 12px !important;
        }
        #webchat .webchat__bubble {
          max-width: 85% !important;
          margin: 8px !important;
        }
        #webchat .webchat__basic-transcript__content ul,
        #webchat .webchat__basic-transcript__content ol,
        #webchat .webchat__bubble__content ul,
        #webchat .webchat__bubble__content ol {
          padding-left: 24px !important;
          margin: 8px 0 !important;
          list-style-position: outside !important;
        }
        #webchat .webchat__basic-transcript__content li,
        #webchat .webchat__bubble__content li {
          margin: 4px 0 !important;
          padding-left: 4px !important;
        }
        #open-chat {
          position: fixed;
          bottom: 32px;
          right: 32px;
          width: 64px;
          height: 64px;
          border-radius: 50%;
          background: var(--primary-gradient);
          border: none;
          cursor: pointer;
          display: flex;
          align-items: center;
          justify-content: center;
          box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
          transition: all var(--transition-speed) ease-in-out;
          z-index: 998;
        }
        #open-chat.hidden {
          opacity: 0;
          transform: scale(0.95) translateY(10px);
          pointer-events: none;
        }
        #open-chat:hover {
          transform: translateY(-4px);
          box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
        }
        #open-chat:focus {
          outline: 3px solid rgba(79, 70, 229, 0.5);
          outline-offset: 2px;
        }
        #open-chat svg {
          width: 28px;
          height: 28px;
          color: white;
          transition: transform 0.2s ease;
        }
        .main-content {
          max-width: 1200px;
          margin: 0 auto;
          padding: 48px 24px;
        }
        .main-content h1 {
          font-size: 36px;
          color: #111827;
          text-align: center;
        }
        .main-content p {
          font-size: 18px;
          color: #4b5563;
          line-height: 1.6;
          margin-bottom: 48px;
          text-align: center;
          max-width: 800px;
          margin-left: auto;
          margin-right: auto;
        }
        .content-grid {
          display: grid;
          grid-template-columns: repeat(2, 1fr);
          gap: 32px;
          margin-bottom: 32px;
        }
        .content-box {
          background: linear-gradient(135deg, #e6e6e6, #c4c4c4, #9f9f9f);
          padding: 32px;
          border-radius: 12px;
          box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
                      0 2px 4px -1px rgba(0, 0, 0, 0.06);
          min-height: 300px;
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          text-align: center;
          position: relative;
          overflow: hidden;
        }
        .content-box::before {
          content: '';
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          height: 4px;
        }
        .content-box.featured {
          grid-column: span 2;
          min-height: 350px;
          background: linear-gradient(135deg, #e6e6e6, #c4c4c4, #9f9f9f);
          color: #000000;
        }
        .content-box h2 {
          font-size: 24px;
          margin-bottom: 16px;
          position: relative;
        }
        .content-box p {
          font-size: 16px;
          color: #6b7280;
          margin-bottom: 0;
        }
        .content-box.featured p {
          color: #000000;
        }
        @media (max-width: 768px) {
          .content-grid {
            grid-template-columns: 1fr;
          }
          .content-box.featured {
            grid-column: span 1;
          }
          .main-content {
            padding: 24px 16px;
          }
          .main-content h1 {
            font-size: 28px;
          }
          #chatbot-popup {
            width: 100%;
            height: 100%;
            bottom: 0;
            right: 0;
            border-radius: 0;
          }
        }
      </style>
    </head>
    <body>
      <div class="main-content">
        <h1>Header</h1>
        <p>Lorem ipsum dolor sit amet consectetur adipiscing elit. Quisque faucibus ex sapien vitae pellentesque sem placerat.</p>
        <div class="content-grid">
          <div class="content-box featured">
            <h2>Featured Content</h2>
            <p>Primary content area with custom styling and gradient background</p>
          </div>
          <div class="content-box">
            <h2>Section One</h2>
            <p>Content box with minimal design</p>
          </div>
          <div class="content-box">
            <h2>Section Two</h2>
            <p>Another content section with consistent styling</p>
          </div>
        </div>
      </div>
      <div id="chatbot-popup" role="complementary" aria-label="Chat Assistant">
        <div id="chatbot-header">
          <div class="header-title">
            <svg
              class="chat-icon"
              width="24"
              height="24"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
              stroke-linecap="round"
              stroke-linejoin="round"
              aria-hidden="true"
            >
              <path
                d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
              ></path>
            </svg>
            <span>Contoso Assistant</span>
          </div>
          <div class="header-buttons">
            <button
              class="icon-button"
              id="restart-button"
              onclick="restartConversation()"
              aria-label="Restart Conversation"
            >
              <svg
                width="20"
                height="20"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                stroke-linecap="round"
                stroke-linejoin="round"
                aria-hidden="true"
              >
                <path
                  d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"
                ></path>
                <path d="M3 3v5h5"></path>
              </svg>
            </button>
            <button
              class="icon-button"
              id="close-button"
              onclick="hideChat()"
              aria-label="Close Chat"
            >
              <svg
                width="20"
                height="20"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                stroke-width="2"
                stroke-linecap="round"
                stroke-linejoin="round"
                aria-hidden="true"
              >
                <line x1="18" y1="6" x2="6" y2="18"></line>
                <line x1="6" y1="6" x2="18" y2="18"></line>
              </svg>
            </button>
          </div>
        </div>
        <div id="webchat" role="main"></div>
      </div>
      <button
        id="open-chat"
        onclick="showChat()"
        aria-label="Open Chat Assistant"
      >
        <svg
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          stroke-linecap="round"
          stroke-linejoin="round"
          aria-hidden="true"
        >
          <path
            d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"
          ></path>
        </svg>
      </button>
    </body>
    </html>
    
    
  2. 检索代理的令牌终结点

  3. index.html 中,在第 const tokenEndpoint = "<YOUR TOKEN ENDPOINT>"; 行,用您的智能体的令牌端点替换占位符。

  4. 使用新式浏览器(例如,Microsoft Edge)打开 index.html ,以在自定义画布中打开代理。

  5. 测试代理,以确保收到来自它的响应,并且它正常工作。

  6. 向 Web 开发人员提供代码片段(index.html)以将代理添加到网站。