# 使用API调用运行时接口（IAM认证）
本指南面向通过编写代码并将智能体托管到AgentArts运行时的开发者，介绍如何使用IAM认证（AK/SK 签名）方式调用已部署的智能体运行时API。
与平台"低码开发智能体"模式不同，托管运行时允许您完全自定义智能体逻辑，并以标准HTTP服务形式部署。调用方需遵循华为云API网关的V11-HMAC-SHA256签名规范，本指南将详细拆解签名流程、请求结构，并与您编写的智能体服务代码建立清晰的对应关系。
#### 理解托管运行时与调用接口
#### 什么是托管运行时
AgentArts托管运行时是一种将您的智能体代码容器化并部署到云端的服务。您通过编写代码定义智能体核心逻辑，并利用agentarts-sdk提供的AgentArtsRuntimeApp类将业务函数封装为符合平台规范的HTTP服务。AgentArtsRuntimeApp会自动为您注册两个标准接口：
表1AgentArtsRuntimeApp类说明 
| 接口路径           | 方法    | 用途                       |
|:---|:---|:---|
| /ping          | GET | 平台健康检查，判断容器是否存活。          |
| /invocations | POST | 智能体调用入口，接收用户请求并返回处理结果。 |
   
运行时部署后，平台为您生成一个API网关地址，所有调用请求先经过网关鉴权，再路由到您的容器实例。运行时接口格式为：
```
https://{网关信息}.cn-southwest-2.huaweicloud-agentarts.com/runtimes/{运行时名称}/invocations
```
#### 调用接口的传参如何与智能体代码对应
运行时接口的请求体字段结构完全由您的业务代码决定，平台网关仅做透传，不会修改请求体内容。
您在编写智能体服务时，会可以使用@app.invocation_handler装饰器注册一个处理函数，该函数接收一个request参数（即HTTP请求体解析后的字典），并返回一个字典作为HTTP响应体。
```
# 在您的服务代码中（文件名任意）
from agentarts.sdk import AgentArtsRuntimeApp
app = AgentArtsRuntimeApp()
@app.invocation_handler
def handle_invocation(request: dict) -> dict:
    # request 是调用方传入的请求体字典
    message = request.get("message", "")  # 此处定义了需要接收的字段名
    # ... 业务处理 ...
    return {"reply": result}              # 此处定义了响应体结构
```
调用方在发送请求时，请求体中的字段名必须与处理函数中request.get()读取的字段名完全一致。例如，如果您的处理函数使用request.get("query")读取用户输入，则调用方必须传递{"query": "..."}；如果处理函数使用message读取用户输入，则调用接口也需要使用message参数。
响应体同理，调用方收到的结构取决于您处理函数返回的字典内容。通常会使用 {"response": "...", "status": "success"}，但这完全由您自定义。
#### IAM认证 vs API Key认证
表2认证方式说明 
| 认证方式     | 说明                                               | 适用场景         |
|:---|:---|:---|
| IAM 认证    | 使用华为云账号的AK/SK对请求进行V11-HMAC-SHA256签名，由IAM服务统一鉴权。 | 生产环境、企业级多服务集成。 |
| API Key 认证 | 使用固定Bearer {API_Key}鉴权，无需签名。                   | 快速验证、内部测试。    |
   
