View a markdown version of this page

LangGraph - Batuan Dasar Amazon AgentCore

LangGraph

Halaman ini menjelaskan cara instrumen LangGraphagen, bagaimana rentang diidentifikasi, dan bagaimana bidang evaluasi diekstraksi. Ini ditutup dengan praktik terbaik untuk penataan LangGraph agen sehingga dapat dievaluasi dengan andal.

Topik

Instrumen agen Anda

Anda dapat menginstrumentasikan LangGraph agen dengan salah satu dari dua pustaka instrumentasi: OpenTelemetry(opentelemetry-instrumentation-langchain) atau OpenInference(openinference-instrumentation-langchain). Amazon Bedrock AgentCore Evaluations mendukung kedua pustaka. Pustaka memancarkan nama lingkup yang berbeda dan menggunakan atribut rentang yang berbeda. Layanan evaluasi mengekstrak nilai yang sama dari masing-masing.

Saat agen Anda berjalan dengan AWS Distro for OpenTelemetry (ADOT), seperti di Amazon Bedrock AgentCore Runtime, Anda tidak perlu menambahkan kode instrumentasi eksplisit. Menambahkan pustaka instrumentasi ke dependensi proyek Anda sudah cukup. ADOT menemukannya saat startup dan mengaktifkannya secara otomatis.

Tambahkan pustaka instrumentasi untuk jalur yang Anda inginkan ke dependensi Anda. Contoh berikut menyematkan versi minimum; gunakan versi terbaru yang tersedia kecuali Anda memiliki alasan untuk menyematkan.

contoh
OpenTelemetry

CATATAN: Gunakan versi 0.55.0 atau yang lebih baru. Versi 0.55.0 menambahkan dukungan untuk konvensi rentang agen OpenTelemetry generatif-AI yang lebih baru yang diandalkan oleh layanan evaluasi.

Tambahkan opentelemetry-instrumentation-langchain ke dependensi Anda. Nama lingkup yang dipancarkan adalah. opentelemetry.instrumentation.langchain

requirements.txt:

opentelemetry-instrumentation-langchain>=0.55.0

pyproject.toml:

[project] dependencies = [ "opentelemetry-instrumentation-langchain>=0.55.0", ]
OpenInference

Tambahkan openinference-instrumentation-langchain ke dependensi Anda. Nama lingkup yang dipancarkan adalah. openinference.instrumentation.langchain

requirements.txt:

openinference-instrumentation-langchain>=0.1.62

pyproject.toml:

[project] dependencies = [ "openinference-instrumentation-langchain>=0.1.62", ]
catatan

Instrumentasi adalah salah satu langkah dalam mengatur observabilitas. Untuk mengekspor telemetri untuk evaluasi, selesaikan pengaturan lengkap di Siapkan observabilitas.

Bagaimana rentang diidentifikasi

Atribut yang digunakan untuk mengklasifikasikan bentang berbeda antara dua pustaka instrumentasi.

contoh
OpenTelemetry

Pustaka OpenTelemetry instrumentasi mengklasifikasikan rentang menggunakan traceloop.span.kind atribut, dan versi terbaru juga disetel. gen_ai.operation.name

Jenis rentang Mengidentifikasi atribut

Memohon agen

traceloop.span.kind= workflow (juga gen_ai.operation.name =invoke_agent)

Jalankan alat

traceloop.span.kind= tool (juga gen_ai.operation.name =execute_tool)

Inferensi

gen_ai.operation.name = chat

OpenInference

Pustaka OpenInference instrumentasi mengklasifikasikan rentang menggunakan atribut. openinference.span.kind

Jenis rentang Mengidentifikasi atribut

Memohon agen

openinference.span.kind= CHAIN atau AGENT

Jalankan alat

openinference.span.kind = TOOL

Inferensi

openinference.span.kind = LLM

Bagaimana bidang evaluasi diekstraksi

Untuk rentang agen pemanggilan, input dan output tidak berisi daftar per pesan yang bersih. Sebaliknya, konten adalah status LangChain grafik serial: string JSON yang membungkus status penuh. Bentuk yang tepat dari status serial ini berbeda antara dua pustaka instrumentasi. Dalam kedua kasus, layanan menguraikannya untuk menemukan prompt pengguna (pesan manusia) dan respons agen (pesan AI).

LangGraph juga membuat serial peran pesan dalam lebih dari satu bentuk. Peran dapat muncul sebagai nilai huruf kecil (human,ai,tool) atau sebagai nama kelas LangChain pesan (HumanMessage,AIMessage,ToolMessage). Layanan mengenali kedua bentuk.

