本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。
為 AgentCore 評估設定 LangGraph 遙測
此頁面說明如何檢測 LangGraph 代理程式、如何識別範圍,以及如何擷取評估欄位。AgentCore Evaluations 支援建置在 Python 和 TypeScript 中的 LangGraph 代理程式;此頁面分別涵蓋 Python 代理程式支援和 TypeScript 代理程式支援中的每種語言。它會關閉並採用最佳實務來建構 LangGraph 代理程式,以便可靠地評估它。
主題
Python 代理程式支援
Python LangGraph 代理程式會在範圍名稱 opentelemetry.instrumentation.langchain(OpenTelemetry) 或 openinference.instrumentation.langchain(OpenInference) 下發出。
檢測您的代理程式
您可以使用兩種檢測程式庫之一來檢測 LangGraph 代理程式:OpenTelemetry (opentelemetry-instrumentation-langchain) 或 OpenInference ()openinference-instrumentation-langchain。Amazon Bedrock AgentCore Evaluations 支援這兩個程式庫。程式庫會發出不同的範圍名稱,並使用不同的跨度屬性。評估服務會從每個 中擷取相同的值。
當您的代理程式使用 AWS Distro for OpenTelemetry (ADOT) 執行時,例如在 Amazon Bedrock AgentCore 執行期,您不需要新增明確的檢測程式碼。將檢測程式庫新增至專案的相依性已足夠。ADOT 在啟動時發現它並自動啟用它。
為您想要的相依性路徑新增檢測程式庫。下列範例會鎖定最低版本;除非您有鎖定原因,否則請使用最新的可用版本。
範例
- OpenTelemetry
-
注意:使用 版本 0.55.0 或更新版本。0.55.0 版新增了對 GitHub 網站上較新 OpenTelemetry 生成式 AI 代理程式跨度慣例的支援,評估服務依賴這些慣例。
將 opentelemetry-instrumentation-langchain新增至您的相依性。發出的範圍名稱為 opentelemetry.instrumentation.langchain。
requirements.txt:
opentelemetry-instrumentation-langchain>=0.55.0
pyproject.toml:
[project]
dependencies = [
"opentelemetry-instrumentation-langchain>=0.55.0",
]
- OpenInference
-
將 openinference-instrumentation-langchain新增至您的相依性。發出的範圍名稱為 openinference.instrumentation.langchain。
requirements.txt:
openinference-instrumentation-langchain>=0.1.62
pyproject.toml:
[project]
dependencies = [
"openinference-instrumentation-langchain>=0.1.62",
]
如何識別跨度
用於分類範圍的屬性在兩個檢測程式庫之間不同。
範例
- OpenTelemetry
-
OpenTelemetry 檢測程式庫會使用 traceloop.span.kind 屬性來分類跨度,而最新版本也會設定 gen_ai.operation.name。
| 跨度類型 |
識別屬性 |
|
叫用代理程式
|
traceloop.span.kind = workflow(也是 gen_ai.operation.name = invoke_agent)
|
|
執行工具
|
traceloop.span.kind = tool(也是 gen_ai.operation.name = execute_tool)
|
|
Inference
|
gen_ai.operation.name = chat
|
- OpenInference
-
OpenInference 檢測程式庫會使用 openinference.span.kind 屬性分類跨度。
| 跨度類型 |
識別屬性 |
|
叫用代理程式
|
openinference.span.kind = CHAIN或 AGENT
|
|
執行工具
|
openinference.span.kind = TOOL
|
|
Inference
|
openinference.span.kind = LLM
|
對於調用代理程式範圍,輸入和輸出不包含乾淨的每則訊息清單。反之,內容是序列化 LangChain 圖形狀態:包裝完整狀態的 JSON 字串。此序列化狀態的確切形狀在兩個檢測程式庫之間有所不同。在這兩種情況下,服務都會剖析它,以尋找使用者提示 (人工訊息) 和客服人員回應 (AI 訊息)。
LangGraph 也會以多種形式序列化訊息角色。角色可以顯示為小寫值 (human、ai、tool) 或 LangChain 訊息類別名稱 (HumanMessage、AIMessage、)ToolMessage。服務會辨識這兩種形式。
此內容的位置取決於收集遙測的方式。在這兩種情況下,識別屬性 (traceloop.span.kind 或 openinference.span.kind) 位於跨度。如需詳細資訊,請參閱遙測設定和交付。
使用分割遙測,服務會從與每個範圍相關的事件記錄中讀取內容:
如需詳細資訊,請參閱分割遙測中的範例跨度。
使用統一遙測,相同的內容會保留在跨度上做為屬性。屬性取決於檢測程式庫:
-
OpenTelemetry:
-
OpenInference:
如需詳細資訊,請參閱統一遙測中的範例跨度。
分割遙測中的範例範圍
使用分割遙測時,跨度會攜帶識別屬性,並且內容存在於相關事件記錄中。下列範例來自部署在 Amazon Bedrock AgentCore 執行期上的 Python LangGraph 行程規劃代理程式。相同的代理程式會顯示在每個檢測程式庫下方。
這些範例不是完整的跨度。它們會顯示來自實際客服人員互動的代表性資料,省略一些欄位,並截斷長值以保證可讀性。
OpenTelemetry
範例
- Invoke agent span
-
traceloop.span.kind 屬性 (workflow) 將此識別為調用代理程式範圍;最近的程式庫版本也會設定 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"
}
}
相關事件記錄會承載對話。每個訊息的 content都是序列化 LangChain 圖形狀態。輸入會在 inputs金鑰下包裝 狀態。輸出將其包裝在 outputs金鑰下,每個訊息都是 LangChain 建構函數物件。使用者提示是人工訊息,客服人員回應是該序列化狀態內的 AI 訊息。
{
"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
-
traceloop.span.kind 屬性 (tool) 將此識別為執行工具範圍; gen_ai.tool.name會保留工具名稱 並 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"
}
}
相關事件記錄會攜帶工具輸入 (引數) 和輸出 (結果,序列化為 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
使用 OpenInference 程式庫時,跨度類型會在 openinference.span.kind 屬性中承載,而代理程式輸入和輸出會在相關事件記錄中序列化。
範例
- Invoke agent span
-
openinference.span.kind 屬性 ( CHAIN或使用名稱編譯圖形AGENT時) 會將此識別為叫用代理程式範圍。
{
"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"
}
}
相關事件記錄會承載對話。使用者提示是人力角色訊息,客服人員回應是序列化訊息中的 AI 角色訊息。
{
"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
-
openinference.span.kind 屬性 (TOOL) 將此識別為執行工具範圍; tool.name會保留工具名稱。
{
"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"
}
}
相關事件記錄會攜帶工具輸入 (引數) 和輸出 (結果,序列化為 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"
}
]
}
}
}
統一遙測中的範例範圍
使用統一遙測,相同的內容會保留在跨屬性上,而且不會產生單獨的事件記錄。下列範例來自 Python LangGraph 行程規劃代理程式。相同的代理程式會顯示在每個檢測程式庫下方。
這些範例不是完整的跨度。它們會顯示來自實際客服人員互動的代表性資料,省略一些欄位,並截斷長值以保證可讀性。
OpenTelemetry
範例
- Invoke agent span
-
gen_ai.task.input 屬性會保留使用者提示,而gen_ai.task.output屬性會保留具有代理程式回應的序列化狀態。兩者都是序列化 LangChain 圖形狀態。
{
"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
-
gen_ai.tool.call.arguments 屬性會保留工具引數,而 gen_ai.tool.call.result 屬性會保留工具結果,序列化為 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
範例
- Invoke agent span
-
input.value 屬性會保留使用者提示,而output.value屬性會保留具有代理程式回應的序列化狀態。
{
"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
-
input.value 屬性會保留工具引數,而 output.value 屬性會保留工具結果,序列化為 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"
}
}
TypeScript 代理程式支援
TypeScript LangGraph 代理程式會發出與 Python 代理程式相同的跨度類型,因此評估服務會以相同的方式讀取。有三個 TypeScript 檢測程式庫,每個程式庫都有自己的範圍名稱和跨分類慣例。
檢測您的代理程式
為您想要的 TypeScript 相依性路徑新增檢測程式庫。下列範例會鎖定最低版本;除非您有鎖定原因,否則請使用最新的可用版本。
範例
- ADOT (OpenTelemetry)
-
對於 ADOT 上的 TypeScript 代理程式,將 AWS Distro Node 自動檢測套件 (@aws/aws-distro-opentelemetry-node-autoinstrumentation) 新增至您的相依性。它包含內建的 LangChain 檢測,其會在啟動時啟用並發出範圍名稱 @aws/aws-distro-opentelemetry-instrumentation-langchain。
package.json:
{
"dependencies": {
"@aws/aws-distro-opentelemetry-node-autoinstrumentation": "^0.12.0"
}
}
- Traceloop (OpenTelemetry)
-
將 Traceloop LangChain 檢測 (@traceloop/instrumentation-langchain) 新增至您的相依性。發出的範圍名稱為 @traceloop/instrumentation-langchain。
package.json:
{
"dependencies": {
"@traceloop/instrumentation-langchain": "^0.27.0"
}
}
- OpenInference
-
將 @arizeai/openinference-instrumentation-langchain新增至您的相依性。發出的範圍名稱為 @arizeai/openinference-instrumentation-langchain。
package.json:
{
"dependencies": {
"@arizeai/openinference-instrumentation-langchain": "^4.0.14"
}
}
如何識別跨度
跨度識別取決於檢測程式庫:
-
ADOT (OpenTelemetry): AWS Distro Node 自動檢測套件 (@aws/aws-distro-opentelemetry-node-autoinstrumentation),會發出範圍名稱 @aws/aws-distro-opentelemetry-instrumentation-langchain、集合 gen_ai.operation.name(invoke_agent、execute_tool、chat),與其他 ADOT 原生架構相同。
-
Traceloop (OpenTelemetry):來自 Traceloop (@traceloop/instrumentation-langchain) 的 OpenTelemetry JS 程式庫 traceloop.span.kind (workflow 代表叫用代理程式範圍, task代表工具範圍),與 Python OpenTelemetry 程式庫相符。請參閱 Python 代理程式支援下的跨度識別方式。
-
OpenInference:OpenInference JS 程式庫 (@arizeai/openinference-instrumentation-langchain) 集 openinference.span.kind(CHAIN 或 AGENT、TOOL、LLM),與 Python OpenInference 程式庫相同。
欄位擷取取決於檢測程式庫:
-
ADOT (OpenTelemetry):調用代理程式範圍是結構容器,對話內容存在於部分格式gen_ai.input.messages和gen_ai.output.messages屬性中的推論 (chat) 範圍。
-
Traceloop (OpenTelemetry):使用來自 Traceloop 的 OpenTelemetry JS 程式庫,對話處於序列化 LangChain 狀態的 traceloop.entity.input和 traceloop.entity.output 屬性。這符合 Python OpenTelemetry 程式庫;請參閱如何在 Python 代理程式支援下擷取評估欄位。 Python 代理程式支援
-
OpenInference:使用 OpenInference JS 程式庫時,對話會位於 input.value和 output.value 屬性中,而推論訊息也會出現在索引llm.input_messages.*和 llm.output_messages.* 屬性上。這符合 Python OpenInference 程式庫。
來自 TypeScript 代理程式的範例
下列範例來自部署在 Amazon Bedrock AgentCore 執行期和統一遙測的 TypeScript LangGraph 行程規劃代理程式。三個 TypeScript 檢測程式庫的每個程式庫下方都會顯示相同的代理程式。
這些範例不是完整的跨度。它們會顯示來自實際客服人員互動的代表性資料,省略一些欄位,並截斷長值以保證可讀性。
OpenTelemetry (ADOT 原生)
使用 ADOT 原生程式庫 (從 AWS Distro Node 自動檢測套件 發出範圍名稱 @aws/aws-distro-opentelemetry-instrumentation-langchain)@aws/aws-distro-opentelemetry-node-autoinstrumentation,調用代理程式範圍是結構容器,對話內容存在於部分格式gen_ai.input.messages和gen_ai.output.messages屬性的推論 (chat) 範圍上。
範例
- Invoke agent span
-
gen_ai.operation.name 屬性 (invoke_agent) 將此識別為調用代理程式範圍。跨度具有客服人員名稱和模型,但沒有對話內容。
{
"traceId": "6a6bd0a1c8d91ed1e70a3906b551618",
"spanId": "ba1833fa7f097041",
"name": "invoke_agent LangGraph",
"kind": "INTERNAL",
"scope": {
"name": "@aws/aws-distro-opentelemetry-instrumentation-langchain",
"version": "0.12.0"
},
"attributes": {
"gen_ai.operation.name": "invoke_agent",
"gen_ai.agent.name": "LangGraph",
"gen_ai.provider.name": "openai",
"gen_ai.request.model": "gpt-4o-mini",
"session.id": "sea-nyc-trip-2-turns"
},
"status": {
"code": "OK"
}
}
- Execute tool span
-
gen_ai.operation.name 屬性 (execute_tool) 將此識別為執行工具範圍; gen_ai.tool.name會保留工具名稱。gen_ai.tool.call.arguments 和 gen_ai.tool.call.result 屬性會保留工具引數和結果。
{
"traceId": "6a6bd0a25c52f3d86a35038f35f5ba30",
"spanId": "5b332f3cd15ace04",
"name": "execute_tool search_flights",
"kind": "INTERNAL",
"scope": {
"name": "@aws/aws-distro-opentelemetry-instrumentation-langchain",
"version": "0.12.0"
},
"attributes": {
"gen_ai.operation.name": "execute_tool",
"gen_ai.tool.name": "search_flights",
"gen_ai.tool.type": "function",
"gen_ai.tool.call.arguments": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}",
"gen_ai.tool.call.result": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"flights\": [ ... ]}",
"session.id": "sea-nyc-trip-2-turns"
},
"status": {
"code": "OK"
}
}
- Inference span
-
gen_ai.operation.name 屬性 (chat) 將此識別為推論範圍。gen_ai.input.messages 和 gen_ai.output.messages 屬性會保留部分格式的對話,並gen_ai.system_instructions保留系統提示。
{
"traceId": "6a6bd0a1c8d91ed1e70a3906b551618",
"spanId": "7c1f9a2b4d6e8a03",
"name": "chat gpt-4o-mini",
"kind": "INTERNAL",
"scope": {
"name": "@aws/aws-distro-opentelemetry-instrumentation-langchain",
"version": "0.12.0"
},
"attributes": {
"gen_ai.operation.name": "chat",
"gen_ai.provider.name": "openai",
"gen_ai.request.model": "gpt-4o-mini",
"gen_ai.input.messages": "[{\"role\": \"user\", \"parts\": [{\"type\": \"text\", \"content\": \"Hey, how can you help me\"}]}]",
"gen_ai.output.messages": "[{\"role\": \"assistant\", \"parts\": [{\"type\": \"text\", \"content\": \"I can assist you with planning your trip ...\"}]}]",
"gen_ai.system_instructions": "[{\"type\": \"text\", \"content\": \"You are a travel planning assistant ...\"}]",
"session.id": "sea-nyc-trip-2-turns"
},
"status": {
"code": "OK"
}
}
OpenTelemetry (Traceloop)
使用來自 Traceloop 的 OpenTelemetry JS 程式庫 (@traceloop/instrumentation-langchain),跨度類型會在 traceloop.span.kind 屬性中承載 (workflow 代表叫用代理程式跨度, task 代表工具跨度),而 gen_ai.operation.name = workflow代表叫用代理程式跨度。對話處於 traceloop.entity.input和 traceloop.entity.output 屬性,作為序列化 LangChain 狀態。
範例
- Invoke agent span
-
traceloop.span.kind 屬性 (workflow) 將此識別為調用代理程式範圍。traceloop.entity.input 和 traceloop.entity.output 屬性會保留序列化 LangChain 狀態,從中剖析使用者提示 (人類訊息) 和客服人員回應 (AI 訊息)。
{
"traceId": "6a6bd0b1c8d91ed1e70a3906b551618",
"spanId": "ba1833fa7f097041",
"name": "workflow RunnableSequence",
"kind": "INTERNAL",
"scope": {
"name": "@traceloop/instrumentation-langchain",
"version": "0.27.0"
},
"attributes": {
"traceloop.span.kind": "workflow",
"gen_ai.operation.name": "workflow",
"gen_ai.provider.name": "langchain",
"traceloop.workflow.name": "RunnableSequence",
"traceloop.entity.input": "{\"messages\": [{\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain_core\", \"messages\", \"HumanMessage\"], \"kwargs\": {\"content\": \"Hey, how can you help me\"}}]}",
"traceloop.entity.output": "{\"messages\": [{\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain_core\", \"messages\", \"AIMessage\"], \"kwargs\": {\"content\": \"I can assist you with planning your trip ...\"}}]}",
"session.id": "sea-nyc-trip-2-turns"
},
"status": {
"code": "OK"
}
}
- Execute tool span
-
traceloop.span.kind 屬性 (task) 將此識別為執行工具範圍。traceloop.entity.input 和 traceloop.entity.output 屬性會保留工具引數和結果。
{
"traceId": "6a6bd0b25c52f3d86a35038f35f5ba30",
"spanId": "5b332f3cd15ace04",
"name": "task search_flights",
"kind": "INTERNAL",
"scope": {
"name": "@traceloop/instrumentation-langchain",
"version": "0.27.0"
},
"attributes": {
"traceloop.span.kind": "task",
"traceloop.entity.name": "search_flights",
"traceloop.entity.input": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}",
"traceloop.entity.output": "{\"output\": {\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain_core\", \"messages\", \"ToolMessage\"], \"kwargs\": {\"status\": \"success\", \"content\": \"{\\\"origin\\\": \\\"SEA\\\", \\\"destination\\\": \\\"NYC\\\", \\\"flights\\\": [ ... ]}\"}}}",
"session.id": "sea-nyc-trip-2-turns"
},
"status": {
"code": "OK"
}
}
OpenInference
使用 OpenInference JS 程式庫 (@arizeai/openinference-instrumentation-langchain),跨度類型會在 openinference.span.kind 屬性中承載。對話內容位於 input.value和 output.value 屬性中,推論訊息也會出現在索引llm.input_messages.*和llm.output_messages.*屬性上。
範例
- Invoke agent span
-
openinference.span.kind 屬性 (CHAIN) 將此識別為調用代理程式範圍。input.value 和 output.value 屬性會保留序列化 LangChain 狀態。
{
"traceId": "6a6bd0c1c8d91ed1e70a3906b551618",
"spanId": "0a7990d804132a9b",
"name": "LangGraph",
"kind": "INTERNAL",
"scope": {
"name": "@arizeai/openinference-instrumentation-langchain",
"version": "4.0.14"
},
"attributes": {
"openinference.span.kind": "CHAIN",
"input.value": "{\"messages\": [{\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain_core\", \"messages\", \"HumanMessage\"], \"kwargs\": {\"content\": \"Hey, how can you help me\"}}]}",
"output.value": "{\"messages\": [{\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain_core\", \"messages\", \"AIMessage\"], \"kwargs\": {\"content\": \"I can assist you with planning your trip ...\"}}]}",
"session.id": "sea-nyc-trip-2-turns"
},
"status": {
"code": "OK"
}
}
- Execute tool span
-
openinference.span.kind 屬性 (TOOL) 將此識別為執行工具範圍; tool.name會保留工具名稱。input.value 和 output.value 屬性會保留工具引數和結果 (序列化為 LangChain ToolMessage)。
{
"traceId": "6a6bd0c25c52f3d86a35038f35f5ba30",
"spanId": "ab105c12cc40048f",
"name": "search_flights",
"kind": "INTERNAL",
"scope": {
"name": "@arizeai/openinference-instrumentation-langchain",
"version": "4.0.14"
},
"attributes": {
"openinference.span.kind": "TOOL",
"tool.name": "search_flights",
"input.value": "{\"origin\": \"SEA\", \"destination\": \"NYC\", \"date\": \"2025-03-15\"}",
"output.value": "{\"output\": {\"lc\": 1, \"type\": \"constructor\", \"id\": [\"langchain_core\", \"messages\", \"ToolMessage\"], \"kwargs\": {\"status\": \"success\", \"content\": \"{\\\"origin\\\": \\\"SEA\\\", \\\"destination\\\": \\\"NYC\\\", \\\"flights\\\": [ ... ]}\"}}}",
"session.id": "sea-nyc-trip-2-turns"
},
"status": {
"code": "OK"
}
}
- Inference span
-
openinference.span.kind 屬性 (LLM) 將此識別為推論範圍。llm.input_messages.* 屬性會保留系統提示和使用者提示,而llm.output_messages.*屬性會保留客服人員回應。
{
"traceId": "6a6bd0c1c8d91ed1e70a3906b551618",
"spanId": "1221a062c7f90a8e",
"name": "ChatOpenAI",
"kind": "INTERNAL",
"scope": {
"name": "@arizeai/openinference-instrumentation-langchain",
"version": "4.0.14"
},
"attributes": {
"openinference.span.kind": "LLM",
"llm.model_name": "gpt-4o-mini",
"llm.input_messages.0.message.role": "system",
"llm.input_messages.0.message.content": "You are a travel planning assistant ...",
"llm.input_messages.1.message.role": "user",
"llm.input_messages.1.message.content": "Hey, how can you help me",
"llm.output_messages.0.message.role": "assistant",
"llm.output_messages.0.message.content": "I can assist you with planning your trip ...",
"session.id": "sea-nyc-trip-2-turns"
},
"status": {
"code": "OK"
}
}
LangGraph 代理程式的最佳實務
建置和叫用 LangGraph 代理程式的方式會影響其遙測中出現的內容,因此評估代理程式的可靠性。下列實務有助於確保可復原使用者提示、客服人員回應和工具活動。
1. 選擇代理程式建構模式
有兩種常見的方法來建置 LangGraph 代理程式:
-
預先建置 create_agent :最快速的入門方式。它會產生每個回合的單一叫用代理程式範圍,並透過 LangGraph 的內建執行迴圈傳遞對話。當您想要不使用自訂控制流程的標準 reason-act 代理程式時,請使用此選項。
from langchain.agents import create_agent
agent = create_agent(model=model, tools=[search_flights, book_flight])
-
自訂 StateGraph :可讓您完全控制節點、邊緣和條件式路由。每個節點執行都會成為自己的跨度,因此追蹤更為精細。當您需要自訂協同運作時,請使用此選項。
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()
兩種模式的評估方式都相同;差異在於追蹤的精細程度。
2. 在圖形狀態messages中使用 (建議)
評估服務會從客服人員的輸入和輸出訊息重建對話。使用messages欄位不是強制性的,但可啟用最可靠的擷取。對於自訂 StateGraph,請將對話保留在 狀態的 messages 欄位中:
-
在您的狀態messages中包含 (建議)。您可以新增其他自訂欄位 (例如 user_id或 中繼資料)。當 messages 存在時,標準擷取會直接尋找使用者提示和客服人員回應。如果 messages 不存在,則服務會從個別推論範圍重建對話,這較不可靠。
-
附加,請勿取代。遵循 LangGraph 將新訊息附加至清單而非覆寫,因此會保留完整的對話歷史記錄。
-
使用正式 LangChain 訊息類型 (HumanMessage、AIMessage、ToolMessage、SystemMessage)。檢測會正確序列化這些項目,而服務會辨識其角色。
3. 以支援的格式傳遞使用者訊息
當您叫用 LangGraph 代理程式時,您可以將使用者訊息新增至圖形messages的狀態。LangGraph 接受三種可互換格式的訊息,而 AgentCore Evaluations 支援所有訊息。每個 都會產生服務可讀取的跨度和事件記錄。
-
雙組:一(role, content)對:
agent.invoke({"messages": [("user", user_message)]}, config=config)
-
LangChain 訊息物件: HumanMessage(或其他訊息類別):
from langchain_core.messages import HumanMessage
agent.invoke({"messages": [HumanMessage(content=user_message)]}, config=config)
-
字典:{"role", "content"}字典:
agent.invoke({"messages": [{"role": "user", "content": user_message}]}, config=config)
這三種格式都會產生相同的messages狀態,因此無論您選擇哪個格式,都會以相同的方式擷取使用者提示和客服人員回應。