你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

将 SharePoint 工具与代理 API 配合使用(预览版)

重要

本文中标记了“(预览版)”的项目目前为公共预览版。 此预览版未提供服务级别协议,不建议将其用于生产工作负载。 某些功能可能不受支持或者受限。 有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款

注释

  • 本文介绍 Foundry 智能体服务的 Microsoft SharePoint 工具。 有关使用和部署 SharePoint 网站的信息,请参阅 SharePoint 文档
  • 请参阅有关优化工具使用情况的 最佳做法

将代理与 Microsoft SharePoint 集成,安全地与专用文档聊天。 可以连接到 SharePoint 网站,例如 contoso.sharepoint.com/sites/policies,以便为您的代理提供该数据支持。 当用户发送查询时,代理将确定它是否应使用 SharePoint。 如果是这样,它将使用 SharePoint 工具发送查询。 该工具检查用户是否有Microsoft 365 Copilot 许可证,并使用托管标识检索他们有权访问的相关文档。 检索范围包括此 SharePoint 网站中的所有受支持文档。 最后,代理基于检索的信息生成响应。 通过使用身份直通(On-Behalf-Of)授权,此集成简化了在 SharePoint 中访问企业数据的过程,同时保持强大的安全性,确保适当的访问控制和企业级别的保护。 有关基础 Microsoft 365 Copilot API 集成的详细信息,请参阅 “工作原理 ”部分。

使用支持

Microsoft Foundry 支持 Python SDK C# SDK JavaScript SDK Java SDK REST API 基本代理设置 标准代理设置
✔️ ✔️ ✔️ ✔️ - ✔️ ✔️ ✔️

先决条件

  • 开发人员和最终用户必须拥有 Microsoft 365 Copilot 许可证,以符合 Microsoft 365 Copilot API 的要求。
  • 开发人员和最终用户在 Foundry 项目中至少分配了Azure AI User个 RBAC 角色。 有关 Azure 基于角色的访问控制的详细信息,请参阅 Foundry 中的 Azure 基于角色的访问控制
  • 开发人员和最终用户至少有READ访问该 SharePoint 网站的权限。
  • 已安装的最新预发行版包:
    • Pythonpip install azure-ai-projects --pre
    • C#:安装 Azure.AI.Projects NuGet 包(预发行版)
    • TypeScript/JavaScriptnpm install @azure/ai-projects
  • 配置的环境变量:
    • AZURE_AI_PROJECT_ENDPOINT:Foundry 项目终结点 URL
    • AZURE_AI_MODEL_DEPLOYMENT_NAME:模型部署名称(例如 gpt-4
    • SHAREPOINT_PROJECT_CONNECTION_ID:您的 SharePoint 连接 ID 的格式为 /subscriptions/{{subscriptionID}}/resourceGroups/{{resourceGroupName}}/providers/Microsoft.CognitiveServices/accounts/{{foundryAccountName}}/projects/{{foundryProjectName}}/connections/{{foundryConnectionName}}
  • 有关其他身份验证设置详细信息,请参阅 快速入门

代码示例

将代理与 SharePoint 配合使用的示例

以下示例演示如何创建一个代理,该代理使用 SharePoint 工具基于 SharePoint 网站中的内容进行响应。

import os
from dotenv import load_dotenv
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import (
    PromptAgentDefinition,
    SharepointAgentTool,
    SharepointGroundingToolParameters,
    ToolProjectConnection,
)

load_dotenv()

project_client = AIProjectClient(
    endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
    credential=DefaultAzureCredential(),
)

# Get the OpenAI client for responses and conversations
openai_client = project_client.get_openai_client()

sharepoint_tool = SharepointAgentTool(
    sharepoint_grounding_preview=SharepointGroundingToolParameters(
        project_connections=[
            ToolProjectConnection(project_connection_id=os.environ["SHAREPOINT_PROJECT_CONNECTION_ID"])
        ]
    )
)

with project_client:
    agent = project_client.agents.create_version(
        agent_name="MyAgent",
        definition=PromptAgentDefinition(
            model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
            instructions="""You are a helpful agent that can use SharePoint tools to assist users. 
            Use the available SharePoint tools to answer questions and perform tasks.""",
            tools=[sharepoint_tool],
        ),
    )
    print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})")

    # Send initial request that will trigger the SharePoint tool
    stream_response = openai_client.responses.create(
        stream=True,
        input="Please summarize the last meeting notes stored in SharePoint.",
        extra_body={"agent": {"name": agent.name, "type": "agent_reference"}},
    )

    for event in stream_response:
        if event.type == "response.created":
            print(f"Follow-up response created with ID: {event.response.id}")
        elif event.type == "response.output_text.delta":
            print(f"Delta: {event.delta}")
        elif event.type == "response.text.done":
            print(f"\nFollow-up response done!")
        elif event.type == "response.output_item.done":
            if event.item.type == "message":
                item = event.item
                if item.content[-1].type == "output_text":
                    text_content = item.content[-1]
                    for annotation in text_content.annotations:
                        if annotation.type == "url_citation":
                            print(
                                f"URL Citation: {annotation.url}, "
                                f"Start index: {annotation.start_index}, "
                                f"End index: {annotation.end_index}"
                            )
        elif event.type == "response.completed":
            print(f"\nFollow-up completed!")
            print(f"Full response: {event.response.output_text}")

