# 自定义路径调用
[ExecuteRuntimeWithPrefix接口](https://support.huaweicloud.com/api-agentarts/ExecuteRuntimeWithPrefix.html)，用于通过前缀匹配方式调用已部署的智能体运行时中的自定义接口。使用该接口需确保智能体运行时的路由匹配模式设置为**前缀匹配（PREFIX_MATCH）**。
图1前缀匹配   
![](https://support.huaweicloud.com/highcode-agentarts/zh-cn_image_0000002753340125.png "点击放大")
#### 使用场景
标准的[ExecuteRuntime](https://support.huaweicloud.com/api-agentarts/InvokeRuntime1.html)（POST /invocations）接口适用于大多数对话场景。但在很多实际场景中，一个Agent不只有一个接口，它可能同时提供对话、健康检查、批量处理等多种功能。这时就需要通过自定义路径调用不同的接口。
- 多功能接口：除了对话接口外，Agent还提供健康检查（/health）、状态查询（/status）、批量处理（/batch）等能力。
- RESTful API：Agent提供了完整的RESTful风格接口，如GET /users、POST /tasks、DELETE /tasks/{id}等。
- MCP Server 集成：部署为MCP Server的运行时需要通过自定义路径接收MCP协议请求。
- 回调通知：Agent需要接收外部系统的Webhook回调。
 
#### 工作原理
当您发起自定义接口调用时，请求经过以下路径到达Agent代码：
调用链路说明：
1. 客户端发起接口请求，例如POST /runtimes/{runtime_name}/invocations/chat，携带请求体{"input": "hello"}。
2. 请求首先到达API网关，网关按序完成三项处理：
   - **身份校验**：校验Authorization请求头中的认证凭据，确认调用方有权限访问该运行时。
   
   - **格式校验**：校验请求头格式（如Session ID等），确保请求符合协议规范。
   
   - **路由分发**：根据路径中的runtime_name查找对应的目标容器实例，并将请求转发过去。
    
3. 请求到达Agent容器后，平台将请求原样传递给您Agent中定义的对应路由处理函数（如 /chat）。
4. handler执行业务逻辑后返回结果对象{"output": "hello"}。
5. 返回值再经由API网关原样回传给调用方。
网关在整个过程中**不解析、不修改**请求体和响应体的内容，仅负责鉴权和路由。
**与标准调用的区别**：
标准调用接口（ExecuteRuntime）路径为/runtimes/{runtime_name}/invocations，只能调用Agent的默认入口。
而自定义接口在前缀匹配模式下支持invocations/{custom_path}路径，允许调用Agent代码中定义的任意自定义路由，如/chat、/query、/search 等，且支持所有HTTP方法（POST、GET、PUT、DELETE 等）。
#### 路径映射原理
理解自定义路径调用的方法，需要理解"API接口 → Agent容器路由"的映射关系。当您在Agent代码中注册了多个路由处理器时，比如：
```
from agentarts.sdk import AgentArtsRuntimeApp
app = AgentArtsRuntimeApp()
# 路由 1：标准对话（固定路径 /invocations）
@app.invocation_handler
def handle_invocation(request: dict) -> dict:
    message = request.get("message", "")
    return {"reply": f"你说了：{message}"}
# 路由 2：健康检查（自定义路径 /health）
@app.handler("/health")
def handle_health(request: dict) -> dict:
    return {"status": "ok", "version": "1.0.0"}
# 路由 3：批量处理（自定义路径 /batch）
@app.handler("/batch")
def handle_batch(request: dict) -> dict:
    tasks = request.get("tasks", [])
    results = [{"task": t, "done": True} for t in tasks]
    return {"processed": len(tasks), "results": results}
```
那么，调用的API接口和Agent路由的对应关系如下。
表1对应关系说明 
| 调用的API接口                              | 网关转发到Agent容器的路由 | 匹配的处理函数           |
|:---|:---|:---|
| POST /runtimes/{name}/invocations    | /invocations     | handle_invocation |
| GET /runtimes/{name}/invocations/health | /health        | handle_health     |
| POST /runtimes/{name}/invocations/batch | /batch          | handle_batch        |
   
API接口中/invocations/后面跟的部分（即custom_path），就是Agent代码中@app.handler()注册的路由路径。
#### 前置条件
使用自定义路径调用前，请确保部署运行时时已将URL匹配模式设置为PREFIX_MATCH（前缀匹配）。如果使用默认的精确匹配模式（ACCURATE_MATCH），非 /invocations 路径的请求会被网关直接拒绝。
配置方式：
- 方式一：在.agentarts_config.yaml配置文件中声明：
  ```
  runtime:
    invoke_config:
      url_match_type: PREFIX_MATCH
  ```
  
- 方式二：在AgentArts控制台托管智能体，创建运行时过程中，在高级配置中将"路由配置"设置为"前缀匹配"。
  前缀匹配支持 /runtimes/{runtime_name}/invocations 以及 /runtimes/{runtime_name}/invocations/{custom_path} 的调用路径；一旦选择前缀匹配，后续镜像中可以新增、删除接口等。
  图2前缀匹配   
  ![](https://support.huaweicloud.com/highcode-agentarts/zh-cn_image_0000002753508221.png "点击放大") 
 
#### 接口介绍
表2接口说明 
| 项目               | 说明                                                                                                                            |
|:---|:---|
| 请求方法             | 支持所有 HTTP 方法（POST、GET、PUT、DELETE 等），请按后端实际接口方法调用。                                                                              |
| 请求路径              | /runtimes/{runtime_name}/invocations/{custom_path}                                                                              |
| runtime_name     | 您的运行时名称，可在控制台"智能体运行时"列表中获取。以小写字母开头，以小写字母或数字结尾，包含小写字母、数字和中划线，长度 2-48 个字符。                                                       |
| custom_path     | 需要调用的自定义接口URL路径，**不能以/开头**，需确保运行时路由匹配模式设置为前缀匹配。包含英文字母、数字和特殊字符（- _ . \~ : / ? # \[ \] @ ! $ \& ' ( ) \* + , ; = %），长度1-256个字符。 |
| endpoint 参数（可选） | 查询参数?endpoint=xxx，指定访问方式名称以路由到特定运行时版本。不传时默认使用Latest。                                                                            |
   
表3请求头参数 
| 请求头                           | 是否必填     | 说明                                                                                                    |
|:---|:---|:---|
| Content-Type                  | 是     | 固定为 application/json。                                                                             |
| Authorization               | 是       | 身份认证凭据。API Key 方式填写 Bearer {api_key}；IAM 方式由签名 SDK 自动生成；OAuth 2.0 方式填写 Bearer {jwt_token}。          |
| X-Hw-Agentarts-Session-Id | 是        | 会话 ID，用于标识一次会话。您可以自行生成一个字符串（如 UUID），同一个 Session ID 的多次调用在 Agent 侧可关联上下文。由英文、数字、-、_ 组成，不超过 64 个字符。    |
| X-Sdk-Content-Sha256          | IAM认证时必填 | 如果智能体运行时的入站认证类型为IAM认证时，需要指定该Header头为UNSIGNED-PAYLOAD。                                                |
| X-Hw-Agentgateway-User-Id   | 否          | 用户标识，用于区分不同终端用户。由英文、数字、-、_ 组成，不超过 128 个字符。                                                           |
| Mcp-Session-Id              | 否       | 本次MCP调用对应的会话唯一ID，用于标识同一次会话上下文，实现会话级别的状态保持、日志追踪与问题排查。同一会话上下文内应保持一致。由英文、数字、-、_ 组成，不超过128位字符。            |
| Mcp-Protocol-Version       | 否         | 本次MCP协议通信版本，适配Streamable HTTP传输。客户端可指定版本，未传时服务端默认采用 2025-03-26。支持 2025-03-26、2025-06-18、2025-11-25。 |
   
#### 请求体
请求体格式由您的Agent代码定义。网关不做任何校验，原样转发。以下是一个常见的请求体示例（假设您的Agent代码使用message字段接收用户输入）：
```
{
  "message": "hello"
}
```
#### 响应体
响应Body为Agent代码返回的结果，格式由您的Agent代码决定。
```
{
  "output": "hello"
}
```
表4错误响应 
| 状态码  | 说明                  | 响应示例                                           |
|:---|:---|:---|
| 401   | 未授权（认证令牌缺失、无效或已过期） | {"code": 401, "message": "Unauthorized"}      |
| 404   | 运行时资源不存在          | {"code": 404, "message": "runtime not found"} |
| 500 | 服务器内部错误           | {"code": 500, "message": "internal error"}    |
   
#### 调用示例
**以下示例使用API Key鉴权方式进行演示。**
**第一步：在Agent代码中注册路由**
```
from agentarts.sdk import AgentArtsRuntimeApp
app = AgentArtsRuntimeApp()
@app.invocation_handler
def handle_invocation(request: dict) -> dict:
    """标准对话接口"""
    message = request.get("message", "")
    return {"reply": f"你说了：{message}"}
@app.handler("/health")
def handle_health(request: dict) -> dict:
    """健康检查接口，供监控系统定时探测"""
    return {"status": "ok", "version": "1.0.0"}
@app.handler("/batch")
def handle_batch(request: dict) -> dict:
    """批量处理接口，一次提交多条任务"""
    tasks = request.get("tasks", [])
    results = [{"task": t, "done": True} for t in tasks]
    return {"processed": len(tasks), "results": results}
```
**第二步：部署时选择前缀匹配模式**
在控制台部署运行时时，将URL的路由匹配模式设置为"前缀匹配"。
**第三步：调用各个接口**
- 调用标准对话接口（@app.invocation_handler → /invocations）
  ```
  curl -X POST \
    "https://{域名}/runtimes/{runtime_name}/invocations" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer {API_Key}" \
    -H "X-Hw-Agentarts-Session-Id: session-001" \
    -d '{"message": "你好"}'
  ```
  
- 调用健康检查接口（@app.handler("/health") → /invocations/health）
  ```
  curl -X GET \
    "https://{域名}/runtimes/{runtime_name}/invocations/health" \
    -H "Authorization: Bearer {API_Key}" \
    -H "X-Hw-Agentarts-Session-Id: session-001"
  ```
  
- 调用批量处理接口（@app.handler("/batch") → /invocations/batch）
  ```
  curl -X POST \
    "https://{域名}/runtimes/{runtime_name}/invocations/batch" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer {API_Key}" \
    -H "X-Hw-Agentarts-Session-Id: session-001" \
    -d '{"tasks": ["任务A", "任务B", "任务C"]}'
  ```
  
- 通过访问方式指定版本
  与标准调用一样，自定义路径调用也支持通过endpoint查询参数指定版本：
  ```
  # 调用dev版本的/batch 接口
  POST https://{网关域名}/runtimes/{runtime_name}/invocations/batch?endpoint=dev
  ```
  
 
