LangGraph
Auf dieser Seite wird erklärt, wie ein LangGraphAgent instrumentiert wird, wie Spans identifiziert werden und wie Bewertungsfelder extrahiert werden. Abschließend werden bewährte Verfahren zur Strukturierung eines LangGraph Agenten beschrieben, sodass er zuverlässig bewertet werden kann.
Topics
Instrumentieren Sie Ihren Agenten
Sie können einen LangGraph Agenten mit einer von zwei Instrumentierungsbibliotheken instrumentieren: OpenTelemetry(opentelemetry-instrumentation-langchain) oder OpenInference(openinference-instrumentation-langchain). Amazon Bedrock AgentCore Evaluations unterstützt beide Bibliotheken. Die Bibliotheken geben unterschiedliche Bereichsnamen aus und verwenden unterschiedliche Span-Attribute. Der Bewertungsservice extrahiert aus jedem die gleichen Werte.
Wenn Ihr Agent mit AWS Distro for OpenTelemetry (ADOT) ausgeführt wird, z. B. auf Amazon Bedrock AgentCore Runtime, müssen Sie keinen expliziten Instrumentierungscode hinzufügen. Es reicht aus, die Instrumentierungsbibliothek zu den Abhängigkeiten Ihres Projekts hinzuzufügen. ADOT erkennt es beim Start und aktiviert es automatisch.
Fügen Sie die Instrumentierungsbibliothek für den gewünschten Pfad zu Ihren Abhängigkeiten hinzu. In den folgenden Beispielen wird eine Mindestversion angehängt. Verwenden Sie die neueste verfügbare Version, sofern Sie keinen Grund dafür haben.
Beispiel
- OpenTelemetry
-
HINWEIS: Verwenden Sie Version 0.55.0 oder höher. Version 0.55.0 fügte Unterstützung für die neueren OpenTelemetry Generative-AI-Agent-Span-Konventionen hinzu, auf denen sich der Evaluierungsservice stützt.
Fügen Sie Ihre Abhängigkeiten hinzuopentelemetry-instrumentation-langchain. Der ausgegebene Bereichsname lautetopentelemetry.instrumentation.langchain.
requirements.txt:
opentelemetry-instrumentation-langchain>=0.55.0
pyproject.toml:
[project]
dependencies = [
"opentelemetry-instrumentation-langchain>=0.55.0",
]
- OpenInference
-
Fügen openinference-instrumentation-langchain Sie Ihre Abhängigkeiten hinzu. Der ausgegebene Bereichsname lautetopeninference.instrumentation.langchain.
requirements.txt:
openinference-instrumentation-langchain>=0.1.62
pyproject.toml:
[project]
dependencies = [
"openinference-instrumentation-langchain>=0.1.62",
]
Die Instrumentierung ist ein Schritt bei der Einrichtung der Beobachtbarkeit. Um Telemetrie zur Auswertung zu exportieren, schließen Sie die vollständigen Einstellungen unter Beobachtbarkeit einrichten ab.
Wie werden Spannweiten identifiziert
Das zur Klassifizierung von Spans verwendete Attribut unterscheidet sich zwischen den beiden Instrumentierungsbibliotheken.
Beispiel
- OpenTelemetry
-
In der OpenTelemetry Instrumentierungsbibliothek werden Spans anhand des traceloop.span.kind Attributs klassifiziert. Neuere Versionen werden ebenfalls festgelegt. gen_ai.operation.name
| Typ der Spanne |
Identifizierendes Attribut |
|
Agent aufrufen
|
traceloop.span.kind= workflow (auch gen_ai.operation.name =invoke_agent)
|
|
Tool ausführen
|
traceloop.span.kind= tool (auch gen_ai.operation.name =execute_tool)
|
|
Inferenz
|
gen_ai.operation.name = chat
|
- OpenInference
-
Die OpenInference Instrumentierungsbibliothek klassifiziert Spannweiten anhand des openinference.span.kind Attributs.
| Typ der Spannweite |
Identifizierendes Attribut |
|
Agent aufrufen
|
openinference.span.kind= oder CHAIN AGENT
|
|
Tool ausführen
|
openinference.span.kind = TOOL
|
|
Inferenz
|
openinference.span.kind = LLM
|
Beim Invoke Agent Span enthalten Eingabe und Ausgabe keine saubere Liste pro Nachricht. Stattdessen ist der Inhalt der serialisierte LangChain Graphstatus: eine JSON-Zeichenfolge, die den vollständigen Status umschließt. Die genaue Form dieses serialisierten Zustands unterscheidet sich zwischen den beiden Instrumentierungsbibliotheken. In beiden Fällen analysiert der Dienst ihn, um die Benutzeraufforderung (die menschliche Nachricht) und die Antwort des Agenten (die KI-Nachricht) zu finden.
LangGraph serialisiert auch Nachrichtenrollen in mehr als einer Form. Eine Rolle kann als kleingeschriebener Wert (human,ai,tool) oder als LangChain Nachrichtenklassenname (HumanMessage,,AIMessage) erscheinen. ToolMessage Der Dienst erkennt beide Formen.
Der Speicherort dieser Inhalte hängt davon ab, wie Telemetriedaten erfasst wurden. Das identifizierende Attribut (traceloop.span.kindoderopeninference.span.kind) befindet sich in beiden Fällen auf der Spanne. Weitere Informationen finden Sie unter Spans, Ereignisdatensätze und Telemetriesignale.
Wenn die Telemetrie aufgeteilt wird, liest der Dienst Inhalte aus dem Ereignisdatensatz, der jeder Spanne zugeordnet ist:
-
Benutzeraufforderung und Antwort des Agenten: aus dem Ereignisdatensatz des Invoke Agent Span, in und. body.input body.output
-
Werkzeugaufruf: Der Werkzeugname aus dem Bereich „Tool ausführen“. Die Werkzeugargumente und das Ergebnis stammen aus dem Ereignisdatensatz dieser Spanne, in body.input undbody.output.
Beispiele finden Sie unter Beispiel für Spans mit Ereignisdatensätzen.
Wenn die Telemetrie nicht aufgeteilt wird, verbleibt derselbe Inhalt als Attribute im Bereich. Die Attribute hängen von der Instrumentierungsbibliothek ab:
-
OpenTelemetry:
-
Benutzeraufforderung und Agentenantwort: von gen_ai.task.input und nach gen_ai.task.output dem Invoke Agent Span.
-
Werkzeugaufruf: der Werkzeugname von gen_ai.tool.name und die Argumente und das Ergebnis von gen_ai.tool.call.arguments und gen_ai.tool.call.result im Bereich des Ausführungswerkzeugs.
-
OpenInference:
-
Benutzereingabe und Agentenantwort: von input.value und nach output.value dem Invoke-Agent-Span.
-
Werkzeugaufruf: der Werkzeugname von tool.name und die Argumente und das Ergebnis von input.value und output.value im Bereich des Ausführungswerkzeugs.
Beispiele finden Sie unter Beispielbereiche ohne Ereignisdatensätze.
Beispiel für Zeitspannen mit Ereignisdatensätzen
Wenn die Telemetrie aufgeteilt wird, enthält die Spanne die identifizierenden Attribute und der Inhalt befindet sich in einem korrelierten Ereignisdatensatz. Die folgenden Beispiele stammen von einem LangGraph Reiseplanungsagenten, der auf Amazon AgentCore Bedrock Runtime eingesetzt wurde. Derselbe Agent wird unter jeder Instrumentierungsbibliothek angezeigt.
Bei diesen Beispielen handelt es sich nicht um vollständige Datenreihen. Sie zeigen repräsentative Daten aus einer echten Agenteninteraktion, wobei einige Felder weggelassen und lange Werte aus Gründen der Lesbarkeit gekürzt wurden.
OpenTelemetry
Beispiel
- Invoke agent span
-
Das traceloop.span.kind Attribut (workflow) identifiziert dies als Span für den Aufruf-Agenten. Neuere Bibliotheksversionen haben auch den Wert = gesetzt. gen_ai.operation.name invoke_agent
{
"traceId": "6a01eef11066751d68f90def0da1f80a",
"spanId": "ba1833fa7f097041",
"parentSpanId": "836a5ccf9a2186cc",
"name": "travel_agent.workflow",
"kind": "INTERNAL",
"scope": {
"name": "opentelemetry.instrumentation.langchain",
"version": "0.60.0"
},
"startTimeUnixNano": 1778511607308521744,
"endTimeUnixNano": 1778511610930280395,
"durationNano": 3621758651,
"attributes": {
"traceloop.span.kind": "workflow",
"gen_ai.operation.name": "invoke_agent",
"gen_ai.agent.name": "travel_agent",
"gen_ai.provider.name": "langgraph",
"traceloop.workflow.name": "travel_agent",
"session.id": "sea-nyc-trip-2-turns-adot_v17_opentelemetry_0_60_0"
},
"status": {
"code": "OK"
}
}
Der korrelierte Ereignisdatensatz enthält die Konversation. Bei jeder Nachricht content handelt es sich um den serialisierten LangChain Graphstatus. Die Eingabe umschließt den Status unter einem inputs Schlüssel. Die Ausgabe umschließt ihn unter einen outputs Schlüssel, wobei jede Nachricht ein LangChain Konstruktorobjekt ist. Die Benutzeraufforderung ist die menschliche Nachricht und die Antwort des Agenten ist die KI-Nachricht innerhalb dieses serialisierten Zustands.
{
"spanId": "ba1833fa7f097041",
"traceId": "6a01eef11066751d68f90def0da1f80a",
"scope": {
"name": "opentelemetry.instrumentation.langchain"
},
"body": {
"input": {
"messages": [
{
"content": "{\"inputs\": {\"messages\": [{\"role\": \"user\", \"content\": \"Hey, how can you help me\"}]}, \"tags\": [], \"metadata\": {\"ls_integration\": \"langchain_create_agent\", \"lc_agent_name\": \"travel_agent\", \"thread_id\": \"sea-nyc-trip-2-turns-adot_v17_opentelemetry_0_60_0\"}, \"kwargs\": {\"name\": \"travel_agent\"}}",
"role": "user"
}
]
},
"output": {
"messages": [
{
"content": "{\"outputs\": {\"messages\": [{\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain\", \"schema\", \"messages\", \"HumanMessage\"], \"kwargs\": {\"content\": \"Hey, how can you help me\", \"type\": \"human\", \"id\": \"12345678-1234-1234-1234-123456789012\"}}, {\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain\", \"schema\", \"messages\", \"AIMessage\"], \"kwargs\": {\"content\": \"Hello! I'm your travel planning assistant ...\", \"type\": \"ai\"}}]}, \"kwargs\": {\"tags\": []}}",
"role": "assistant"
}
]
}
}
}
- Execute tool span
-
Das traceloop.span.kind Attribut (tool) identifiziert dies als einen Bereich für das Ausführungswerkzeug. Es gen_ai.tool.name enthält den Namen des Tools und gen_ai.operation.name =execute_tool.
{
"traceId": "6a01eefa5c52f3d86a35038f35f5ba30",
"spanId": "5b332f3cd15ace04",
"parentSpanId": "922a21edc04eba29",
"name": "execute_tool search_flights",
"kind": "INTERNAL",
"scope": {
"name": "opentelemetry.instrumentation.langchain",
"version": "0.60.0"
},
"startTimeUnixNano": 1778511614892698232,
"endTimeUnixNano": 1778511614893399618,
"durationNano": 701386,
"attributes": {
"traceloop.span.kind": "tool",
"gen_ai.operation.name": "execute_tool",
"gen_ai.tool.name": "search_flights",
"gen_ai.tool.type": "function",
"gen_ai.tool.description": "Search for available flights between cities.",
"gen_ai.provider.name": "langgraph",
"traceloop.workflow.name": "travel_agent",
"session.id": "sea-nyc-trip-2-turns-adot_v17_opentelemetry_0_60_0"
},
"status": {
"code": "OK"
}
}
Der korrelierte Ereignisdatensatz enthält die Werkzeugeingabe (Argumente) und die Ausgabe (Ergebnis, serialisiert als a LangChain ToolMessage).
{
"spanId": "5b332f3cd15ace04",
"traceId": "6a01eefa5c52f3d86a35038f35f5ba30",
"scope": {
"name": "opentelemetry.instrumentation.langchain"
},
"body": {
"input": {
"messages": [
{ "content": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}" }
]
},
"output": {
"messages": [
{
"role": "tool",
"name": "search_flights",
"content": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"flights\": [ ... ]}"
}
]
}
}
}
OpenInference
In der OpenInference Bibliothek ist der Span-Typ im openinference.span.kind Attribut enthalten, und die Eingabe und Ausgabe des Agenten werden im korrelierten Ereignisdatensatz serialisiert.
Beispiel
- Invoke agent span
-
Das openinference.span.kind Attribut (oder AGENT wenn das Diagramm mit einem Namen kompiliert wird) identifiziertCHAIN, dass es sich um einen Span für den Aufruf-Agenten handelt.
{
"traceId": "6a387ee61078243c1cc455ed45c6c313",
"spanId": "0a7990d804132a9b",
"parentSpanId": "29ae22014173881c",
"name": "LangGraph",
"kind": "INTERNAL",
"scope": {
"name": "openinference.instrumentation.langchain",
"version": "0.1.66"
},
"startTimeUnixNano": 1782087405949310976,
"endTimeUnixNano": 1782087408945828864,
"durationNano": 2996517888,
"attributes": {
"openinference.span.kind": "CHAIN",
"input.mime_type": "application/json",
"output.mime_type": "application/json",
"llm.input_messages.0.message.role": "user",
"session.id": "sea-nyc-trip-2-turns-oi-0-1-66"
},
"status": {
"code": "OK"
}
}
Der korrelierte Ereignisdatensatz enthält die Konversation. Bei der Benutzeraufforderung handelt es sich um die Nachricht in der menschlichen Rolle und die Antwort des Agenten um die AI-role Nachricht in den serialisierten Nachrichten.
{
"spanId": "0a7990d804132a9b",
"traceId": "6a387ee61078243c1cc455ed45c6c313",
"scope": {
"name": "openinference.instrumentation.langchain"
},
"body": {
"input": {
"messages": [
{
"role": "user",
"content": "{\"messages\": [{\"role\": \"user\", \"content\": \"Hey, how can you help me\"}]}"
}
]
},
"output": {
"messages": [
{
"content": "{\"messages\": [{\"type\": \"human\", \"data\": {\"content\": \"Hey, how can you help me\", ...}}, {\"type\": \"ai\", \"data\": {\"content\": \"Hello! I'm your travel planning assistant ...\", ...}}]}",
"role": "assistant"
}
]
}
}
}
- Execute tool span
-
Das openinference.span.kind Attribut (TOOL) identifiziert dies als einen Bereich für das Ausführungstool; es tool.name enthält den Namen des Tools.
{
"traceId": "6a387ef07b8f4f3732fab45d3c0b51ff",
"spanId": "ab105c12cc40048f",
"parentSpanId": "9b2d4e72760690b4",
"name": "search_flights",
"kind": "INTERNAL",
"scope": {
"name": "openinference.instrumentation.langchain",
"version": "0.1.66"
},
"startTimeUnixNano": 1782087411724620032,
"endTimeUnixNano": 1782087411725306880,
"durationNano": 686848,
"attributes": {
"openinference.span.kind": "TOOL",
"tool.name": "search_flights",
"tool.description": "Search for available flights between cities.",
"input.mime_type": "application/json",
"output.mime_type": "application/json",
"session.id": "sea-nyc-trip-2-turns-oi-0-1-66"
},
"status": {
"code": "OK"
}
}
Der korrelierte Ereignisdatensatz enthält die Werkzeugeingabe (Argumente) und die Ausgabe (Ergebnis, serialisiert als a LangChain ToolMessage).
{
"spanId": "ab105c12cc40048f",
"traceId": "6a387ef07b8f4f3732fab45d3c0b51ff",
"scope": {
"name": "openinference.instrumentation.langchain"
},
"body": {
"input": {
"messages": [
{
"role": "user",
"content": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}"
}
]
},
"output": {
"messages": [
{
"content": "{\"type\": \"tool\", \"data\": {\"content\": \"{\\\"origin\\\": \\\"SEA\\\", \\\"destination\\\": \\\"NYC\\\", \\\"flights\\\": [ ... ]}\", \"type\": \"tool\", \"name\": \"search_flights\", \"tool_call_id\": \"toolu_bdrk_01LzXXJCfpfuS7Bpf7e1qLMg\", \"status\": \"success\"}}",
"role": "assistant"
}
]
}
}
}
Beispiel: Spans ohne Ereignisdatensätze
Wenn die Telemetrie nicht aufgeteilt wird, verbleibt derselbe Inhalt in den Span-Attributen und es wird kein separater Ereignisdatensatz erstellt. Die folgenden Beispiele stammen von einem LangGraph Reiseplanungsbüro. Derselbe Agent wird unter jeder Instrumentenbibliothek angezeigt.
Bei diesen Beispielen handelt es sich nicht um vollständige Datenreihen. Sie zeigen repräsentative Daten aus einer echten Agenteninteraktion, wobei einige Felder weggelassen und lange Werte aus Gründen der Lesbarkeit gekürzt wurden.
OpenTelemetry
Beispiel
- Invoke agent span
-
Das gen_ai.task.input Attribut enthält die Benutzeraufforderung, und das gen_ai.task.output Attribut enthält den serialisierten Status der Agentenantwort. Bei beiden handelt es sich um den serialisierten LangChain Graphstatus.
{
"traceId": "6a4de7b85e61747e6b568a1f4768e89d",
"spanId": "31ea3d5882dac680",
"name": "LangGraph.workflow",
"kind": "INTERNAL",
"scope": {
"name": "opentelemetry.instrumentation.langchain",
"version": "0.62.1"
},
"attributes": {
"traceloop.span.kind": "workflow",
"gen_ai.operation.name": "invoke_agent",
"gen_ai.agent.name": "LangGraph",
"gen_ai.task.input": "{\"inputs\": {\"messages\": [{\"role\": \"user\", \"content\": \"Hey, how can you help me\"}]}, \"tags\": [], \"metadata\": { ... }, \"kwargs\": {\"name\": \"LangGraph\"}}",
"gen_ai.task.output": "{\"outputs\": {\"messages\": [{\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain\", \"schema\", \"messages\", \"HumanMessage\"], \"kwargs\": {\"content\": \"Hey, how can you help me\", \"type\": \"human\"}}, {\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain\", \"schema\", \"messages\", \"AIMessage\"], \"kwargs\": {\"content\": \"Hello! I'm your travel planning assistant ...\", \"type\": \"ai\"}}]}, \"kwargs\": {\"tags\": []}}",
"session.id": "sea-nyc-trip-2-turns-unified"
},
"status": {
"code": "OK"
}
}
- Execute tool span
-
Das gen_ai.tool.call.arguments Attribut enthält die Werkzeugargumente und das gen_ai.tool.call.result Attribut enthält das Werkzeugergebnis, serialisiert als. LangChain ToolMessage
{
"traceId": "6a4de7c376913db82e6f0f336a16731d",
"spanId": "b64c37adefae74f0",
"name": "execute_tool search_flights",
"kind": "INTERNAL",
"scope": {
"name": "opentelemetry.instrumentation.langchain",
"version": "0.62.1"
},
"attributes": {
"traceloop.span.kind": "tool",
"gen_ai.operation.name": "execute_tool",
"gen_ai.tool.name": "search_flights",
"gen_ai.tool.description": "Search for available flights between cities.",
"gen_ai.tool.call.arguments": "{\"input_str\": \"{'origin': 'SEA', 'destination': 'NYC', 'date': '2025-03-15'}\", \"inputs\": {\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}, \"metadata\": { ... }}",
"gen_ai.tool.call.result": "{\"output\": {\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain\", \"schema\", \"messages\", \"ToolMessage\"], \"kwargs\": {\"content\": \"{\\\"origin\\\": \\\"SEA\\\", \\\"destination\\\": \\\"NYC\\\", \\\"flights\\\": [ ... ]}\", \"type\": \"tool\", \"name\": \"search_flights\", \"status\": \"success\"}}}",
"session.id": "sea-nyc-trip-2-turns-unified"
},
"status": {
"code": "OK"
}
}
OpenInference
Beispiel
- Invoke agent span
-
Das input.value Attribut enthält die Benutzeraufforderung, und das output.value Attribut enthält den serialisierten Status der Agentenantwort.
{
"traceId": "6a387ee61078243c1cc455ed45c6c313",
"spanId": "b8c0b67876b78b91",
"name": "LangGraph",
"kind": "INTERNAL",
"scope": {
"name": "openinference.instrumentation.langchain",
"version": "0.1.66"
},
"attributes": {
"openinference.span.kind": "CHAIN",
"input.value": "{\"messages\": [{\"role\": \"user\", \"content\": \"Hey, how can you help me\"}]}",
"output.value": "{\"messages\": [{\"type\": \"human\", \"data\": {\"content\": \"Hey, how can you help me\"}}, {\"type\": \"ai\", \"data\": {\"content\": \"Hello! I'm your travel planning assistant ...\"}}]}",
"session.id": "sea-nyc-trip-2-turns-oi-0-1-66"
},
"status": {
"code": "OK"
}
}
- Execute tool span
-
Das input.value Attribut enthält die Werkzeug-Argumente und das output.value Attribut enthält das Werkzeugergebnis, serialisiert als. LangChain ToolMessage
{
"traceId": "6a387ef07b8f4f3732fab45d3c0b51ff",
"spanId": "58752612d9b22ae1",
"name": "search_flights",
"kind": "INTERNAL",
"scope": {
"name": "openinference.instrumentation.langchain",
"version": "0.1.66"
},
"attributes": {
"openinference.span.kind": "TOOL",
"tool.name": "search_flights",
"tool.description": "Search for available flights between cities.",
"input.value": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}",
"output.value": "{\"type\": \"tool\", \"data\": {\"content\": \"{\\\"origin\\\": \\\"SEA\\\", \\\"destination\\\": \\\"NYC\\\", \\\"flights\\\": [ ... ]}\", \"name\": \"search_flights\"}}",
"session.id": "sea-nyc-trip-2-turns-oi-0-1-66"
},
"status": {
"code": "OK"
}
}
Bewährte Methoden für Agenten LangGraph
Die Art und Weise, wie Sie einen LangGraph Agenten erstellen und aufrufen, wirkt sich darauf aus, was in seiner Telemetrie angezeigt wird und wie zuverlässig der Agent bewertet werden kann. Mit den folgenden Methoden wird sichergestellt, dass die Benutzeraufforderung, die Antwort des Agenten und die Aktivität des Tools wiederhergestellt werden können.
1. Wählen Sie ein Konstruktionsmuster für Agenten
Es gibt zwei gängige Methoden, einen LangGraph Agenten zu erstellen:
-
Vorkonfiguriert create_agent: der schnellste Weg, um loszulegen. Pro Runde wird ein einziger Agent-Aufruf-Span erzeugt, wobei die Konversation die integrierte Ausführungsschleife LangGraph durchläuft. Verwenden Sie diese Option, wenn Sie einen Standard-Reason-Act-Agenten ohne benutzerdefinierten Kontrollfluss benötigen.
from langchain.agents import create_agent
agent = create_agent(model=model, tools=[search_flights, book_flight])
-
Benutzerdefiniert StateGraph: gibt Ihnen die volle Kontrolle über Knoten, Kanten und bedingtes Routing. Die Ausführung jedes Knotens erhält eine eigene Spanne, sodass die Traces detaillierter sind. Verwenden Sie dies, wenn Sie eine benutzerdefinierte Orchestrierung benötigen.
from langgraph.graph import StateGraph, START, END
from typing_extensions import TypedDict
class State(TypedDict):
messages: list
graph = StateGraph(State)
graph.add_node("generate_response", generate_response)
graph.add_node("tools", run_tools)
graph.add_edge(START, "generate_response")
agent = graph.compile()
Beide Muster werden auf die gleiche Weise ausgewertet. Der Unterschied besteht in der Granularität der Ablaufverfolgung.
2. Verwenden Sie Nachrichten in Ihrem Graphenstatus (empfohlen)
Der Bewertungsservice rekonstruiert die Konversation anhand der Eingabe- und Ausgabenachrichten des Agenten. Die Verwendung eines messages Felds ist nicht verpflichtend, ermöglicht aber die zuverlässigste Extraktion. Für ein benutzerdefiniertes StateGraph Feld sollten Sie die Konversation in einem messages Feld in Ihrem Bundesstaat speichern:
-
messagesIn Ihrem Bundesland angeben (empfohlen). Sie können weitere benutzerdefinierte Felder hinzufügen (z. user_id B. Metadaten). Wenn messages vorhanden, findet die Standardextraktion die Benutzeraufforderung und die Antwort des Agenten direkt. Wenn sie nicht vorhanden messages ist, rekonstruiert der Service die Konversation anhand einzelner Inferenzspannen, was weniger zuverlässig ist.
-
Anfügen, nicht ersetzen. Halten Sie sich an die LangGraph Konvention, neue Nachrichten an die Liste anzuhängen, anstatt sie zu überschreiben, sodass der gesamte Konversationsverlauf erhalten bleibt.
-
Verwenden Sie kanonische LangChain Nachrichtentypen (HumanMessage,,,AIMessage). ToolMessage SystemMessage Die Instrumentierung serialisiert diese korrekt und der Dienst erkennt ihre Rollen.
3. Übergeben Sie die Benutzernachricht in einem unterstützten Format
Wenn Sie einen LangGraph Agenten aufrufen, fügen Sie die Benutzernachricht zum messages Status des Diagramms hinzu. LangGraph akzeptiert die Nachricht in drei austauschbaren Formaten, und AgentCore Evaluations unterstützt alle Formate. Jedes erzeugt Zeitspannen und Ereignisdatensätze, die der Service lesen kann.
-
Tupel: ein (role, content) Paar:
agent.invoke({"messages": [("user", user_message)]}, config=config)
-
LangChain Nachrichtenobjekt: a HumanMessage (oder eine andere Nachrichtenklasse):
from langchain_core.messages import HumanMessage
agent.invoke({"messages": [HumanMessage(content=user_message)]}, config=config)
-
Wörterbuch: ein {"role", "content"} Wörterbuch:
agent.invoke({"messages": [{"role": "user", "content": user_message}]}, config=config)
Alle drei Formate führen zu demselben messages Status, sodass die Benutzeraufforderung und die Antwort des Agenten unabhängig davon, welches Sie wählen, identisch extrahiert werden.