此代码的作用

此示例创建一个具有 SharePoint 基础功能的代理并处理流响应:

  1. 使用 Foundry 项目终结点和 Azure 凭据初始化项目客户端
  2. 使用项目连接配置 SharePoint 工具,以启用对 SharePoint 内容的访问。
  3. 使用说明和附加的 SharePoint 工具创建代理
  4. 发送一个查询 ,要求代理汇总来自 SharePoint 的会议笔记。
  5. 处理流式处理响应 以实时显示代理的答案。
  6. 从注释中提取 URL 链接,以显示引用了哪些 SharePoint 文档。

预期输出

运行此代码时,会看到如下所示的输出:

Agent created (id: asst_abc123, name: MyAgent, version: 1)

Sending request to SharePoint agent with streaming...
Follow-up response created with ID: resp_xyz789
Delta: Based
Delta:  on
Delta:  the
Delta:  meeting
Delta:  notes
...
URL Citation: https://contoso.sharepoint.com/sites/policies/Documents/meeting-notes.docx, Start index: 0, End index: 245

Follow-up response done!

Follow-up completed!
Full response: Based on the meeting notes from your SharePoint site, the last meeting covered the following topics: project timeline updates, budget review, and next quarter planning.

将代理与 SharePoint 配合使用的示例

以下示例演示如何创建一个代理,该代理使用 SharePoint 工具将 SharePoint 网站中的内容作为响应的基础。 此示例使用同步方法为简单起见。 有关异步版本,请参阅 Azure SDK for .NET GitHub 存储库上的 SharePoint 代理示例文档

若要使代理能够访问 SharePoint,请使用 SharepointAgentTool

using System;
using Azure.AI.Projects;
using Azure.AI.Projects.OpenAI;
using Azure.Identity;

// Create an agent client and read the environment variables, which will be used in the next steps.
var projectEndpoint = System.Environment.GetEnvironmentVariable("PROJECT_ENDPOINT");
var modelDeploymentName = System.Environment.GetEnvironmentVariable("MODEL_DEPLOYMENT_NAME");
var sharepointConnectionName = System.Environment.GetEnvironmentVariable("SHAREPOINT_CONNECTION_NAME");
AIProjectClient projectClient = new(endpoint: new Uri(projectEndpoint), tokenProvider: new DefaultAzureCredential());

// Use the SharePoint connection name as it's shown in the connections section of Microsoft Foundry to get the connection.
// Get the connection ID to initialize the SharePointGroundingToolOptions,
// which will be used to create SharepointAgentTool. Use this tool to create an Agent.
AIProjectConnection sharepointConnection = projectClient.Connections.GetConnection(sharepointConnectionName);
SharePointGroundingToolOptions sharepointToolOption = new()
{
    ProjectConnections = { new ToolProjectConnection(projectConnectionId: sharepointConnection.Id) }
};
PromptAgentDefinition agentDefinition = new(model: modelDeploymentName)
{
    Instructions = "You are a helpful assistant.",
    Tools = { new SharepointAgentTool(sharepointToolOption), }
};
AgentVersion agentVersion = projectClient.Agents.CreateAgentVersion(
    agentName: "myAgent",
    options: new(agentDefinition));

