使用 StreamAssist API 调用特定代理

如需调用特定的已注册代理,请在 streamAssist REST API 请求或客户端库调用中提供可选的 agentsSpec 字段。AgentsSpec API 定义了用于处理请求的代理的规范。助理直接将查询路由到该代理,并在多轮对话中保留会话上下文。

概览

规范 详细信息
API 方法 projects.locations.collections.engines.assistants.streamAssist
端点版本 v1alpha 用于发现代理 ID;v1 用于调用 streamAssist
关键形参 agentsSpec.agentSpecs[].agentId
支持的代理类型 核心助理Deep ResearchAgent Designer 对话智能体(原低代码)
所需的 IAM 权限 discoveryengine.assistants.assist
必需的 OAuth 范围 https://www.googleapis.com/auth/cloud-platform

准备工作

  1. 在您的 Google Cloud 项目中启用 Discovery Engine API (discoveryengine.googleapis.com)。
  2. 确保您的主账号(用户账号或服务账号)具有授予 discoveryengine.assistants.assist IAM 权限的角色,例如 Discovery Engine Editor (roles/discoveryengine.editor) 或 Gemini Enterprise Admin (roles/discoveryengine.agentspaceAdmin)。
  3. 验证您的 Gemini Enterprise 应用(引擎)是否已创建,并且包含至少一个已注册的代理。
  4. 如果您使用应用默认凭据 (ADC) 进行身份验证,请确保您的客户端发送配额项目标头:-H "X-Goog-User-Project: PROJECT_ID"

查找应用 ID 和位置信息

streamAssist 网址需要您的引擎 ID 及其位置(globaluseu)。如果您只知道应用的显示名称,请列出项目中的引擎以找到底层 ID:

curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://LOCATION-discoveryengine.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/collections/default_collection/engines"

在响应中,引擎 name 格式为 projects/{project}/locations/{location}/collections/default_collection/engines/{ENGINE_ID}ENGINE_ID 段是调用中必需的 APP_ID

查找代理 ID

agentId 是 Discovery Engine API 中代理的完整资源名称的最后一部分:

projects/{project}/locations/{location}/collections/{collection}/engines/{engine}/assistants/{assistant}/agents/{AGENT_ID}

注册代理使用较长的数字 ID(例如 15492003793394502655),而不是友好的显示名称。请在请求中仅提供此最终的 {AGENT_ID} 数字字符串。

如需列出已注册到应用的代理并发现其数字 ID,请对 v1alpha 端点调用 agents 集合:

curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://LOCATION-discoveryengine.googleapis.com/v1alpha/projects/PROJECT_ID/locations/LOCATION/collections/default_collection/engines/APP_ID/assistants/default_assistant/agents"

返回的每个代理资源都包含以下字段:

  • name:以 {AGENT_ID} 结尾的完整资源路径。
  • displayName:在 Google Cloud 控制台中显示的简单易懂的名称。
  • state:运营状态(例如 ENABLEDPRIVATE)。
  • 一个定义对象,用于指示代理类型(例如 a2aAgentDefinitionlowCodeAgentDefinition)。

如需查看完整的代理资源架构,请参阅 agents REST API 参考文档

向代理发送查询

如需向特定代理发送查询,您必须使用适当的 agentsSpec 构建请求,并使用 REST 或客户端库执行该请求。

请求正文结构

如需将查询路由到特定代理,请在 POST 请求正文中添加可选的 agentsSpec 对象:

{
  "query": {
    "text": "QUERY_TEXT"
  },
  "session": "SESSION_RESOURCE_NAME",
  "agentsSpec": {
    "agentSpecs": [
      {
        "agentId": "AGENT_ID"
      }
    ]
  }
}

字段参考

  • agentsSpec (对象,可选):用于处理请求的代理的规范。
  • agentsSpec.agentSpecs[] (数组,可选):代理规范的列表。您可以在此数组中指定多个代理。
  • agentsSpec.agentSpecs[].agentId (字符串,在规范中为必需):用于标识已注册的代理资源的 ID。必须符合 RFC-1034 的要求,且长度上限为 63 个字符。

如需查看完整的请求架构,请参阅 streamAssist REST API 参考文档

调用 streamAssist

REST

以下 curl 命令使用 REST API 向特定代理发送查询:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://LOCATION-discoveryengine.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/collections/default_collection/engines/APP_ID/assistants/default_assistant:streamAssist" \
  -d '{
    "query": {
      "text": "List all contact cards."
    },
    "agentsSpec": {
      "agentSpecs": [
        {
          "agentId": "AGENT_ID"
        }
      ]
    }
  }'
    

替换以下占位符:

  • LOCATION:主机名和资源路径的多区域(globaluseu)。如果您的应用位于 global 位置,请从主机名中省略位置前缀 (discoveryengine.googleapis.com)。
  • PROJECT_ID:您的 Google Cloud 项目 ID。
  • APP_ID:您的 Gemini Enterprise 引擎 ID(可在查找应用 ID 和位置中找到)。
  • AGENT_ID:数字代理 ID(在查找代理 ID中发现)。

Python

