כדי להפעיל נציג רשום ספציפי, צריך לספק את השדה האופציונלי agentsSpec בבקשה ל-API בארכיטקטורת REST או בקריאה לספריית הלקוח של streamAssist. AgentsSpec API מגדיר את המפרט של הסוכנים שמשמשים לטיפול בבקשה. ה-Assistant מנתבת את השאילתות ישירות לסוכן הזה ושומרת על ההקשר של הסשן בין התורות.
בקצרה
| מפרט | פרטים |
|---|---|
| שיטת API | projects.locations.collections.engines.assistants.streamAssist |
| גרסאות של נקודות קצה | v1alpha כדי למצוא מזהי סוכנים, v1 כדי להתקשר אל streamAssist |
| פרמטר מפתח | agentsSpec.agentSpecs[].agentId |
| סוגי הנציגים הנתמכים | Core Assistant, Deep Research, סוכני צ'אט של Workflow Builder (לשעבר עם תכנות מינימלי) ותהליכי עבודה של Workflow Builder (ראו הפעלת תהליך עבודה) |
| הרשאת IAM נדרשת | discoveryengine.assistants.assist |
| היקף ההרשאות הנדרש של OAuth | https://www.googleapis.com/auth/cloud-platform |
לפני שמתחילים
- מפעילים את Discovery Engine API (
discoveryengine.googleapis.com) בפרויקט Google Cloud . - מוודאים שלחשבון המשתמש או לחשבון השירות יש תפקיד שמעניק את הרשאת ה-IAM
discoveryengine.assistants.assist, כמו עריכה ב-Discovery Engine (roles/discoveryengine.editor) או אדמין ב-Gemini Enterprise (roles/discoveryengine.agentspaceAdmin). - מוודאים שאפליקציית Gemini Enterprise (המנוע) נוצרה ומכילה לפחות סוכן רשום אחד.
- אם אתם מבצעים אימות באמצעות Application Default Credentials (ADC), ודאו שהלקוח שולח את הכותרת של הפרויקט לצורכי מכסה:
-H "X-Goog-User-Project: PROJECT_ID".
איפה נמצא מזהה האפליקציה והמיקום שלה
כדי להשתמש בכתובת ה-URL של streamAssist, צריך את מזהה המנוע ואת המיקום שלו (global, us או eu). אם אתם יודעים רק את השם המוצג של האפליקציה, אתם יכולים להציג את רשימת המנועים בפרויקט כדי לאתר את המזהה הבסיסי:
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 שנדרש בקריאה.
איך מוצאים את מזהה הסוכן
agentId הוא החלק האחרון בשם המשאב המלא של הנציג ב-Discovery Engine API:
projects/{project}/locations/{location}/collections/{collection}/engines/{engine}/assistants/{assistant}/agents/{AGENT_ID}
לסוכנים רשומים יש מזהה מספרי ארוך (לדוגמה, 15492003793394502655) במקום שם תצוגה ידידותי. בבקשה, ציין רק את המחרוזת המספרית הסופית {AGENT_ID}.
כדי לראות את רשימת הסוכנים שרשומים באפליקציה ולגלות את המזהים המספריים שלהם, קוראים את אוסף agents בנקודת הקצה v1alpha:
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: המצב התפעולי (למשלENABLEDאוPRIVATE). - אובייקט הגדרה שמציין את סוג הנציג (למשל
a2aAgentDefinition,lowCodeAgentDefinitionאוworkflowAgentDefinition).
לסכימת משאבי הסוכן המלאה, אפשר לעיין במאמרי העזרה של ה-API בארכיטקטורת REST agents.
שליחת שאילתות לסוכנים
כדי לשלוח שאילתות לנציג ספציפי, צריך ליצור את הבקשה עם ה-agentsSpec המתאים ולהפעיל אותה באמצעות REST או ספריות לקוח.
מבנה גוף הבקשה
כדי לנתב שאילתה לסוכן ספציפי, צריך לכלול את האובייקט האופציונלי agentsSpec בגוף בקשת ה-POST:
{
"query": {
"text": "QUERY_TEXT"
},
"session": "SESSION_RESOURCE_NAME",
"agentsSpec": {
"agentSpecs": [
{
"agentId": "AGENT_ID"
}
]
}
}
הפניה לשדה
-
agentsSpec(אובייקט, אופציונלי): מפרט של הסוכנים שמשמשים למילוי הבקשה. -
agentsSpec.agentSpecs[](מערך, אופציונלי): רשימה של הגדרות נציגים. אפשר לציין כמה סוכנים במערך הזה. agentsSpec.agentSpecs[].agentId(מחרוזת, חובה במפרט): המזהה של משאב הסוכן הרשום. השם צריך להתאים לתקן RFC-1034, והאורך המקסימלי שלו הוא 63 תווים.
אפשר לעיין במאמרי העזרה של streamAssist API בארכיטקטורת REST כדי לראות את הסכימה המלאה של הבקשה.
Call streamAssist
REST
הפקודה הבאה של curl שולחת שאילתה לנציג ספציפי באמצעות ה-API בארכיטקטורת REST:
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" } ] } }'
מחליפים את ה-placeholders הבאים:
-
LOCATION: מספר האזורים של שם המארח ושל נתיב המשאב (global,usאוeu). אם האפליקציה נמצאת במיקוםglobal, צריך להשמיט את הקידומת של המיקום משם המארח (discoveryengine.googleapis.com). -
PROJECT_ID: מזהה הפרויקט ב- Google Cloud . -
APP_ID: מזהה המנוע של Gemini Enterprise (אפשר למצוא אותו במאמר איך מוצאים את מזהה האפליקציה והמיקום). -
AGENT_ID: המזהה המספרי של הנציג (שמופיע בקטע איתור מזהה הנציג).
Python
בדוגמה הזו של Python מתבצעת קריאה ל-streamAssist באמצעות ספריית הלקוח google-cloud-discoveryengine:
# 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 מחזירה זרם של נתחי JSON דרך REST, או איטרטור של אובייקטים של תגובה בספריות לקוח:
- טקסט התשובה: טקסט התשובה המצטבר מגיע ב-
answer.replies[].groundedContent.content.text. כדי לשחזר את התשובה המלאה, צריך לשרשר את קטעי הטקסט האלה לפי סדר הקבלה. - קטעי חשיבה רציונלית: קטעים שמסומנים בסמל
"thought": trueמייצגים את תהליך החשיבה הרציונלית הפנימי של המודל. צריך לסנן את הקטעים האלה כשמציגים את הפלט הסופי למשתמשי הקצה. - מצב ההרצה: השדה
answer.stateמתקדם מ-IN_PROGRESSלמצב סופי:SUCCEEDED: הבקשה הושלמה ונוצרה תשובה.-
SKIPPED: השאילתה לא נלקחה בחשבון או שהמערכת דילגה עליה. כדאי לבדוק אתassistSkippedReasonsכדי לקבל פרטים (למשל,NON_ASSIST_SEEKING_QUERY_IGNOREDלברכות קצרות). -
FAILED: אירעה שגיאת הרצה בהפעלה.
- המשכיות של הסשן: החלק האחרון של הנתונים כולל את
sessionInfo.session(שם משאב הסשן) ואתassistToken.
להמשיך את השיחה באותו סשן
כדי לשמור על ההקשר בין התורות, צריך להעביר את המחרוזת session מ-sessionInfo בבקשות הבאות:
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 או מציינים את הערך - כמזהה הסשן, ה-API יוצר באופן אוטומטי סשן חדש ומבודד.
קריאה לתהליך עבודה
כדי להריץ תהליך עבודה ב-Workflow Builder, שולחים את אותה בקשה עם המזהה של תהליך העבודה ב-agentsSpec.agentSpecs[].agentId. כל שיחה מתחילה הפעלה ידנית של תהליך העבודה.
- הגרסה שמופעלת: אם תהליך העבודה פורסם, ההפעלה תהיה של הגרסה שפורסמה. שינויים שנשמרו ב-Workflow Builder אבל עדיין לא פורסמו לא משפיעים על הגורמים שמבצעים קריאות ל-API עד שמפרסמים אותם. אם תהליך העבודה אף פעם לא פורסם, הקריאה מפעילה את הטיוטה שלו.
- מי יכול להפעיל אותו: הבעלים והאדמינים של תהליך העבודה יכולים להפעיל אותו. משתמשים אחרים יכולים להתקשר לתהליך עבודה שפורסם אחרי ששיתפתם אותו איתם. רק הבעלים או אדמין יכולים לקרוא לתהליך עבודה שמעולם לא פורסם. גורמים אחרים שמנסים לקרוא לו מקבלים את השגיאה
HTTP 403. - טריגרים: בתהליך העבודה חייב להיות טריגר ידני אחד בדיוק. הקריאות נכשלות בתהליך עבודה שמשלב טריגר ידני עם טריגר אחר, או שיש בו יותר מטריגר ידני אחד.
- קלט: אי אפשר להגדיר את משתני הקלט של הטריגר הידני באמצעות
streamAssist. אם הטריגר הידני דורש קלט, ההפעלה נכשלת, גם אם לקלט יש ערך ברירת מחדל. הקלט האופציונלי ריק, וערכי ברירת המחדל שלו לא מוחלים. טקסט השאילתה מועבר לצומתי ה-LLM של תהליך העבודה, כך שאפשר לכלול שם נתונים, אבל הוא לא ממלא משתני קלט.
מגבלות
המגבלות הבאות חלות כשמתקשרים לנציגים באמצעות streamAssist:
- סוגי סוכנים שלא נתמכים: סוכני A2A או ADK שרשומים לאפליקציית Gemini Enterprise לא נתמכים דרך
streamAssist. כדי לקרוא לסוכן A2A ישירות באמצעות נקודת הקצה שלו במאגר, קראו את המאמר קריאה לסוכן באמצעות נקודת הקצה שלו במאגר A2A. - פעולות מוטטיביות: ה-API של
streamAssistמותאם לשאילתות שיחה ולאחזור לקריאה בלבד דרך מחברים. אין תמיכה בהפעלה פרוגרמטית של כלים ופעולות שמשנים נתונים (כמו ניסוח אימיילים, יצירת אירועים ביומן או שליחת הודעות בצ'אט) באמצעותstreamAssist. ניסיון להפעיל Agentic Workflows שמבצע פעולות מוטטיביות עלול לגרום לכשלים שקטים או ללולאות ביצוע לא מבוססות.
פתרון בעיות
אתם יכולים להיעזר בטבלה הבאה כדי לפתור שגיאות נפוצות בהפעלה של streamAssist:
| תיאור הבעיה | סיבה אפשרית | רזולוציה |
|---|---|---|
| שגיאת HTTP 404 כשמציגים את רשימת הנציגים | מתבצעת קריאה ל-agents בנקודת הקצה v1 או v1beta. |
במקום זאת, צריך לשלוח את בקשת הרשימה לנקודת הקצה v1alpha. |
התשובה נראית כללית למרות ההגדרה agentsSpec |
הערך המספרי agentId לא תקין, או שהשאילתה כללית מדי ולא מפעילה התנהגות של דומיין. |
צריך לוודא מהו מזהה המספר המדויק מv1alphaרשימת הסוכנים, לשלוח שאילתה ספציפית לדומיין ולבדוק אם יש בטקסט התשובה ניסוח ספציפי לסוכן. |
| לא הוחזרה שגיאה, אבל סוכן היעד לא פעל | agentId לא תקין גרם למעבר שקט לתזמור ברירת המחדל. |
צריך לוודא שהערך של agentId מורכב מספרות בלבד ותואם בדיוק למזהה מרשימת המרשם. |
התשובה שמתקבלת היא SKIPPED |
הקלט הוערך כשאילתה שלא מבקשת עזרה (כמו ברכה קצרה). | שולחים שאילתה מהותית לגבי המשימה ובודקים את assistSkippedReasons במטען הייעודי (payload) של התגובה. |
HTTP 401 או HTTP 403 Permission Denied |
חסר היקף OAuth, תפקיד IAM לא מספיק או כותרת פרויקט של מכסה. | מוודאים שלמתקשר יש discoveryengine.assistants.assist, שהיקף ה-OAuth כולל cloud-platform ומוסיפים -H "X-Goog-User-Project: PROJECT_ID" אם משתמשים ב-ADC. |
HTTP 403 עם Only the agent owner or an admin can run a draft of this agent. |
תהליך העבודה אף פעם לא פורסם, והגורם שקורא לו הוא לא הבעלים או האדמין שלו. | מפרסמים את תהליך העבודה ב-Workflow Builder ומשתפים אותו עם המתקשר. |
HTTP 403 עם User does not have permission to access the Agent. |
תהליך העבודה לא משותף עם המתקשר. | משתפים את תהליך העבודה עם המתקשר. |
| תהליך העבודה מתנהג כמו גרסה ישנה יותר | השיחה מופעלת על פי הגרסה שפורסמה, ולא על פי שינויים שלא פורסמו ב-Workflow Builder. | מפרסמים את תהליך העבודה. |
השיחה בתהליך העבודה מסתיימת עם answer.state FAILED ושגיאה INTERNAL |
בתהליך העבודה יש טריגר ידני ועוד טריגר, או יותר מטריגר ידני אחד. | משאירים טריגר ידני אחד. |