// Create the response and make sure we are always using tool.
ProjectResponsesClient responseClient = projectClient.OpenAI.GetProjectResponsesClientForAgent(agentVersion.Name);
ResponseCreationOptions responseOptions = new()
{
    ToolChoice = ResponseToolChoice.CreateRequiredChoice()
};
OpenAIResponse response = responseClient.CreateResponse("What is Contoso whistleblower policy", options: responseOptions);

// SharePoint tool can create the reference to the page, grounding the data.
// Create the GetFormattedAnnotation method to get the URI annotation.
private static string GetFormattedAnnotation(OpenAIResponse response)
{
    foreach (ResponseItem item in response.OutputItems)
    {
        if (item is MessageResponseItem messageItem)
        {
            foreach (ResponseContentPart content in messageItem.Content)
            {
                foreach (ResponseMessageAnnotation annotation in content.OutputTextAnnotations)
                {
                    if (annotation is UriCitationMessageAnnotation uriAnnotation)
                    {
                        return $" [{uriAnnotation.Title}]({uriAnnotation.Uri})";
                    }
                }
            }
        }
    }
    return "";
}

// Print the Agent output and add the annotation at the end.
Assert.That(response.Status, Is.EqualTo(ResponseStatus.Completed));
Console.WriteLine($"{response.GetOutputText()}{GetFormattedAnnotation(response)}");

// After the sample is completed, delete the Agent we have created.
projectClient.Agents.DeleteAgentVersion(agentName: agentVersion.Name, agentVersion: agentVersion.Version);

此代码的作用

此示例演示了使用同步方法的 SharePoint 基础配置:

  1. 使用您的 Foundry 项目终结点创建项目客户端
  2. 根据名称从项目的连接中检索 SharePoint 连接
  3. 使用连接 ID 配置 SharePoint 工具
  4. 使用 SharePoint 工具创建代理以启用文档访问
  5. 创建一个响应,询问 Contoso 的举报人政策
  6. 使用帮助程序方法格式化和显示响应,该方法从批注中提取 URL 引文
  7. 通过删除代理版本进行清理

预期输出

运行此代码时,会看到如下所示的输出:

The Contoso whistleblower policy outlines procedures for reporting unethical behavior confidentially. Employees can submit concerns through the ethics hotline or online portal. [Whistleblower Policy](https://contoso.sharepoint.com/sites/policies/Documents/whistleblower-policy.pdf)

输出包括基于 SharePoint 内容的代理响应,以及指向源文档的引文链接。

将代理与 SharePoint 配合使用的示例

以下示例演示如何创建一个代理,该代理使用 SharePoint 工具以 SharePoint 网站的内容为基础生成响应。

curl --request POST \
  --url "$AZURE_AI_FOUNDRY_PROJECT_ENDPOINT/openai/responses?api-version=$API_VERSION" \
  --H "Authorization: Bearer $AGENT_TOKEN" \
  --H "Content-Type: application/json" \
  --H "User-Agent: insomnia/11.6.1" \
  --d '{
"model": "$AZURE_AI_MODEL_DEPLOYMENT_NAME",
"input": "Please summarize the last meeting notes stored in SharePoint.",
"tools": [
    {
        "type": "sharepoint_grounding_preview",
        "sharepoint_grounding_preview": {
            "project_connections": [
                {
                    "project_connection_id": "$SHAREPOINT_PROJECT_CONNECTION_ID"
                }
        ]
    }
    }
    ]
}'

此代码的作用

此 REST API 调用以 SharePoint 集成为基础创建响应:

  1. 将 POST 请求发送到/openai/responses终结点
  2. 使用代理的持有者令牌进行身份验证
  3. 指定要用于生成响应的模型部署
  4. 包括用户请求从 SharePoint 获取会议笔记的查询
  5. 使用项目连接 ID 配置 SharePoint 工具以启用文档检索
  6. 返回一个 JSON 响应 ,其中包含代理的答案和对源文档的引文