以下 Python 示例使用 google-cloud-discoveryengine 客户端库调用 streamAssist

# Install library: pip install google-cloud-discoveryengine
from google.api_core.client_options import ClientOptions
from google.cloud import discoveryengine_v1 as discoveryengine

# TODO(developer): Replace placeholder values with your project and agent details.
project_id = "PROJECT_ID"
location = "LOCATION"          # For example: "us", "eu", or "global"
engine_id = "APP_ID"
agent_id = "AGENT_ID"          # The numeric agent ID
query_text = "List all contact cards."

client_options = (
    ClientOptions(api_endpoint=f"{location}-discoveryengine.googleapis.com")
    if location != "global"
    else None
)
client = discoveryengine.AssistantServiceClient(client_options=client_options)

assistant_path = client.assistant_path(
    project=project_id,
    location=location,
    collection="default_collection",
    engine=engine_id,
    assistant="default_assistant",
)

request = discoveryengine.StreamAssistRequest(
    name=assistant_path,
    query=discoveryengine.Query(text=query_text),
    agents_spec=discoveryengine.StreamAssistRequest.AgentsSpec(
        agent_specs=[
            discoveryengine.StreamAssistRequest.AgentsSpec.AgentSpec(
                agent_id=agent_id,
            )
        ]
    ),
)

for response in client.stream_assist(request=request):
    for reply in response.answer.replies:
        # Filter out model reasoning fragments (thought: true)
        if hasattr(reply, "grounded_content") and reply.grounded_content.content:
            print(reply.grounded_content.content.text, end="", flush=True)

print()
    

了解流式传输响应

streamAssist 端点通过 REST 返回 JSON 块的流,或在客户端库中返回响应对象的迭代器:

  • 答案文本:增量响应文本在 answer.replies[].groundedContent.content.text 中到达。按接收顺序连接这些文本片段,以重构完整答案。
  • 推理片段:标有 "thought": true 的片段表示模型的内部推理过程。在向最终用户呈现最终输出时,过滤掉这些片段。
  • 执行状态answer.state 字段从 IN_PROGRESS 变为最终状态:
    • SUCCEEDED:请求已完成并生成了回答。
    • SKIPPED:查询被忽略或绕过。检查 assistSkippedReasons 以了解详情(例如 NON_ASSIST_SEEKING_QUERY_IGNORED 表示简短的问候语)。
    • FAILED:调用遇到了执行错误。
  • 会话连续性:终端块包含 sessionInfo.session(会话资源名称)和 assistToken

在同一会话中继续对话

如需在多轮对话中保持上下文,请在后续请求中传递 sessionInfo 中的 session 字符串:

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://LOCATION-discoveryengine.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/collections/default_collection/engines/APP_ID/assistants/default_assistant:streamAssist" \
  -d '{
    "session": "projects/PROJECT_ID/locations/LOCATION/collections/default_collection/engines/APP_ID/sessions/SESSION_ID",
    "query": {
      "text": "Who is John Doe?"
    },
    "agentsSpec": {
      "agentSpecs": [
        {
          "agentId": "AGENT_ID"
        }
      ]
    }
  }'

如果您省略 session 字段或指定 - 作为会话 ID,API 会自动生成一个新的隔离会话。

限制

使用 streamAssist 调用代理时,存在以下限制:

  • 不支持的代理类型
    • 不支持工作流代理。
    • 通过 streamAssist 注册到 Gemini Enterprise 应用的 A2A 或 ADK 代理不受支持。如需使用 A2A 代理的注册端点直接调用该代理,请参阅使用 A2A 注册端点调用代理
  • 突变操作streamAssist API 针对对话式查询和通过连接器进行的只读检索进行了优化。不支持通过 streamAssist 以程序化方式执行更改性工具和操作(例如撰写电子邮件、创建日历活动或发送聊天消息)。尝试调用执行变异操作的代理工作流可能会导致静默失败或无根据的执行循环。

问题排查

您可以使用下表排查常见的 streamAssist 调用错误:

症状 可能的原因 解决方法
列出代理时出现 HTTP 404 错误 v1v1beta 端点调用 agents 改为向 v1alpha 端点发送列表请求。
即使设置了 agentsSpec,回答看起来仍然很笼统 无效的数值 agentId,或者查询过于宽泛,无法触发网域行为。 确认 v1alpha 代理列表中的确切数字 ID;发送特定领域的查询;检查回答文本中是否包含特定于代理的措辞。
未返回错误,但目标代理未执行 格式错误的 agentId 导致静默回退到默认编排。 验证 agentId 是否仅包含数字,并且与注册数据库列表中的某个 ID 完全一致。
响应状态返回 SKIPPED 输入被评估为非寻求帮助的查询(例如简短的问候语)。 发送实质性任务查询;检查响应载荷中的 assistSkippedReasons
HTTP 401HTTP 403 Permission Denied 缺少 OAuth 范围、IAM 角色不足或缺少配额项目标头。 验证调用者是否具有 discoveryengine.assistants.assist;确保 OAuth 范围包含 cloud-platform;如果使用 ADC,请添加 -H "X-Goog-User-Project: PROJECT_ID"

后续步骤