Lokasi konten ini tergantung pada bagaimana telemetri dikumpulkan. Atribut pengidentifikasi (traceloop.span.kindatauopeninference.span.kind) berada pada rentang dalam kedua kasus. Untuk informasi selengkapnya, lihat Rentang, catatan peristiwa, dan sinyal telemetri.

Dari catatan acara

Saat telemetri dibagi, layanan membaca konten dari catatan peristiwa yang berkorelasi dengan setiap rentang:

  • Prompt pengguna dan respons agen: dari catatan peristiwa rentang agen pemanggilan, di body.input danbody.output.

  • Panggilan alat: nama alat dari rentang alat eksekusi. Argumen dan hasil alat berasal dari catatan peristiwa rentang itu, di body.input danbody.output.

Sebagai contoh, lihat Contoh bentang dengan catatan peristiwa.

Dari atribut span

Ketika telemetri tidak dibagi, konten yang sama tetap pada rentang sebagai atribut. Atribut tergantung pada pustaka instrumentasi:

  • OpenTelemetry:

    • Prompt pengguna dan respons agen: dari gen_ai.task.input dan gen_ai.task.output pada rentang agen pemanggilan.

    • Panggilan alat: nama alat darigen_ai.tool.name, dan argumen dan hasil dari gen_ai.tool.call.arguments dangen_ai.tool.call.result, pada rentang alat eksekusi.

  • OpenInference:

    • Prompt pengguna dan respons agen: dari input.value dan output.value pada rentang agen pemanggilan.

    • Panggilan alat: nama alat daritool.name, dan argumen dan hasil dari input.value danoutput.value, pada rentang alat eksekusi.

Sebagai contoh, lihat Contoh rentang tanpa catatan peristiwa.

Contoh membentang dengan catatan acara

Ketika telemetri dibagi, rentang membawa atribut pengidentifikasi dan konten hidup dalam catatan peristiwa yang berkorelasi. Contoh berikut berasal dari agen LangGraph perencanaan perjalanan yang digunakan di Amazon Bedrock Runtime. AgentCore Agen yang sama ditampilkan di bawah setiap perpustakaan instrumentasi.

catatan

Contoh-contoh ini bukan bentang lengkap. Mereka menunjukkan data representatif dari interaksi agen nyata, dengan beberapa bidang dihilangkan dan nilai panjang dipotong untuk keterbacaan.

OpenTelemetry

contoh
Invoke agent span

traceloop.span.kindAtribut (workflow) mengidentifikasi ini sebagai rentang agen pemanggilan; versi pustaka terbaru juga menetapkan 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" } }

Catatan peristiwa yang berkorelasi membawa percakapan. Setiap pesan content adalah status LangChain grafik serial. Input membungkus status di bawah inputs kunci. Output membungkusnya di bawah outputs kunci, dengan setiap pesan sebagai objek LangChain konstruktor. Prompt pengguna adalah pesan manusia dan respons agen adalah pesan AI di dalam status serial itu.

{ "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.kindAtribut (tool) mengidentifikasi ini sebagai rentang alat eksekusi; gen_ai.tool.name memegang nama alat dan 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" } }

Catatan peristiwa yang berkorelasi membawa input alat (argumen) dan output (hasil, diserialkan sebagai 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

Dengan OpenInference perpustakaan, tipe rentang dibawa dalam openinference.span.kind atribut, dan input dan output agen diserialisasikan dalam catatan peristiwa yang berkorelasi.

contoh
Invoke agent span

openinference.span.kindAtribut (CHAIN, atau AGENT ketika grafik dikompilasi dengan nama) mengidentifikasi ini sebagai rentang agen pemanggilan.

{ "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" } }

Catatan peristiwa yang berkorelasi membawa percakapan. Prompt pengguna adalah pesan peran manusia dan respons agen adalah AI-role pesan dalam pesan serial.

{ "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.kindAtribut (TOOL) mengidentifikasi ini sebagai rentang alat eksekusi; tool.name memegang nama alat.

{ "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" } }