预期输出

API 返回 JSON 响应,其中包含代理的答案和引文信息:

{
  "id": "resp_abc123xyz",
  "object": "response",
  "created_at": 1702345678,
  "status": "completed",
  "output_text": "Based on the meeting notes from your SharePoint site, the last meeting covered project timeline updates, budget review, and next quarter planning.",
  "output_items": [
    {
      "type": "message",
      "content": [
        {
          "type": "output_text",
          "text": "Based on the meeting notes...",
          "annotations": [
            {
              "type": "url_citation",
              "url": "https://contoso.sharepoint.com/sites/policies/Documents/meeting-notes.docx",
              "start_index": 0,
              "end_index": 245
            }
          ]
        }
      ]
    }
  ]
}

将代理与 SharePoint 配合使用的示例

此示例演示如何使用 SharepointAgentTool 和同步 Azure AI Projects 客户端创建具有 SharePoint 功能的 AI 代理。 代理可以搜索 SharePoint 内容,并提供来自 SharePoint 网站的相关信息的响应。 有关此示例的 JavaScript 版本,请参阅 Azure SDK for JavaScript GitHub 存储库中的 SharePoint 代理示例文档

import { DefaultAzureCredential } from "@azure/identity";
import { AIProjectClient } from "@azure/ai-projects";
import "dotenv/config";

const projectEndpoint = process.env["AZURE_AI_PROJECT_ENDPOINT"] || "<project endpoint>";
const deploymentName = process.env["MODEL_DEPLOYMENT_NAME"] || "<model deployment name>";
const sharepointProjectConnectionId =
  process.env["SHAREPOINT_PROJECT_CONNECTION_ID"] || "<sharepoint project connection id>";

export async function main(): Promise<void> {
  const project = new AIProjectClient(projectEndpoint, new DefaultAzureCredential());
  const openAIClient = await project.getOpenAIClient();

  console.log("Creating agent with SharePoint tool...");

  const agent = await project.agents.createVersion("MyAgent", {
    kind: "prompt",
    model: deploymentName,
    instructions:
      "You are a helpful agent that can use SharePoint tools to assist users. Use the available SharePoint tools to answer questions and perform tasks.",
    // Define SharePoint tool that searches SharePoint content
    tools: [
      {
        type: "sharepoint_grounding_preview",
        sharepoint_grounding_preview: {
          project_connections: [
            {
              project_connection_id: sharepointProjectConnectionId,
            },
          ],
        },
      },
    ],
  });
  console.log(`Agent created (id: ${agent.id}, name: ${agent.name}, version: ${agent.version})`);

  // Send initial request that will trigger the SharePoint tool
  console.log("\nSending request to SharePoint agent with streaming...");
  const streamResponse = await openAIClient.responses.create(
    {
      input: "Please summarize the last meeting notes stored in SharePoint.",
      stream: true,
    },
    {
      body: {
        agent: { name: agent.name, type: "agent_reference" },
      },
    },
  );

  // Process the streaming response
  for await (const event of streamResponse) {
    if (event.type === "response.created") {
      console.log(`Follow-up response created with ID: ${event.response.id}`);
    } else if (event.type === "response.output_text.delta") {
      process.stdout.write(event.delta);
    } else if (event.type === "response.output_text.done") {
      console.log("\n\nFollow-up response done!");
    } else if (event.type === "response.output_item.done") {
      if (event.item.type === "message") {
        const item = event.item;
        if (item.content && item.content.length > 0) {
          const lastContent = item.content[item.content.length - 1];
          if (lastContent.type === "output_text" && lastContent.annotations) {
            for (const annotation of lastContent.annotations) {
              if (annotation.type === "url_citation") {
                console.log(
                  `URL Citation: ${annotation.url}, Start index: ${annotation.start_index}, End index: ${annotation.end_index}`,
                );
              }
            }
          }
        }
      }
    } else if (event.type === "response.completed") {
      console.log("\nFollow-up completed!");
    }
  }

  // Clean up resources by deleting the agent version
  // This prevents accumulation of unused resources in your project
  console.log("\nCleaning up resources...");
  await project.agents.deleteVersion(agent.name, agent.version);
  console.log("Agent deleted");

  console.log("\nSharePoint agent sample completed!");
}