本指南假设您已在部署运行时勾选"入站身份认证"为IAM认证。如选择API Key，请参考[使用API调用运行时接口（API Key认证）](https://support.huaweicloud.com/api-agentarts/agentarts_07_0035.html#agentarts_07_0035)。
#### 步骤一：前置准备
#### 获取调用接口
通过AgentArts页面部署运行时，请在**"入站身份认证"处选择IAM认证**。
如果使用AgentArts运行时SDK提供的deploy或launch命令部署，则默认部署的运行时为IAM认证。
在运行时列表中找到部署的实例，在基本信息页面获取运行时接口。
图1获取运行时接口   
![](https://support.huaweicloud.com/api-agentarts/zh-cn_image_0000002748601739.png "点击放大")
 #### 配置华为云AK/SK
1. 登录控制台"[我的凭证 \> 访问密钥](https://console.huaweicloud.com/iam/#/mine/accessKey)"，获取AK和SK。AK、SK最多可添加2个。
   
   图2获取AK、SK   
   ![](https://support.huaweicloud.com/api-agentarts/zh-cn_image_0000002748527127.png "点击放大")
   图3AK、SK示例   
   ![](https://support.huaweicloud.com/api-agentarts/zh-cn_image_0000002718927310.png "点击放大")
   
   
2. 在Python SDK所在文件夹的地址栏输入cmd打开命令窗口后，执行以下命令设置临时环境变量。 
   ```
   set HUAWEICLOUD_SDK_AK=您的Access Key
   set HUAWEICLOUD_SDK_SK=您的Secret Key
   ```
   
   
3. 通过以下命令检查环境变量是否生效。 
   ```
   echo %HUAWEICLOUD_SDK_AK%
   echo %HUAWEICLOUD_SDK_SK%
   ```
   
   
 
 #### 准备签名SDK
**安装运行环境：**
- 安装Python：如果您还没装，去[python.org](https://www.python.org/)下载并安装（记得安装时勾选 "Add Python to PATH"）。
- 安装requests库： 打开电脑的"命令提示符"（Windows按Win+R键输入cmd），输入以下命令并按回车：
  ```
  pip install requests
  ```
  
**获取API签名所需的SDK包：**
1. 在[签名指南](https://support.huaweicloud.com/devg-apisign/api-sign-sdk-python.html)文档中下载Python SDK，并在本地解压。签名指南文档中的其他内容本案例中可不用关注。
   
   图4获取SDK   
   ![](https://support.huaweicloud.com/api-agentarts/zh-cn_image_0000002748607209.png "点击放大")
   解压后的文件目录结构如下：
   ```
   ApiGateway-python-sdk/              ← 根目录（解压出来的文件夹）
   │
   ├── apig_sdk/                       ← 【核心签名库，不要动！】
   │   ├── __init__.py                 ← 包的入口标识文件
   │   └── signer.py                   ← 签名核心代码（所有签名逻辑都在这里）
   │
   ├── main.py                         ← 【您要改的文件】调用示例
   │
   └── licenses/                       ← 开源许可证文件夹（不用管）
       └── license-requests            ← requests库的许可证说明
   ```
   图5目录结构   
   ![](https://support.huaweicloud.com/api-agentarts/zh-cn_image_0000002718928016.png "点击放大")
   
   
 
#### 签名规范说明
AgentArts运行时采用华为云API网关的V11-HMAC-SHA256签名算法，与标准IAM签名有以下关键差异：
表3签名算法说明 
| 特性           | 说明                                                                                          |
|:---|:---|
| 密钥派生机制（HKDF）   | 结合AK + SK + 请求日期 + 区域（cn-southwest-2）+ 服务（agentarts）动态派生加密密钥，安全性高于普通签名算法。                    |
| Body 不参与签名 | 由于智能体交互的请求Body可能包含较长文本，约定在请求头中设置X-Sdk-Content-Sha256: UNSIGNED-PAYLOAD，通知网关跳过Body哈希计算，提升性能。 |
| 时间戳防重放         | 请求头必须包含X-Sdk-Date（ISO 8601 UTC格式），网关校验与当前时间偏差需小于15分钟，防止请求被重放攻击。                              |
| 会话上下文追踪    | 推荐携带x-hw-agentarts-session-id请求头，用于多轮对话中的会话管理。服务端可根据此ID关联上下文信息。                                |
   
签名器初始化代码示例：
```
from apig_sdk import signer
sig = signer.Signer(
    algorithm="V11-HMAC-SHA256",   # 必须指定 V11 版本
    region_id="cn-southwest-2"     # 固定为贵阳一区域
)
sig.Key = os.getenv("HUAWEICLOUD_SDK_AK")
sig.Secret = os.getenv("HUAWEICLOUD_SDK_SK")
```
#### 步骤二：构造调用脚本
1. 以下Python脚本实现了与托管运行时的完整交互，打开[准备签名SDK]步骤中的main.py脚本，删除原有内容，并将下方代码添加进去。
   
   代码中智能体的调用路径（API_URL）按实际进行填写，获取方法参考[步骤一：部署智能体并选择IAM认证](https://support.huaweicloud.com/api-agentarts/agentarts_07_0052.html#agentarts_07_0052__zh-cn_topic_0000002686391511_section9621137131719)。
   ```
   # -*- coding: utf-8 -*-
   """
   AgentArts 托管运行时 API 调用示例（IAM 认证，V11-HMAC-SHA256）
   适用于任意自定义智能体代码。
   """
   import os
   import json
   import uuid
   import requests
   from urllib.parse import urlparse, urlunparse
   from apig_sdk import signer
   # ========== 配置区域 ==========
   # 从控制台复制的完整调用路径
   API_URL = "完整调用路径"
   REGION_ID = "cn-southwest-2"   # 默认为贵阳一
   # ===============================
   def normalize_api_url(url: str) -> str:
       """移除 URL 中可能携带的查询参数（如 ?endpoint=Latest）"""
       parsed = urlparse(url.strip())
       clean = urlunparse(parsed._replace(query="", fragment=""))
       if parsed.query:
           print(f"[提示] 已剥离查询参数「?{parsed.query}」，实际使用: {clean}\n")
       return clean
   def build_signed_request(sig, api_url: str, payload: dict, session_id: str):
       """
       构造请求并执行 V11 签名
       :param payload: 请求体字典，其字段结构必须与您的服务代码中定义的接口一致
       """
       method = "POST"
       body = json.dumps(payload, ensure_ascii=False)
       headers = {
           "Content-Type": "application/json",
           "X-Sdk-Content-Sha256": "UNSIGNED-PAYLOAD",   # Body 免签名
           "x-hw-agentarts-session-id": session_id
       }
       req = signer.HttpRequest(method, api_url, headers, body)
       sig.Sign(req)   # 自动填充 X-Sdk-Date 和 Authorization
       return req
   def main():
       api_url = normalize_api_url(API_URL)
       # 读取 IAM 凭证
       ak = os.getenv('HUAWEICLOUD_SDK_AK', '').strip()
       sk = os.getenv('HUAWEICLOUD_SDK_SK', '').strip()
       if not ak or not sk:
           print("错误：环境变量 HUAWEICLOUD_SDK_AK/SK 未设置！")
           return
       # 初始化 V11 签名器
       sig = signer.Signer(algorithm="V11-HMAC-SHA256", region_id=REGION_ID)
       sig.Key = ak
       sig.Secret = sk
       # 生成会话 ID（同一用户的多轮对话应复用同一个 session_id）
       session_id = str(uuid.uuid4())
       # 打印鉴权头示例（用于调试）
       demo_payload = {"message": "ping"}   # 字段名需与您的服务定义一致
       demo_req = build_signed_request(sig, api_url, demo_payload, session_id)
       print(f"X-Sdk-Date    : {demo_req.headers.get('X-Sdk-Date')}")
       print(f"Authorization : {demo_req.headers.get('Authorization')[:80]}...\n")
       print("=== AgentArts 运行时交互式调用 ===")
       print("输入 'exit' 或 'quit' 退出\n")
       while True:
           try:
               user_input = input("【您】: ").strip()
               if not user_input:
                   continue
               if user_input.lower() in ["exit", "quit"]:
                   break
               # 【关键】构造请求体：字段名必须与您的 handler 中 request.get() 的键名一致
               # 示例中使用 "message" 作为用户输入字段
               payload = {"message": user_input}
               # 每次请求自动重新签名（使用最新时间）
               req = build_signed_request(sig, api_url, payload, session_id)
               resp = requests.request(
                   method=req.method,
                   url=f"{req.scheme}://{req.host}{req.uri}",
                   headers=req.headers,
                   data=req.body,
                   timeout=(5, 60)   # 连接超时 5 秒，读取超时 60 秒
               )
               print(f"\n[HTTP {resp.status_code}]")
               try:
                   resp_json = resp.json()
                   print("【Agent响应】:", json.dumps(resp_json, ensure_ascii=False, indent=2))
               except:
                   print("【原始响应】:", resp.text)
               print("-" * 50)
           except KeyboardInterrupt:
               break
           except Exception as e:
               print(f"发生异常: {e}")
   if __name__ == '__main__':
       main()
   ```
   
   
2. 脚本编辑完成后，保存并关闭该脚本。
 
#### 步骤三：运行脚本获取接口响应
1. 在Python SDK的文件夹上方显示路径的地址栏里，清空地址，直接输入cmd后按回车。 
   ![](https://support.huaweicloud.com/api-agentarts/zh-cn_image_0000002718928268.png "点击放大")
   
   
2. 在打开的命令提示符窗口中会显示出当前的文件夹路径，输入以下命令执行脚本。 
   ```
   python main.py
   ```
   运行该脚本会返回接口的鉴权信息值，以及接口的响应结果。
   图6运行示例   
   ![](https://support.huaweicloud.com/api-agentarts/zh-cn_image_0000002718931654.png "点击放大")
   调用AgentArts运行时API时，HTTP响应返回401状态码，响应体为 {"code": 401, "message": "Authentication failed!"}。控制台检查确认运行时"入站身份认证"已正确选择为"IAM 认证"，签名算法和区域配置是否均无误。
   在终端中执行以下命令检查AK/SK环境变量是否生效，如果未生效，请参考[配置华为云AK/SK]重新配置：
   ```
   echo $HUAWEICLOUD_SDK_AK
   echo $HUAWEICLOUD_SDK_SK
   ```
   
   
 