Catatan peristiwa yang berkorelasi membawa input alat (argumen) dan output (hasil, diserialkan sebagai 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" } ] } } }

Contoh membentang tanpa catatan peristiwa

Ketika telemetri tidak dibagi, konten yang sama tetap pada atribut rentang dan tidak ada catatan peristiwa terpisah yang dihasilkan. Contoh berikut berasal dari agen LangGraph perencanaan perjalanan. Agen yang sama ditampilkan di bawah setiap perpustakaan instrumentasi.

catatan

Contoh-contoh ini bukan bentang lengkap. Mereka menunjukkan data representatif dari interaksi agen nyata, dengan beberapa bidang dihilangkan dan nilai panjang dipotong untuk keterbacaan.

OpenTelemetry

contoh
Invoke agent span

gen_ai.task.inputAtribut menahan prompt pengguna, dan gen_ai.task.output atribut memegang status serial dengan respons agen. Keduanya adalah status LangChain grafik serial.

{ "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.argumentsAtribut memegang argumen alat, dan gen_ai.tool.call.result atribut memegang hasil alat, diserialkan sebagai 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

contoh
Invoke agent span

input.valueAtribut menahan prompt pengguna, dan output.value atribut memegang status serial dengan respons agen.

{ "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.valueAtribut memegang argumen alat, dan output.value atribut memegang hasil alat, diserialkan sebagai 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" } }

Praktik terbaik untuk LangGraph agen

Bagaimana Anda membangun dan memanggil LangGraph agen memengaruhi apa yang muncul dalam telemetrinya, dan oleh karena itu seberapa andal agen tersebut dapat dievaluasi. Praktik berikut membantu memastikan prompt pengguna, respons agen, dan aktivitas alat dapat dipulihkan.

1. Pilih pola konstruksi agen

Ada dua cara umum untuk membangun LangGraph agen:

  • Prebuilt create_agent: cara tercepat untuk memulai. Ini menghasilkan rentang agen pemanggilan tunggal per giliran, dengan percakapan melewati LangGraph loop eksekusi bawaan. Gunakan ini saat Anda menginginkan agen alasan-tindakan standar tanpa alur kontrol khusus.

    from langchain.agents import create_agent agent = create_agent(model=model, tools=[search_flights, book_flight])
  • Kustom StateGraph: memberi Anda kontrol penuh atas node, tepi, dan perutean bersyarat. Setiap eksekusi node menjadi rentangnya sendiri, sehingga jejaknya lebih granular. Gunakan ini saat Anda membutuhkan orkestrasi khusus.

    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()

Kedua pola dievaluasi dengan cara yang sama; perbedaannya adalah perincian jejak.

2. Gunakan pesan dalam Status grafik Anda (disarankan)

Layanan evaluasi merekonstruksi percakapan dari pesan input dan output agen. Menggunakan messages bidang tidak wajib, tetapi memungkinkan ekstraksi yang paling dapat diandalkan. Untuk kebiasaanStateGraph, simpan percakapan di messages bidang di Negara Bagian Anda:

  • Sertakan messages di Negara Anda (disarankan). Anda dapat menambahkan bidang khusus lainnya (seperti user_id atau metadata). Ketika messages hadir, ekstraksi standar menemukan prompt pengguna dan respons agen secara langsung. Jika tidak messages ada, layanan akan kembali merekonstruksi percakapan dari rentang inferensi individu, yang kurang dapat diandalkan.

  • Tambahkan, jangan ganti. Ikuti LangGraph konvensi menambahkan pesan baru ke daftar daripada menimpa, sehingga riwayat percakapan lengkap dipertahankan.

  • Gunakan jenis LangChain pesan kanonik (HumanMessage,, AIMessageToolMessage,SystemMessage). Instrumentasi membuat serial ini dengan benar, dan layanan mengenali peran mereka.

3. Meneruskan pesan pengguna dalam format yang didukung

Saat Anda memanggil LangGraph agen, Anda menambahkan pesan pengguna ke messages status grafik. LangGraph menerima pesan dalam tiga format yang dapat dipertukarkan, dan AgentCore Evaluasi mendukung semuanya. Masing-masing menghasilkan rentang dan catatan peristiwa yang dapat dibaca oleh layanan.

  • Tuple: (role, content) sepasang:

    agent.invoke({"messages": [("user", user_message)]}, config=config)
  • LangChain objek pesan: a HumanMessage (atau kelas pesan lainnya):

    from langchain_core.messages import HumanMessage agent.invoke({"messages": [HumanMessage(content=user_message)]}, config=config)
  • Kamus: {"role", "content"} kamus:

    agent.invoke({"messages": [{"role": "user", "content": user_message}]}, config=config)

Ketiga format menghasilkan messages status yang sama, sehingga prompt pengguna dan respons agen diekstraksi secara identik terlepas dari mana yang Anda pilih.