main().catch((err) => {
  console.error("The sample encountered an error:", err);
});

此代码的作用

此 TypeScript 示例演示 SharePoint 的完整代理生命周期:

  1. 使用 Foundry 终端节点和 Azure 凭据初始化项目客户端
  2. 获取 OpenAI 客户端 以创建响应。
  3. 使用项目连接 ID 创建具有 SharePoint 工具配置的代理。
  4. 发送流式处理请求 ,要求代理汇总会议笔记。
  5. 处理流式处理事件 ,以在生成响应时显示响应。
  6. 从响应注释中提取和显示 URL 引文
  7. 完成后,通过删除代理版本来清理资源

预期输出

运行此代码时,会看到如下所示的输出:

Creating agent with SharePoint tool...
Agent created (id: asst_abc123, name: MyAgent, version: 1)

Sending request to SharePoint agent with streaming...
Follow-up response created with ID: resp_xyz789
Based on the meeting notes from your SharePoint site, the last meeting covered the following topics: project timeline updates, budget review, and next quarter planning.

Follow-up response done!
URL Citation: https://contoso.sharepoint.com/sites/policies/Documents/meeting-notes.docx, Start index: 0, End index: 245

Follow-up completed!

Cleaning up resources...
Agent deleted

SharePoint agent sample completed!

设置

注释

  • 支持的文档类型:以下格式的文本数据:.pdf、、.docx.ppt.txt.aspx
  • 从具有简单文件夹结构和少量短文档的 SharePoint 网站开始。
  • SharePoint 工具仅支持用户标识身份验证。 它不支持服务主体名称(SPN)身份验证。
  • SharePoint 站点和 Microsoft Foundry 智能体需要位于同一租户中。
  1. 选择 SharePoint 并按照提示添加该工具。 每个代理只能添加一个。

  2. 选择添加新连接。 添加连接后,可以直接从现有列表中选择。

    1. 若要创建新连接,请在 site_url SharePoint 网站中找到。 您可以添加 SharePoint 网站或 SharePoint 文件夹。 对于 SharePoint 网站,其外观如下所示 https://microsoft.sharepoint.com/teams/<site_name>。 对于 SharePoint 文件夹,其外观如下所示 https://microsoft.sharepoint.com/teams/<site_name>/Shared%20documents/<folder_name>

      注释

      • 您的 site_url 需要遵循上述格式。 如果从 SharePoint 的地址栏中复制整个值,则它不起作用。
    2. 添加连接。 请确保选择 “机密 ”选项。

工作原理

通过 SharePoint 工具,可以在 AI 代理与 SharePoint 中存储的业务文档之间实现无缝集成。 此功能由 Microsoft 365 Copilot API 提供支持。 若要为 SharePoint 文档建立基础,请输入要连接的网站或文件夹。 SharePoint 工具利用 内置的索引功能 增强搜索和检索体验,包括智能索引、查询处理和内容分块。

此功能自动执行整个检索管道,而不是要求开发人员导出 SharePoint 内容、生成自定义语义索引、管理治理控件和配置刷新逻辑。 它动态索引文档、将内容分解为有意义的区块,并应用高级查询处理来显示最相关的信息。 通过使用支持智能 Microsoft 365 Copilot 副驾驶® 的相同企业级检索堆栈,确保 AI 智能体响应基于最新且上下文相关的内容。

客户依靠 SharePoint 中的数据安全性来访问、创建和共享具有灵活文档级访问控制的文档。 标识传递/“代表”(OBO)身份验证等企业功能可确保适当的访问控制。 最终用户会收到从他们有权访问的 SharePoint 文档生成的响应。 通过使用 OBO 身份验证,Foundry 代理服务使用最终用户的身份来授权和检索相关的 SharePoint 文档,从而生成针对特定最终用户定制的响应。

后续步骤