使用 Azure Functions 结合 OAuth 和 Microsoft Graph API 从 ChatGPT 搜索 O365 / SharePoint
概述
本解决方案使 GPT 动作能够根据用户在 SharePoint 或 Office365 中可访问的文件内容回答用户的问题,利用 Microsoft Graph API 的搜索功能和检索文件的能力。它使用 Azure Functions 处理 Graph API 响应并将其转换为人类可读格式或以 ChatGPT 理解的方式结构化。此代码旨在提供方向性指导,您应根据需求进行修改。
工作原理
以下提供了两种解决方案,每种方案在仓库中都有相应的代码。
第一种解决方案 解决方案 1 利用在动作中检索 文件的能力,并将其用作直接上传到对话中的文件。Azure Function 返回一个 base64 字符串,ChatGPT 将其转换为文件,处理方式与直接上传到对话中的文件相同。此解决方案可以处理比下面其他解决方案更多的文件类型,但存在大小限制(参见文档)。
第二种解决方案 解决方案 2 在 Azure Function 中预处理文件。Azure Function 返回文本,而不是 base64 编码的文件。由于预处理和转换为文本,此解决方案最适合用于大型非结构化文档,以及当您希望分析超过第一种解决方案支持的文件数量时(参见文档)。
解决方案 1:使用返回文件模式将文件返回给 GPT
此解决方案使用 Node.js Azure Function,根据登录用户:
- 根据用户的初始问题搜索用户有权访问的相关文件。
- 对于找到的每个文件,将其转换为 base64 字符串。
- 以 ChatGPT 期望的结构格式化数据(参见此处)。
- 将数据返回给 ChatGPT。GPT 随后可以将这些文件用作直接上传到对话中的文件。
解决方案 2:在 Azure Function 中将文件转换为文本
此解决方案使用 Node.js Azure Function,根据登录用户:
- 根据用户的初始问题搜索用户有权访问的相关文件。
- 对于找到的每个文件,将其转换为一致的可读格式并提取所有文本。
- 使用 GPT 3.5-turbo(gpt-3.5-turbo-0125)根据用户的初始问题从文件中提取相关文本。注意 GPT 3.5 turbo 的定价(参见此处)——由于我们处理的是小 token 块,这一步骤的成本是微不足道的。
- 将数据返回给 ChatGPT。GPT 随后使用这些信息来回答用户的初始问题。
从下面的架构图可以看出,前三个步骤与解决方案 1 相同。主要区别在于此 解决方案将文件转换为文本而不是 base64 字符串,然后使用 GPT 3.5 Turbo 总结该文本。
为什么需要这样做而不是直接与 Microsoft API 交互?
-
根据此指南,Microsoft Graph Search API 返回符合条件的文件引用,而不是文件内容本身。因此,我们需要有两种选择,对应于上述两种解决方案:
- 接下来,我们可以通过在函数中使用gpt-3.5-turbo进行总结来进一步优化,以帮助我们今天对Actions施加的100,000字符限制。
前提条件
-
拥有创建Azure Function Apps和Azure Entra App注册权限的Azure门户
-
Postman(以及对API和OAuth的了解)
-
仅限解决方案2: 来自platform.openai.com的OpenAI API密钥
解决方案1 + 解决方案2 安装指南
以下是设置带有身份验证的Azure函数的指南。请确保在实施代码之前遵循这些步骤。
这些安装指南适用于解决方案1和解决方案2。我们鼓励在同一个Function App中设置两个解决方案作为单独的函数,以测试哪个最适合您,因为一旦设置了一个函数,在同一个函数应用中设置另一个函数只需几分钟。
安装应用
您可以在文档左侧了解更多关于Azure函数的语言和部署选项这里。
选项1:使用VSCode
请参阅Microsoft的文档这里了解如何使用VSCode进行部署。如果您熟悉这种方法,请随意使用。
选项2:直接在Azure门户中
请参阅文档这里了解如何使用Azure门户进行部署。我们将在这里一步步进行示例说明。
注意:您可以使用下面的第1部分至第4部分来设置任何带有Entra身份验证的Azure Function App。
第1部分:创建函数
-
创建一个Azure Function应用。我使用了以下设置,但您可以使用任何您熟悉的设置。请注意,并非每种语言/操作系统都允许直接在控制台中编辑函数——我选择的组合可以。在我的演示中,我将所有内容保留为默认设置,并做出了以下选择:
-
基础
-
您想部署代码还是容器镜像?: 代码
-
运行时堆栈: Node.js
-
操作系统: Windows
-
-
网络
- 启用公共访问: 开启(需要连接到GPT)
-
-
完成上述步骤后,您将进入“部署”页面。一旦部署完成(应该只需要几分钟),点击**“转到资源”**返回Function App。
您第一次尝试时可能会遇到错误,再次点击创建,很可能会成功。
第2部分:设置身份验证
-
在Azure Function App的左侧菜单中,点击设置菜单下的身份验证。
-
添加身份提供者
-
选择Microsoft作为身份提供者。
-
工作力作为租户类型
-
**创建一个新应用程序。**如果您使用现有应用程序,步骤大致相似,但创建新应用程序更容易,因为它会自动使用“Easy Auth”暴露回调URL和API。您可以阅读更多相关信息这里。
-
将此页面上的所有其他设置保留为默认值,但根据您的内部指南自由更改。
-
在权限标签页,点击添加权限并添加Files.Read.All和Sites.ReadAll,然后添加。这允许该应用程序读取文件,这对于使用Microsoft Graph搜索API非常重要。
-
-
创建完成后,点击您刚刚创建的企业应用程序(即,离开Function App页面,进入您刚刚创建的企业应用程序页面)。我们现在将给它添加一个额外的权限,即通过模拟登录应用程序的用户来执行Azure函数。更多详情请参阅这里。
-
在主页上,点击“查看API权限”
-
在我的组织使用的API中搜索Microsoft Azure App Service并找到user_impersonation
-
添加它,然后您需要Azure门户上的管理员授予管理员同意。
-
-
在企业应用程序中,点击左侧菜单下**“管理”中的“公开API”,然后使用“复制到剪贴板”**按钮复制创建的范围。范围应类似于“api://<插入-uuid>/user_impersonation”。保存此内容以备后用,记为
SCOPE
。 -
点击左侧菜单下**“管理”中的“身份验证”**
- 在Web部分下,你会注意到一个回调URI已自动添加。添加Postman的重定向URI
https://oauth.pstmn.io/v1/callback
用于测试。
- 在Web部分下,你会注意到一个回调URI已自动添加。添加Postman的重定向URI
-
在左侧,进入概览。复制应用程序(客户端)ID和目录(租户)ID,并保存以备后用,分别记为
CLIENT_ID
和TENANT_ID
。
第三部分:设置测试函数
-
离开页面,回到主页,然后返回你的函数应用。
-
点击创建函数。在这个例子中,我将在门户中开发它,但你也可以使用VSCode或其他IDE。
-
选择HTTP触发器
-
对于授权级别,你可以 选择任何你想要的密钥类型。
- 注意这可能会在第一次出错,但函数很可能已经创建,刷新页面检查一下。
-
-
点击你刚刚创建的函数(你可能需要点击刷新才能看到它)。点击获取函数URL并保存,以便在Postman中测试。稍后创建OpenAPI规范时,你也会用到这个URL。
- 返回函数应用并点击配置。显示
MICROSOFT_PROVIDER_AUTHENTICATION_SECRET
变量的值,复制它(点击高级编辑以复制),并保存以备后用。
至此,你应该已经创建了一个测试函数,并保存了客户端ID、租户ID、密钥、范围和函数URL。现在你可以准备在Postman中测试身份验证了。
第四部分:在Postman中测试身份验证
-
尝试在Postman中使用这些OAuth设置访问你创建的端点:
-
授权类型:授权码
-
授权URL:https://login.microsoftonline.com/
TENANT_ID
/oauth2/v2.0/authorize -
令牌URL:https://login.microsoftonline.com/
TENANT_ID
/oauth2/v2.0/token -
客户端ID:来自步骤7的
CLIENT_ID
-
客户端密钥:来自步骤11的
MICROSOFT_PROVIDER_AUTHENTICATION_SECRET
-
范围:来自步骤5的
SCOPE
-
客户端凭据:在请求体中发送客户端凭据
-
-
你需要点击获取新访问令牌,然后访问你在步骤10中保存的端点。如果成功,你应该会得到这个响应:
“This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response.”
第五部分:添加函数代码
现在你已经有一个经过身份验证的Azure函数,我们可以更新函数以搜索SharePoint/O365
这段代码旨在提供方向 - 虽然它应该开箱即用,但它设计为可根据你的需求 进行定制(参见本文档末尾的示例)。
-
通过进入左侧设置下的配置标签,设置以下环境变量。注意,这可能会直接列在环境变量中,具体取决于你的Azure UI。
-
TENANT_ID
:从前一部分复制 -
CLIENT_ID
:从前一部分复制 -
仅限解决方案2:
OPENAI_API_KEY
:在platform.openai.com上创建一个OpenAI API密钥。
-
-
进入开发工具下的控制台标签
-
在控制台中安装以下包
-
npm install @microsoft/microsoft-graph-client
-
npm install axios
-
仅限解决方案2:
-
npm install pdf-parse
-
npm install openai
-
-
-
-
完成后,再次从Postman调用函数(POST请求),将以下内容放入请求体(使用你认为会产生响应的查询和搜索词)。
解决方案1:
{
"searchTerm": "<选择一个搜索词>"
}解决方案2:
{
"query": "<选择一个问题>",
"searchTerm": "<选择一个搜索词>"
} -
如果你得到响应,你就可以准备将这个设置为自定义GPT了!
第六部分:在自定义GPT中设置
-
为你的端点生成一个OpenAPI规范。
-
将该代码粘贴到 GPT 的 Actions 部分,并选择 OAuth 作为认证类型。按照上述 Postman 的设置方式填写 OAuth 设置。
-
保存操作后,你会在 GPT 配置底部看到一个回调 URI。复制该 URL,然后返回 Azure 门户中的 Function App。
-
点击 设置 下的 认证,然后点击你的 Entra 应用程序。
-
进入后,点击 管理 部分的 认证。
-
在该页面的 Web 部分添加一个新的重定向 URI,并粘贴从第 20 步获得的回调 URI,然后点击保存。
-
自定义提示以使用此操作。你可以在本文件的示例 GPT 说明中看到一个示例提示,该提示定制为通过更改 searchTerm 尝试三次以找到答案。
-
测试 GPT,它应该按预期工作。