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

Azure 容器应用中的无服务器代码解释器会话(预览版)

Azure 容器应用动态会话提供对代码解释器的快速且可缩放的访问。 每个代码解释器会话均按 Hyper-V 边界完全隔离,旨在运行不受信任的代码。

注意

Azure 容器应用动态会话功能目前以预览版提供。 有关详细信息,请参阅预览版限制

用于代码解释器会话

代码解释器会话非常适合需要运行潜在恶意代码或可能对主机系统或其他用户造成危害的情况,例如:

  • 由大型语言模型 (LLM) 生成的代码。
  • 最终用户在 Web 或 SaaS 应用程序中提交的代码。

对于流行的 LLM 框架(例如 LangChain、LlamaIndex 或 Semantic Kernel),可以使用工具和插件将 AI 应用与代码解释器会话集成。

应用程序还可以使用一个 REST API 来与代码解释器会话集成。 该 API 允许你在会话中执行代码并检索结果。 还可以在会话中上传和下载文件。 可以上传和下载可执行代码文件或代码可处理的数据文件。

内置代码解释器会话支持最常见的代码执行场景,无需管理基础结构或容器。 如果需要完全控制代码执行环境或有需要隔离沙盒的不同场景,则可以使用自定义代码解释器会话

代码解释器会话池

若要使用代码解释器会话,需要一个称为会话池的 Azure 资源,它定义代码解释器会话的配置。 在会话池中,可以指定最大并发会话数以及会话终止前会话可空闲时间等设置。

可以使用 Azure 门户、Azure CLI 或 Azure 资源管理器模板创建会话池。 创建会话池后,可以使用池的管理 API 终结点来管理和执行会话中的代码。

使用 Azure CLI 创建会话池

若要使用 Azure CLI 创建代码解释器会话池,请使用以下命令确保安装最新版本的 Azure CLI 和 Azure 容器应用扩展:

# Upgrade the Azure CLI
az upgrade

# Install or upgrade the Azure Container Apps extension
az extension add --name containerapp --upgrade --allow-preview true -y

使用 az containerapps sessionpool create 命令创建池。 以下示例创建一个名为 my-session-pool 的 Python 代码解释器会话池。 运行该命令之前,请务必将 <RESOURCE_GROUP> 替换为你的资源组名称。

az containerapp sessionpool create \
    --name my-session-pool \
    --resource-group <RESOURCE_GROUP> \
    --location westus2 \
    --container-type PythonLTS \
    --max-sessions 100 \
    --cooldown-period 300 \
    --network-status EgressDisabled

创建会话池时,可以定义以下设置:

设置 说明
--container-type 要使用的代码解释器的类型。 唯一支持的值为 PythonLTS
--max-sessions 允许并发分配的最大会话数。 最大值为 600
--cooldown-period 终止前允许的空闲秒数。 每次调用会话的 API 都会重置空闲时间。 允许的范围介于 3003600 之间。
--network-status 指定是否允许从会话发送出站网络流量。 有效值为 EgressDisabled(默认值)和 EgressEnabled

重要

如果启用传出,则会话中运行的代码可以访问 Internet。 当代码不受信任时请务必小心,因为此设置可用于执行恶意活动,例如拒绝服务攻击。

使用 Azure CLI 获取池管理 API 终结点

若要通过 LLM 框架集成或通过直接调用管理 API 终结点来使用代码解释器会话,需要获取池的管理 API 终结点。 终结点的格式为 https://<REGION>.dynamicsessions.io/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/sessionPools/<SESSION_POOL_NAME>

若要检索会话池的管理 API 终结点,请使用 az containerapps sessionpool show 命令。 运行该命令之前,请务必将 <RESOURCE_GROUP> 替换为你的资源组名称。

az containerapp sessionpool show \
    --name my-session-pool \
    --resource-group <RESOURCE_GROUP> \
    --query 'properties.poolManagementEndpoint' -o tsv

会话中的代码执行

创建会话池后,应用程序可以通过与 LLM 框架集成或直接使用池的管理 API 终结点来与池中的会话交互。

会话标识符

重要

会话标识符是敏感信息,需要通过一个安全的过程来管理其值。 在此过程中,应用程序必须确保每个用户或租户仅有权访问其自己的会话。 如果未能保护对会话的访问,可能会导致滥用或未经授权地访问存储在用户会话中的数据。 有关详细信息,请参阅“会话标识符

与池中的会话交互时,可以使用会话标识符来引用每个会话。会话标识符是你定义的、在会话池中唯一的字符串。 如果你正在生成 Web 应用程序,则可以使用用户的 ID。 如果你正在生成聊天机器人,则可以使用对话 ID。

如果正在运行带标识符的会话,则将重用该会话。 如果未运行带标识符的会话,则会自动创建新会话。

若要详细了解会话标识符,请参阅会话概述

身份验证

使用 Microsoft Entra(以前称为 Azure Active Directory)令牌处理身份验证。 有效的 Microsoft Entra 令牌由属于会话池上的“Azure 容器应用会话执行者”和“参与者”角色的标识生成

如果使用 LLM 框架集成,该框架会为你处理令牌生成和管理。 确保为应用程序配置了托管标识,并在会话池中进行了所需的角色分配。

如果直接使用池的管理 API 终结点,则必须生成令牌并将其包含在 HTTP 请求的 Authorization 标头中。 除了前面提到的角色分配之外,令牌还需要包含一个值为 https://dynamicsessions.io 的受众 (aud) 声明。

若要了解详细信息,请参阅身份验证

LLM 框架集成

以下 LLM 框架不直接使用会话池管理 API,而是提供与代码解释器会话的集成:

框架 教程
LangChain Python: langchain-azure-dynamic-sessions 教程
LlamaIndex Python: llama-index-tools-azure-code-interpreter 教程
语义内核 Python:semantic-kernel(版本 0.9.8-b1 或更高版本) 教程

管理 API 终结点

如果不使用 LLM 框架集成,可以直接使用管理 API 终结点来与会话池交互。

以下终结点可用于管理池中的会话:

终结点路径 方法 说明
code/execute POST 在会话中执行代码。
files/upload POST 将文件上传到会话。
files/content/{filename} GET 从会话下载文件。
files GET 列出会话中的文件。

通过将池的管理 API 终结点与终结点路径相连接,为每个终结点构建完整的 URL。 查询字符串必须包含一个 identifier 参数(包含会话标识符)和一个值为 2024-02-02-previewapi-version 参数。

例如:https://<REGION>.dynamicsessions.io/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/sessionPools/<SESSION_POOL_NAME>/code/execute?api-version=2024-02-02-preview&identifier=<IDENTIFIER>

在会话中执行代码

若要在会话中执行代码,请将 POST 请求发送到 code/execute 终结点,并在请求正文中包含要运行的代码。 此示例输出 Python 语言的“Hello,world!”。

在发送请求之前,请将 <> 括号之间的占位符替换为适合你的会话池和会话标识符的值。

POST https://<REGION>.dynamicsessions.io/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/sessionPools/<SESSION_POOL_NAME>/code/execute?api-version=2024-02-02-preview&identifier=<SESSION_ID>
Content-Type: application/json
Authorization: Bearer <token>

{
    "properties": {
        "codeInputType": "inline",
        "executionType": "synchronous",
        "code": "print('Hello, world!')"
    }
}

若要重用会话,请在后续请求中指定相同的会话标识符。

将文件上传到会话

若要将文件上传到会话,请在多部分表单数据请求中向 uploadFile 终结点发送 POST 请求。 将文件数据包含在请求正文中。 该文件必须包括文件名。

上传的文件存储在会话文件系统的 /mnt/data 目录下。

在发送请求之前,请将 <> 括号之间的占位符替换为特定于你的请求的值。

POST https://<REGION>.dynamicsessions.io/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/sessionPools/<SESSION_POOL_NAME>/files/upload?api-version=2024-02-02-preview&identifier=<SESSION_ID>
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Authorization: Bearer <token>

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="<FILE_NAME_AND_EXTENSION>"
Content-Type: application/octet-stream

(data)
------WebKitFormBoundary7MA4YWxkTrZu0gW--

从会话下载文件

若要从会话的 /mnt/data 目录下载文件,请向 file/content/{filename} 终结点发送 GET 请求。 响应包含文件数据。

在发送请求之前,请将 <> 括号之间的占位符替换为特定于你的请求的值。

GET https://<REGION>.dynamicsessions.io/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/sessionPools/<SESSION_POOL_NAME>/files/content/<FILE_NAME_AND_EXTENSION>?api-version=2024-02-02-preview&identifier=<SESSION_ID>
Authorization: Bearer <TOKEN>

列出会话中的文件

若要列出会话的 /mnt/data 目录中的文件,请向 files 终结点发送 GET 请求。

在发送请求之前,请将 <> 括号之间的占位符替换为特定于你的请求的值。

GET https://<REGION>.dynamicsessions.io/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/sessionPools/<SESSION_POOL_NAME>/files?api-version=2024-02-02-preview&identifier=<SESSION_ID>
Authorization: Bearer <TOKEN>

响应包含会话中的文件列表。

以下列表显示了请求会话内容时预期返回的响应类型的示例。

{
    "$id": "1",
    "value": [
        {
            "$id": "2",
            "properties": {
                "$id": "3",
                "filename": "test1.txt",
                "size": 16,
                "lastModifiedTime": "2024-05-02T07:21:07.9922617Z"
            }
        },
        {
            "$id": "4",
            "properties": {
                "$id": "5",
                "filename": "test2.txt",
                "size": 17,
                "lastModifiedTime": "2024-05-02T07:21:08.8802793Z"
            }
        }
    ]
}

预装的包

Python 代码解释器会话包含流行的 Python 包,例如 NumPy、pandas 和 scikit-learn。

若要输出预装的包列表,请使用以下代码调用 code/execute 终结点。

在发送请求之前,请将 <> 括号之间的占位符替换为特定于你的请求的值。

POST https://<REGION>.dynamicsessions.io/subscriptions/<SUBSCRIPTION_ID>/resourceGroups/<RESOURCE_GROUP>/sessionPools/<SESSION_POOL_NAME>/identifier/<SESSION_ID>/code/execute?api-version=2024-02-02-preview&identifier=<SESSION_ID>
Content-Type: application/json
Authorization: Bearer <TOKEN>

{
    "properties": {
        "codeInputType": "inline",
        "executionType": "synchronous",
        "code": "import pkg_resources\n[(d.project_name, d.version) for d in pkg_resources.working_set]"
    }
}

后续步骤