You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2026/10/10 08:34:40 UTC
(skywalking-website) 01/01: Blog: Amazon Bedrock AgentCore in practice with Apache SkyWalking AI Sessionizer
This is an automated email from the ASF dual-hosted git repository.
wu-sheng pushed a commit to branch blog/ai-sessionizer-agentcore
in repository https://gitbox.apache.org/repos/asf/skywalking-website.git
commit e497566772bade11fcfe4d6f836e345712d8f2e5
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Sat Oct 10 16:33:37 2026 +0800
Blog: Amazon Bedrock AgentCore in practice with Apache SkyWalking AI Sessionizer
A LangGraph agent on Amazon Bedrock AgentCore Runtime, recorded by AI
Sessionizer while each session runs and kept after its execution
environment stops, with configuration rather than code: four LANGSMITH_*
variables for the conversation, three ASZ_* variables, asz-changes and the
LangChain shim in the image, and a shared Amazon EFS directory for the file
changes.
From a real run on 2026-10-10 in us-east-1 with Amazon Nova Pro: six talks
on one AgentCore session, 19 model calls and one recorded file change. The
post shows the history carried across invocations, what the tools changed
against what the agent said (an invented agentcore_idle_timeout), and a
turn sent on the same session after the 15-minute idle stop: a fresh
environment, a two-message prompt, a confident wrong recollection, while
the conversation in Sessionizer continued across the stop.
Figures: a hero and an idle timeline drawn with GPT-6 Astra, Figure 1
showing both recording paths, and screenshots of the replay page on Fargate
cropped for the post column. The demo is
https://github.com/wu-sheng/aws-agentcore-asz-demo.
---
.../agentcore-replay-featured.png | Bin 0 -> 136916 bytes
.../agentcore-replay-featured.svg | 94 ++++++++
.../agentcore-topology.svg | 87 ++++++++
.../conversation-list.png | Bin 0 -> 49951 bytes
.../conversation-page.png | Bin 0 -> 560193 bytes
.../idle-prompt.png | Bin 0 -> 130710 bytes
.../idle-timeline.svg | 90 ++++++++
.../2026-10-10-ai-sessionizer-agentcore/index.md | 240 +++++++++++++++++++++
.../prompt-request.png | Bin 0 -> 387206 bytes
.../tool-change.png | Bin 0 -> 272867 bytes
.../turn-steps.png | Bin 0 -> 160894 bytes
11 files changed, 511 insertions(+)
diff --git a/content/blog/2026-10-10-ai-sessionizer-agentcore/agentcore-replay-featured.png b/content/blog/2026-10-10-ai-sessionizer-agentcore/agentcore-replay-featured.png
new file mode 100644
index 000000000000..645609fdf0c0
Binary files /dev/null and b/content/blog/2026-10-10-ai-sessionizer-agentcore/agentcore-replay-featured.png differ
diff --git a/content/blog/2026-10-10-ai-sessionizer-agentcore/agentcore-replay-featured.svg b/content/blog/2026-10-10-ai-sessionizer-agentcore/agentcore-replay-featured.svg
new file mode 100644
index 000000000000..115ba45433cb
--- /dev/null
+++ b/content/blog/2026-10-10-ai-sessionizer-agentcore/agentcore-replay-featured.svg
@@ -0,0 +1,94 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="900" viewBox="0 0 1600 900" role="img" aria-labelledby="hero-title hero-desc" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif">
+ <title id="hero-title">Recorded while running. Kept when it ends.</title>
+ <desc id="hero-desc">One continuous AI Sessionizer record spans two execution environments of one Amazon Bedrock AgentCore session. Five turns run in the first environment with local history and a repository clone. The fifth turn owns the retained file diff. After fifteen idle minutes, the first environment stops and its local state ends. Turn six runs in a fresh a new environment with empty memory and no repository clone. Sessionizer retains all six turns and the file diff. Solid upwa [...]
+ <defs>
+ <marker id="hero-trace-arrow" viewBox="0 0 12 12" refX="11" refY="6" markerWidth="12" markerHeight="12" markerUnits="userSpaceOnUse" orient="auto"><path d="M1 1 11 6 1 11Z" fill="#4f46e5"/></marker>
+ <marker id="hero-file-arrow" viewBox="0 0 12 12" refX="11" refY="6" markerWidth="12" markerHeight="12" markerUnits="userSpaceOnUse" orient="auto"><path d="M1 1 11 6 1 11Z" fill="#695aa1"/></marker>
+ <g id="hero-turn" fill="#ffffff" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
+ <path d="M-19-26H19Q32-26 32-13V13Q32 26 19 26H-7L-21 35V26Q-32 26-32 13V-13Q-32-26-19-26Z"/>
+ <path d="M-15-7H15M-15 7H6" fill="none"/>
+ </g>
+ <clipPath id="hero-vm1-clip"><rect x="80" y="542" width="1020" height="224" rx="20"/></clipPath>
+ </defs>
+
+ <rect width="1600" height="900" fill="#f8fafc"/>
+ <text x="80" y="130" font-size="64" font-weight="600" fill="#0f172a" data-box="80 66 1370 82">Recorded while running.</text>
+ <text x="80" y="208" font-size="64" font-weight="600" fill="#065f46" data-box="80 144 1370 82">Kept when it ends.</text>
+
+ <!-- The retained track is unbroken across the stop and the fresh runtime. -->
+ <rect x="80" y="256" width="1440" height="232" rx="20" fill="#ecfdf5" stroke="#059669" stroke-width="3"/>
+ <text x="112" y="305" font-size="38" font-weight="600" fill="#065f46" data-box="112 267 560 49">Apache SkyWalking AI Sessionizer</text>
+ <text x="1488" y="305" text-anchor="end" font-size="32" fill="#065f46" data-box="1008 273 480 42">One continuous record</text>
+ <path d="M128 350H1480" fill="none" stroke="#059669" stroke-width="4" stroke-linecap="round"/>
+ <g stroke="#059669">
+ <use href="#hero-turn" transform="translate(168 350)"/>
+ <use href="#hero-turn" transform="translate(308 350)"/>
+ <use href="#hero-turn" transform="translate(448 350)"/>
+ <use href="#hero-turn" transform="translate(588 350)"/>
+ <use href="#hero-turn" transform="translate(728 350)"/>
+ <use href="#hero-turn" transform="translate(1360 350)"/>
+ </g>
+ <text x="1016" y="449" font-size="32" fill="#4c1d95">file changes</text>
+ <text x="112" y="449" font-size="32" fill="#065f46" data-box="112 417 480 42">Prompts + tool calls</text>
+
+ <!-- Only the fifth recorded turn owns this diff card. -->
+ <path d="M728 385V405" fill="none" stroke="#695aa1" stroke-width="3"/>
+ <rect x="690" y="405" width="300" height="62" rx="12" fill="#f5f3ff" stroke="#695aa1" stroke-width="2.5"/>
+ <g fill="none" stroke="#695aa1" stroke-width="3" stroke-linecap="round" stroke-linejoin="round">
+ <path d="M712 418H733L744 429V454H712ZM733 418V429H744"/>
+ <path d="M765 425H777M771 419V431M794 425H963M765 447H777M794 447H933"/>
+ </g>
+
+ <!-- Separate runtime lifetimes: the first ends; the second begins empty. -->
+ <rect x="80" y="542" width="1020" height="224" rx="20" fill="#fff7ed"/>
+ <rect x="832" y="542" width="268" height="224" fill="#f1f5f9" clip-path="url(#hero-vm1-clip)"/>
+ <rect x="80" y="542" width="1020" height="224" rx="20" fill="none" stroke="#ea580c" stroke-width="3"/>
+ <text x="112" y="585" font-size="32" font-weight="600" fill="#9a3412" data-box="112 553 450 42">Amazon Bedrock AgentCore Runtime</text>
+
+ <path d="M128 632H832" fill="none" stroke="#ea580c" stroke-width="3"/>
+ <path d="M832 632H1100" fill="none" stroke="#64748b" stroke-width="3" stroke-dasharray="8 8"/>
+ <rect x="1200" y="542" width="320" height="224" rx="20" fill="#ffffff" stroke="#64748b" stroke-width="3"/>
+ <text x="1232" y="585" font-size="32" font-weight="600" fill="#334155" data-box="1232 553 256 42">Same session</text>
+
+ <!-- Six solid trace paths, plus the fifth turn's dashed file path. -->
+ <g fill="none" stroke="#4f46e5" stroke-width="3" marker-end="url(#hero-trace-arrow)">
+ <path d="M168 541V491"/><path d="M308 541V491"/><path d="M448 541V491"/>
+ <path d="M588 541V491"/><path d="M728 541V491"/><path d="M1360 541V491"/>
+ </g>
+ <path d="M760 632H804V469" fill="none" stroke="#695aa1" stroke-width="3" stroke-dasharray="8 6" stroke-linejoin="round" marker-end="url(#hero-file-arrow)"/>
+ <g stroke="#ea580c">
+ <use href="#hero-turn" transform="translate(168 632)"/>
+ <use href="#hero-turn" transform="translate(308 632)"/>
+ <use href="#hero-turn" transform="translate(448 632)"/>
+ <use href="#hero-turn" transform="translate(588 632)"/>
+ <use href="#hero-turn" transform="translate(728 632)"/>
+ <use href="#hero-turn" transform="translate(1360 632)"/>
+ </g>
+
+ <!-- The memory stack and working clone are local to the session's first environment. -->
+ <g fill="#ffffff" stroke="#c2410c" stroke-width="2.5" stroke-linejoin="round">
+ <rect x="112" y="695" width="45" height="14" rx="3"/>
+ <rect x="112" y="712" width="45" height="14" rx="3"/>
+ <rect x="112" y="729" width="45" height="14" rx="3"/>
+ <path d="M354 743V701H376L384 710H406V743Z"/>
+ </g>
+ <text x="177" y="732" font-size="32" fill="#9a3412" data-box="177 700 150 42">History</text>
+ <text x="426" y="732" font-size="32" fill="#9a3412" data-box="426 700 210 42">Repo clone</text>
+ <path d="M728 667V697M714 697H732L742 707V735H714ZM732 697V707H742M721 716H735M728 709V723" fill="none" stroke="#695aa1" stroke-width="2.5" stroke-linejoin="round"/>
+
+ <!-- The idle clock leads into a hard stop; no runtime line crosses it. -->
+ <text x="966" y="585" text-anchor="middle" font-size="32" fill="#475569" data-box="864 553 204 42">15 min idle</text>
+ <circle cx="966" cy="632" r="26" fill="#ffffff" stroke="#475569" stroke-width="3"/>
+ <path d="M966 616V632L980 640" fill="none" stroke="#475569" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
+ <path d="M1100 528V766" fill="none" stroke="#475569" stroke-width="5"/>
+ <rect x="1090" y="622" width="20" height="20" rx="2" fill="#475569"/>
+ <text x="966" y="732" text-anchor="middle" font-size="32" font-weight="600" fill="#475569" data-box="864 700 204 42">Stopped</text>
+ <text x="1232" y="698" font-size="32" fill="#334155" data-box="1232 672 256 42">Starts without</text>
+ <text x="1232" y="744" font-size="32" fill="#334155" data-box="1232 709 256 42">history or clone</text>
+
+ <!-- Recording-path colors and line styles match the architecture figure. -->
+ <path d="M96 818V790" fill="none" stroke="#4f46e5" stroke-width="3" marker-end="url(#hero-trace-arrow)"/>
+ <text x="120" y="812" font-size="32" fill="#3730a3" data-box="120 780 275 40">LangSmith wire</text>
+ <path d="M458 818V790" fill="none" stroke="#695aa1" stroke-width="3" stroke-dasharray="8 6" marker-end="url(#hero-file-arrow)"/>
+ <text x="482" y="812" font-size="32" fill="#5b21b6" data-box="482 780 500 40">asz-changes โ shared EFS</text>
+</svg>
diff --git a/content/blog/2026-10-10-ai-sessionizer-agentcore/agentcore-topology.svg b/content/blog/2026-10-10-ai-sessionizer-agentcore/agentcore-topology.svg
new file mode 100644
index 000000000000..5b5c2a6280c4
--- /dev/null
+++ b/content/blog/2026-10-10-ai-sessionizer-agentcore/agentcore-topology.svg
@@ -0,0 +1,87 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 780" role="img" aria-labelledby="t1 d1" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif" font-size="20">
+ <title id="t1">A LangGraph agent on Amazon Bedrock AgentCore Runtime, recorded by Apache SkyWalking AI Sessionizer</title>
+ <desc id="d1">The caller invokes the agent on AgentCore Runtime with a session id. The runtime's network interfaces sit in private subnets. The agent sends the LangSmith wire to an internal load balancer in front of AI Sessionizer on ECS Fargate, and asz-changes in the agent writes what its tools changed to an Amazon EFS directory that Sessionizer also reads. The agent calls Amazon Nova Pro on Bedrock through a NAT gateway in a public subnet. You open the replay page through a public l [...]
+ <defs>
+ <marker id="a" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">
+ <path d="M0,0 L10,5 L0,10 z" fill="#334155"/>
+ </marker>
+ <marker id="ab" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">
+ <path d="M0,0 L10,5 L0,10 z" fill="#4f46e5"/>
+ </marker>
+ <marker id="ap" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto">
+ <path d="M0,0 L10,5 L0,10 z" fill="#695aa1"/>
+ </marker>
+ </defs>
+ <rect width="1200" height="780" fill="#ffffff"/>
+
+ <!-- VPC and its subnets -->
+ <rect x="240" y="20" width="940" height="670" rx="16" fill="#f8fafc" stroke="#64748b" stroke-width="2" stroke-dasharray="8 6"/>
+ <text x="262" y="56" font-size="22" font-weight="600" fill="#334155">VPC</text>
+ <rect x="258" y="74" width="904" height="436" rx="12" fill="none" stroke="#94a3b8" stroke-width="1.5" stroke-dasharray="5 5"/>
+ <text x="1148" y="100" font-size="20" text-anchor="end" fill="#64748b">private subnets</text>
+ <rect x="258" y="528" width="904" height="146" rx="12" fill="none" stroke="#94a3b8" stroke-width="1.5" stroke-dasharray="5 5"/>
+ <text x="1148" y="554" font-size="20" text-anchor="end" fill="#64748b">public subnets</text>
+
+ <!-- AgentCore Runtime and the agent -->
+ <rect x="276" y="112" width="380" height="250" rx="14" fill="#fff7ed" stroke="#ea580c" stroke-width="2.5"/>
+ <text x="296" y="146" font-size="22" font-weight="600" fill="#9a3412">Bedrock AgentCore Runtime</text>
+ <text x="296" y="174" fill="#7c2d12">one environment per session,</text>
+ <text x="296" y="200" fill="#7c2d12">ENIs in these subnets</text>
+ <rect x="296" y="214" width="340" height="132" rx="10" fill="#ffffff" stroke="#fdba74" stroke-width="1.5"/>
+ <text x="314" y="246" font-size="22" font-weight="600" fill="#1e293b">LangGraph agent</text>
+ <text x="314" y="278" fill="#334155">langsmith client, 4 env vars</text>
+ <text x="314" y="308" fill="#334155">asz-changes โ /mnt/changes</text>
+ <text x="314" y="336" fill="#64748b">repo clone in the session</text>
+
+ <!-- internal load balancer -->
+ <rect x="790" y="112" width="350" height="86" rx="12" fill="#eef2ff" stroke="#4f46e5" stroke-width="2"/>
+ <text x="810" y="146" font-size="22" font-weight="600" fill="#3730a3">Internal LB :1985</text>
+ <text x="810" y="178" fill="#3730a3">agent's security group only</text>
+
+ <!-- Sessionizer -->
+ <rect x="790" y="256" width="350" height="216" rx="14" fill="#ecfdf5" stroke="#059669" stroke-width="2.5"/>
+ <text x="810" y="292" font-size="24" font-weight="600" fill="#065f46">AI Sessionizer</text>
+ <text x="810" y="320" fill="#065f46">on ECS Fargate, one task</text>
+ <text x="810" y="358" fill="#065f46">LangSmith receiver, token</text>
+ <text x="810" y="388" fill="#065f46">changes: /asz/changes</text>
+ <text x="810" y="418" fill="#065f46">conversation assembly</text>
+ <text x="810" y="448" fill="#065f46">replay page :8787</text>
+
+ <!-- EFS -->
+ <rect x="452" y="392" width="270" height="104" rx="12" fill="#f5f3ff" stroke="#695aa1" stroke-width="2"/>
+ <text x="472" y="426" font-size="22" font-weight="600" fill="#4c1d95">Amazon EFS</text>
+ <text x="472" y="456" fill="#4c1d95">/asz-changes, shared</text>
+ <text x="472" y="484" fill="#4c1d95">/asz-data, Sessionizer</text>
+
+ <!-- NAT and public load balancer -->
+ <rect x="276" y="572" width="300" height="88" rx="12" fill="#f1f5f9" stroke="#94a3b8" stroke-width="1.5"/>
+ <text x="296" y="606" font-size="22" font-weight="600" fill="#334155">NAT gateway</text>
+ <text x="296" y="638" fill="#334155">Bedrock, image pulls</text>
+ <rect x="790" y="572" width="350" height="88" rx="12" fill="#f1f5f9" stroke="#94a3b8" stroke-width="1.5"/>
+ <text x="810" y="606" font-size="22" font-weight="600" fill="#334155">Public LB :8787</text>
+ <text x="810" y="638" fill="#334155">your IP only</text>
+
+ <!-- outside the VPC -->
+ <rect x="20" y="166" width="196" height="88" rx="12" fill="#ffffff" stroke="#334155" stroke-width="1.5"/>
+ <text x="38" y="200" font-size="22" font-weight="600" fill="#1e293b">Caller</text>
+ <text x="38" y="232" fill="#334155">session id</text>
+ <rect x="20" y="572" width="196" height="88" rx="12" fill="#fff7ed" stroke="#ea580c" stroke-width="1.5"/>
+ <text x="38" y="606" font-size="21" font-weight="600" fill="#9a3412">Amazon Bedrock</text>
+ <text x="38" y="638" fill="#9a3412">Nova Pro</text>
+ <rect x="790" y="702" width="350" height="62" rx="12" fill="#ffffff" stroke="#334155" stroke-width="1.5"/>
+ <text x="810" y="741" font-size="22" font-weight="600" fill="#1e293b">You, in a browser</text>
+
+ <!-- arrows -->
+ <line x1="216" y1="210" x2="270" y2="210" stroke="#334155" stroke-width="2.5" marker-end="url(#a)"/>
+ <line x1="636" y1="252" x2="784" y2="166" stroke="#4f46e5" stroke-width="3" marker-end="url(#ab)"/>
+ <text x="664" y="262" fill="#3730a3" font-size="20">LangSmith</text>
+ <text x="664" y="286" fill="#3730a3" font-size="20">wire</text>
+ <line x1="965" y1="198" x2="965" y2="250" stroke="#4f46e5" stroke-width="3" marker-end="url(#ab)"/>
+ <line x1="560" y1="362" x2="560" y2="388" stroke="#695aa1" stroke-width="3" stroke-dasharray="7 5" marker-end="url(#ap)"/>
+ <text x="572" y="384" fill="#4c1d95" font-size="20">file changes</text>
+ <line x1="722" y1="444" x2="784" y2="420" stroke="#695aa1" stroke-width="3" stroke-dasharray="7 5" marker-end="url(#ap)"/>
+ <line x1="330" y1="362" x2="330" y2="566" stroke="#334155" stroke-width="2.5" marker-end="url(#a)"/>
+ <line x1="276" y1="616" x2="222" y2="616" stroke="#334155" stroke-width="2.5" marker-end="url(#a)"/>
+ <line x1="965" y1="572" x2="965" y2="478" stroke="#334155" stroke-width="2.5" marker-end="url(#a)"/>
+ <line x1="965" y1="702" x2="965" y2="666" stroke="#334155" stroke-width="2.5" marker-end="url(#a)"/>
+</svg>
diff --git a/content/blog/2026-10-10-ai-sessionizer-agentcore/conversation-list.png b/content/blog/2026-10-10-ai-sessionizer-agentcore/conversation-list.png
new file mode 100644
index 000000000000..d4e1f8228831
Binary files /dev/null and b/content/blog/2026-10-10-ai-sessionizer-agentcore/conversation-list.png differ
diff --git a/content/blog/2026-10-10-ai-sessionizer-agentcore/conversation-page.png b/content/blog/2026-10-10-ai-sessionizer-agentcore/conversation-page.png
new file mode 100644
index 000000000000..2d9e07f6cf63
Binary files /dev/null and b/content/blog/2026-10-10-ai-sessionizer-agentcore/conversation-page.png differ
diff --git a/content/blog/2026-10-10-ai-sessionizer-agentcore/idle-prompt.png b/content/blog/2026-10-10-ai-sessionizer-agentcore/idle-prompt.png
new file mode 100644
index 000000000000..5a1ffbfb3213
Binary files /dev/null and b/content/blog/2026-10-10-ai-sessionizer-agentcore/idle-prompt.png differ
diff --git a/content/blog/2026-10-10-ai-sessionizer-agentcore/idle-timeline.svg b/content/blog/2026-10-10-ai-sessionizer-agentcore/idle-timeline.svg
new file mode 100644
index 000000000000..67f68599ff0a
--- /dev/null
+++ b/content/blog/2026-10-10-ai-sessionizer-agentcore/idle-timeline.svg
@@ -0,0 +1,90 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="520" viewBox="0 0 1200 520" role="img" aria-labelledby="timeline-title timeline-desc" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif">
+ <title id="timeline-title">One conversation across two execution environments of one AgentCore session</title>
+ <desc id="timeline-desc">Turns one through five run in the first execution environment of an Amazon Bedrock AgentCore session and are recorded during execution. Turn five changes terraform.tfvars and owns the diff retained by AI Sessionizer. After fifteen idle minutes, the first environment stops and its local history and repository clone disappear. Turn six starts with empty memory and no repository clone in a fresh a new environment using the same session ID. One unbroken Sessionizer [...]
+ <defs>
+ <marker id="timeline-trace-arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="10" markerHeight="10" markerUnits="userSpaceOnUse" orient="auto"><path d="M0 0 9 5 0 10Z" fill="#4f46e5"/></marker>
+ <marker id="timeline-file-arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="10" markerHeight="10" markerUnits="userSpaceOnUse" orient="auto"><path d="M0 0 9 5 0 10Z" fill="#695aa1"/></marker>
+ <clipPath id="timeline-vm1-clip"><rect x="32" y="302" width="808" height="156" rx="14"/></clipPath>
+ </defs>
+
+ <rect width="1200" height="520" fill="#f8fafc"/>
+ <text x="32" y="34" font-size="28" font-weight="600" fill="#0f172a" data-box="32 6 900 36">Same session ID throughout</text>
+
+ <!-- This track crosses the idle interval and stop without a break. -->
+ <rect x="32" y="52" width="1136" height="178" rx="14" fill="#ecfdf5" stroke="#059669" stroke-width="2.5"/>
+ <text x="56" y="87" font-size="26" font-weight="600" fill="#065f46" data-box="56 61 540 34">AI Sessionizer ยท one conversation</text>
+ <text x="1144" y="87" text-anchor="end" font-size="24" fill="#065f46" data-box="740 63 404 32">Earlier turns and diff kept</text>
+ <path d="M80 125H1138" fill="none" stroke="#059669" stroke-width="4" stroke-linecap="round"/>
+ <g fill="#ffffff" stroke="#059669" stroke-width="3">
+ <circle cx="112" cy="125" r="19"/>
+ <circle cx="212" cy="125" r="19"/>
+ <circle cx="312" cy="125" r="19"/>
+ <circle cx="412" cy="125" r="19"/>
+ <circle cx="512" cy="125" r="19"/>
+ <circle cx="1048" cy="125" r="19"/>
+ </g>
+ <g text-anchor="middle" font-size="24" fill="#065f46">
+ <text x="112" y="133" data-box="98 109 28 30">1</text>
+ <text x="212" y="133" data-box="198 109 28 30">2</text>
+ <text x="312" y="133" data-box="298 109 28 30">3</text>
+ <text x="412" y="133" data-box="398 109 28 30">4</text>
+ <text x="512" y="133" data-box="498 109 28 30">5</text>
+ <text x="1048" y="133" data-box="1034 109 28 30">6</text>
+ </g>
+
+ <!-- A leader from recorded turn five makes diff ownership explicit. -->
+ <path d="M512 145V162" fill="none" stroke="#695aa1" stroke-width="2.5"/>
+ <rect x="448" y="162" width="380" height="46" rx="12" fill="#f5f3ff" stroke="#695aa1" stroke-width="2"/>
+ <text x="468" y="193" font-family="ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace" font-size="24" fill="#5b21b6" data-box="468 169 340 32">terraform.tfvars diff</text>
+ <text x="56" y="184" font-size="24" fill="#065f46" data-box="56 160 364 62"><tspan x="56" y="184">Prompts and tool calls</tspan><tspan x="56" y="214">retained</tspan></text>
+ <text x="1048" y="191" text-anchor="middle" font-size="24" fill="#065f46" data-box="948 167 200 32">Turn 6, +16 min</text>
+
+ <!-- The first runtime owns its history and clone, then terminates. -->
+ <rect x="32" y="302" width="808" height="156" rx="14" fill="#fff7ed"/>
+ <rect x="584" y="302" width="256" height="156" fill="#f1f5f9" clip-path="url(#timeline-vm1-clip)"/>
+ <rect x="32" y="302" width="808" height="156" rx="14" fill="none" stroke="#ea580c" stroke-width="2.5"/>
+ <text x="56" y="333" font-size="26" font-weight="600" fill="#9a3412" data-box="56 307 330 34">AgentCore Runtime session</text>
+ <path d="M80 369H584" fill="none" stroke="#ea580c" stroke-width="3"/>
+ <path d="M584 369H840" fill="none" stroke="#64748b" stroke-width="3" stroke-dasharray="7 7"/>
+ <text x="56" y="411" font-size="24" fill="#9a3412" data-box="56 387 340 32">History + repo clone</text>
+ <text x="56" y="445" font-family="ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace" font-size="24" fill="#9a3412" data-box="56 421 340 32">terraform.tfvars</text>
+ <text x="712" y="333" text-anchor="middle" font-size="24" fill="#475569" data-box="608 309 208 32">15 min idle timeout</text>
+ <text x="840" y="278" text-anchor="end" font-size="24" font-weight="600" fill="#475569" data-box="592 254 248 32">environment stopped</text>
+ <path d="M840 287V458" fill="none" stroke="#475569" stroke-width="4"/>
+ <rect x="833" y="362" width="14" height="14" rx="1" fill="#475569"/>
+
+ <!-- Turn six starts in a separate, empty runtime. -->
+ <rect x="920" y="302" width="248" height="156" rx="14" fill="#ffffff" stroke="#64748b" stroke-width="2.5"/>
+ <text x="944" y="333" font-size="26" font-weight="600" fill="#334155" data-box="944 307 200 34">Same session</text>
+ <text x="944" y="411" font-size="24" fill="#334155" data-box="944 387 200 32">Starts without</text>
+ <text x="944" y="445" font-size="24" fill="#334155" data-box="944 421 200 32">history or clone</text>
+
+ <!-- Upward recording paths. The dashed file path starts at turn five. -->
+ <g fill="none" stroke="#4f46e5" stroke-width="3" marker-end="url(#timeline-trace-arrow)">
+ <path d="M112 301V233"/><path d="M212 301V233"/><path d="M312 301V233"/>
+ <path d="M412 301V233"/><path d="M512 301V233"/><path d="M1048 301V233"/>
+ </g>
+ <path d="M531 369H560V210" fill="none" stroke="#695aa1" stroke-width="3" stroke-dasharray="7 5" stroke-linejoin="round" marker-end="url(#timeline-file-arrow)"/>
+ <g fill="#ffffff" stroke="#ea580c" stroke-width="3">
+ <circle cx="112" cy="369" r="19"/>
+ <circle cx="212" cy="369" r="19"/>
+ <circle cx="312" cy="369" r="19"/>
+ <circle cx="412" cy="369" r="19"/>
+ <circle cx="512" cy="369" r="19"/>
+ <circle cx="1048" cy="369" r="19"/>
+ </g>
+ <g text-anchor="middle" font-size="24" fill="#9a3412">
+ <text x="112" y="377" data-box="98 353 28 30">1</text>
+ <text x="212" y="377" data-box="198 353 28 30">2</text>
+ <text x="312" y="377" data-box="298 353 28 30">3</text>
+ <text x="412" y="377" data-box="398 353 28 30">4</text>
+ <text x="512" y="377" data-box="498 353 28 30">5</text>
+ <text x="1048" y="377" data-box="1034 353 28 30">6</text>
+ </g>
+
+ <path d="M56 507V480" fill="none" stroke="#4f46e5" stroke-width="3" marker-end="url(#timeline-trace-arrow)"/>
+ <text x="74" y="502" font-size="24" fill="#3730a3" data-box="74 478 196 32">LangSmith wire</text>
+ <path d="M284 507V480" fill="none" stroke="#695aa1" stroke-width="3" stroke-dasharray="7 5" marker-end="url(#timeline-file-arrow)"/>
+ <text x="302" y="502" font-size="24" fill="#5b21b6" data-box="302 478 400 32">asz-changes โ shared EFS</text>
+ <text x="1144" y="502" text-anchor="end" font-size="24" fill="#475569" data-box="820 478 324 32">Recorded while running</text>
+</svg>
diff --git a/content/blog/2026-10-10-ai-sessionizer-agentcore/index.md b/content/blog/2026-10-10-ai-sessionizer-agentcore/index.md
new file mode 100644
index 000000000000..3a484a1c54c6
--- /dev/null
+++ b/content/blog/2026-10-10-ai-sessionizer-agentcore/index.md
@@ -0,0 +1,240 @@
+---
+title: "Recorded as the Session Runs, Kept When It Ends: LangGraph on Amazon Bedrock AgentCore"
+date: 2026-10-10
+author: Sheng Wu
+description: "Run a LangGraph agent on Amazon Bedrock AgentCore Runtime and record every turn, model prompt, tool call and file change in Apache SkyWalking AI Sessionizer while the session runs, kept after it ends, with no change to the agent's logic."
+tags:
+ - AI
+ - Engineering
+ - Community
+---
+
+
+
+On **[Amazon Bedrock AgentCore Runtime](https://aws.amazon.com/bedrock/agentcore/)**, each session runs in its own isolated execution environment, with its own CPU, memory and disk. An agent that keeps its conversation in that memory and its working files on that disk, as the simplest LangGraph agent does, loses both when AgentCore stops the environment, by default after 15 idle minutes. The session id stays valid; the next call with it gets a new environment, empty.
+
+So when an answer is wrong, or a file the agent wrote is, the evidence can be gone before anyone asks the questions that matter: **what exactly was the model sent on that turn, which tool result led it there, and what did the tools actually change?**
+
+This post runs a LangGraph agent on AgentCore Runtime with [Apache SkyWalking AI Sessionizer](https://github.com/apache/skywalking-ai-sessionizer) recording each turn as it happens: the runs, model calls and tool calls through LangChain's own tracing client, and the files a tool changed through a small recorder. Sessionizer, a separate, long-lived service, keeps that record after the session's environment stops. The agent's logic does not change for it; the runtime's environment and a pa [...]
+
+## Configuration, not code
+
+The agent is a small LangGraph "deployment advisor" with six tools. Three look facts up: `search_docs`, `check_deployment` and `estimate_cost`. Three work on a clone of the demo repository inside the session's environment: `clone_demo_repo`, `read_file` and `write_file`. Its only AgentCore-specific code is the entrypoint, which any agent on AgentCore has. Shortened from the demo's `agent/app.py`:
+
+```python
+from bedrock_agentcore.runtime import BedrockAgentCoreApp, BedrockAgentCoreContext
+from langchain_core.messages import HumanMessage
+
+graph = build_graph() # Nova Pro, six tools, compiled with an InMemorySaver
+app = BedrockAgentCoreApp()
+
+
+@app.entrypoint
+def invoke(payload: dict) -> dict:
+ # One AgentCore runtime session is one conversation.
+ thread_id = payload.get("thread_id") or BedrockAgentCoreContext.get_session_id()
+ result = graph.invoke(
+ {"messages": [HumanMessage(payload["prompt"])]},
+ config={"configurable": {"thread_id": thread_id},
+ "metadata": {"thread_id": thread_id}},
+ )
+ return {"thread_id": thread_id, "answer": result["messages"][-1].text}
+```
+
+Nothing there is about Sessionizer. The recording rides on two things a LangChain agent already has: the `langsmith` tracing client, which comes with `langchain-core`, and LangChain's callback hooks. The runtime's environment turns both on:
+
+```hcl
+environment_variables = {
+ # The conversation: runs, model calls, tool calls.
+ LANGSMITH_TRACING = "true"
+ LANGSMITH_ENDPOINT = "http://${aws_lb.ingest.dns_name}:1985"
+ LANGSMITH_API_KEY = random_password.asz_ingest_token.result
+ LANGSMITH_PROJECT = "aws-agentcore-asz-demo"
+ # What the tools changed on disk.
+ ASZ_CHANGES = "true"
+ ASZ_WATCH = "/home/agent/workspace"
+ ASZ_CHANGES_DATA = "/mnt/changes"
+}
+```
+
+The first four point the tracing client at Sessionizer's receiver instead of LangSmith's cloud, the same four as on the laptop with a different address. The other three switch on file-change recording. The image carries `asz-changes`, built from the Sessionizer source, and a small LangChain shim, installed with `pip` and switched on with `asz-langchain enable`; the application never imports it. At interpreter start the shim attaches a callback that runs `asz-changes` before and after eac [...]
+
+That is the convenience: the agent's logic, its framework and its model calls stay as they are. What changes is configuration on the runtime and a package in the image.
+
+## Two services, two lifecycles
+
+The tracing client inside the agent neither knows nor cares that it runs on AgentCore. Four things around it change on AgentCore.
+
+- **There is no sidecar.** AgentCore Runtime runs one image per agent, in an environment per session, and an environment lives only as long as its session. Sessionizer is the opposite: a long-lived service with durable storage and a replay page. So the two run as separate services, Sessionizer as one task on **Amazon Elastic Container Service (ECS)** with **AWS Fargate**.
+- **`127.0.0.1` is now the session's environment.** AgentCore's VPC mode places the agent's network interfaces in subnets you choose of your **Amazon Virtual Private Cloud (VPC)**, so the receiver can stay private, behind an internal **Application Load Balancer (ALB)** only the agent's security group may call.
+- **File changes need shared storage.** `asz-changes` writes on the agent's side and Sessionizer reads on its own, so the two share a directory on the network: **Amazon Elastic File System (EFS)**, AWS's managed network file system, mounted over NFS inside the VPC. AgentCore mounts an EFS access point into every session's environment at `/mnt/changes`, and Sessionizer's task mounts the same directory at `/asz/changes`. Neither side reaches into the other.
+- **The session is the conversation.** The caller keeps the session id: it picks one, at least 33 characters, or takes the one AgentCore returns from the first call, and sends it with every call of the conversation. AgentCore routes calls with the same id to the same session, and the id stays valid after an idle stop. The agent only reads the id of the request, with `BedrockAgentCoreContext.get_session_id()`, and uses it as the thread, so one AgentCore session is one Sessionizer conversation.
+
+
+Figure 1: Two services, two lifecycles. The agent is ephemeral and per session; Sessionizer is persistent and shared. Two paths connect them: the LangSmith wire to a private receiver, and file changes through a shared EFS directory.</br>
+
+## Wiring it on AWS
+
+The [demo repository](https://github.com/wu-sheng/aws-agentcore-asz-demo) builds everything in Figure 1 with OpenTofu, the agent included. AWS provider 6.x has an `aws_bedrockagentcore_agent_runtime` resource, so the runtime sits in the same state as the network, the storage and the receiver it points at. Beside the environment above, the runtime needs its network and the shared directory:
+
+```hcl
+resource "aws_bedrockagentcore_agent_runtime" "agent" {
+ # ...
+ network_configuration {
+ network_mode = "VPC"
+ network_mode_config {
+ subnets = aws_subnet.private[*].id
+ security_groups = [aws_security_group.agent.id]
+ }
+ }
+
+ filesystem_configuration {
+ efs_access_point {
+ access_point_arn = aws_efs_access_point.changes.arn
+ mount_path = "/mnt/changes"
+ }
+ }
+}
+```
+
+Sessionizer runs from its published multi-arch image as one ECS Fargate task, with two adapters: the receiver for the conversation and the `changes` adapter for the file changes.
+
+```yaml
+storage:
+ root: /asz/data
+adapters:
+ - name: langsmith-ingest
+ enabled: true
+ listen: 0.0.0.0:1985
+ token: <generated>
+ collector: { mode: watch, interval: 30s }
+ - name: changes
+ enabled: true
+ source_root: /asz/changes
+ collector: { mode: watch, interval: 30s }
+```
+
+A few details decide whether this works the first time:
+
+- **The receiver.** It is an adapter of its own, off by default, on port 1985, not on the replay page's 8787. Its default address is `127.0.0.1:1985`, which no load balancer can reach inside a container, so it listens on `0.0.0.0`. And it assembles what it received every 30 seconds here, instead of its default ten minutes.
+- **The shared directory.** The EFS access point writes everything as uid 65532, the user Sessionizer runs as, so Sessionizer owns what the agent wrote. The execution role needs `elasticfilesystem:ClientMount` and `ClientWrite` on the file system, conditioned on the access point, as the AgentCore guide says. `CreateAgentRuntime` also checks `elasticfilesystem:DescribeAccessPoints` and `DescribeMountTargets`, which the guide does not list, and it checks them without a resource, so a polic [...]
+- **One workspace per conversation.** `asz-changes` keeps one baseline per watched directory, and every session shares its data directory. With one workspace path for all of them, a conversation's first watched tool call is compared with another session's leftovers. The demo's agent works in a directory per conversation and points `ASZ_WATCH` at it each turn.
+- **The image.** AgentCore runs images only from **Amazon Elastic Container Registry (ECR)**. The demo's image is built and published by GitHub Actions; `up.sh` copies it into the account's ECR.
+
+This is a demonstration, so a few things in it are not how you would run it for a team. The replay page is plain HTTP, behind a load balancer only your IP may reach, and has no login of its own. The receiver token sits in the environment, where **AWS Secrets Manager** belongs. And the agent's memory is in memory, the subject of [a later section](#when-the-session-goes-idle).
+
+## One session, one conversation
+
+The demo has no chat application. `invoke.sh` stands in for one user's client: it creates one session id, then sends five prepared questions with `aws bedrock-agentcore invoke-agent-runtime`, all with that `--runtime-session-id`, and a sixth follows on the same session after a long pause, sent the same way. Each is a separate invocation, and all of them land in one conversation in Sessionizer, named from the project and the session id.
+
+In a real deployment, the application around the agent controls the session itself: it keeps one session id for each user's conversation, sends it with every message, and starts a new one when a conversation should start fresh. AgentCore does not map sessions to users, and the agent only reads the id each request carries.
+
+
+Figure 2: One conversation: six talks, 19 model calls and one file change of 29 lines, over 17 minutes. Its title is the first question; the id under it holds the project and the AgentCore session id, shortened, and `invoke.sh` prints the full id.</br>
+
+
+Figure 3: Six AgentCore invocations, one conversation. Each talk opens with the question the caller sent and ends with the agent's answer.</br>
+
+Opening a talk shows the agent loop inside it. The second question asks why tracing to port 8787 landed nothing; Nova Pro called `search_docs` with `ingest_port` and answered from the result:
+
+
+Figure 4: The second talk: the model calls, and the tool step with its input and its result shown together.</br>
+
+## What the model was sent
+
+The first question this post asked is answered by the model call's Prompt tab. Sessionizer lands what each call was sent beside the conversation and rebuilds it on request:
+
+
+Figure 5: The second talk's last model call, 1,140 tokens in and 78 out. Its eight messages include the whole first talk, which ran in a different AgentCore invocation.</br>
+
+The prompt proves the session carried the history: the first question, Nova Pro's reasoning, its tool call, the result and the answer all belonged to an earlier invocation. That is the in-memory checkpointer at work inside one environment. As in the previous post, the body is LangChain's view of what it sent, not the bytes Bedrock received, and the record says so.
+
+## What the tools changed, and what the agent said they changed
+
+The fifth question asks the agent to clone the demo repository and prepare `infra/terraform/terraform.tfvars` from the example, with a new IP and idle sessions stopped after five minutes. Nova Pro answered:
+
+> The `infra/terraform/terraform.tfvars` file has been successfully created with the specified values, including the `agentcore_idle_timeout` set to stop idle sessions after 5 minutes.
+
+The file is in the session environment's local workspace, and that copy is lost when the environment stops. Sessionizer keeps what `asz-changes` recorded while `write_file` ran, in that step's Changes tab.
+
+
+Figure 6: What the tool did, not what the agent said: `terraform.tfvars` created in the session's workspace, 29 lines, the diff in full.</br>
+
+The IP is right. The last line is not. The demo has no variable named `agentcore_idle_timeout`; the line should have read `agent_idle_session_timeout = 300`, in seconds. With the invented name, OpenTofu would only warn about an undeclared variable and keep the default 15 minutes. The same talk's tool calls say why: the agent read `terraform.tfvars.example`, which has no idle-timeout line, never opened `variables.tf`, and made a name up. The answer reads as done; the record shows what was done.
+
+## When the session goes idle
+
+By default AgentCore stops a session's execution environment after 15 idle minutes, or after 8 hours at most. The session id stays valid, and the next call with it gets a new environment. The [AgentCore documentation](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-sessions.html) is plain about what that costs: data kept in memory, conversation history included, lasts only as long as the compute it was kept in. The workspace on its disk goes the same way.
+
+
+Figure 7: The record continues where the session's environment does not.</br>
+
+**The conversation does not stop with the environment. The caller sends the same session id after the stop, the agent uses it as the same thread, and Sessionizer files the next call in the same conversation, after the turns before it.** In this run, `invoke.sh` sent the sixth question with the session id it had used for the first five, and the sixth talk landed in the conversation that held the first five, about sixteen minutes after the fifth: Figure 3 shows it below the fifth, after a [...]
+
+What the stop did take is the agent's own context. The sixth question went out on the same session id about sixteen minutes after the fifth: "Earlier in this session you changed a file in my repository. Which file was it, and what did you change?" Nova Pro answered:
+
+> The file that was changed earlier in this session is `infra/terraform/terraform.tfvars.example`. The changes made to the file were the addition of the `aws_region` and `project_name` variables, as well as the modification of the `asz_ui_cidrs` variable to include your public IP address.
+
+It names the wrong file and misstates what was done: the file was `terraform.tfvars`, it was created, and its invented line was `agentcore_idle_timeout`. Nothing failed, and the answer is fluent. Sessionizer, which received this turn the same way as the five before it, shows why:
+
+
+Figure 8: The sixth talk's first model call: the system prompt and the new question, and nothing before them.</br>
+
+That call was sent 791 tokens, about what the first talk's first call was sent, 796; the fifth talk's first call, in the old environment, had been sent 2,010. The checkpointer started empty in a new environment. The agent then cloned the repository again, since the clone had gone with the old environment, read the example file, and described it as its own work. In the previous talk of the same conversation, the `write_file` step still holds the real change (Figure 6).
+
+That is what recording while the session runs is worth on AgentCore. When the session's environment is gone, the agent's memory and its files are gone with it, and its account of what happened is only as good as what it can still see. The record is not: in Sessionizer the conversation went on across the stop, six talks in one record, and it still holds what the agent no longer can.
+
+Sessionizer keeps that record for you to read; it does not hand it back to the agent. The fix for the agent's memory belongs in the agent: keep LangGraph's checkpoints somewhere that outlives the session's environment. `AgentCoreMemorySaver` from [`langgraph-checkpoint-aws`](https://pypi.org/project/langgraph-checkpoint-aws/) keeps them in **Amazon Bedrock AgentCore Memory**, and AgentCore's [session storage](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-filesyste [...]
+
+## Next to AgentCore Observability
+
+AgentCore has observability of its own. In **Amazon CloudWatch** it shows the runtime's sessions, their traces and spans, and with OpenTelemetry instrumentation in the agent, the model and tool calls inside them and their intermediate outputs. That is the place to watch the runtime across every session: latency, errors and usage.
+
+Sessionizer adds a conversation view: the turns of one session as one record across invocations and environments, each model call's request rebuilt beside it, each watched tool's diff attached to its step, all of it kept in storage you own. This demo sets up only that part.
+
+## Share it through SkyWalking
+
+This post ran Sessionizer in its simple mode: it collects, stores and serves the replay page itself. To make conversations from many agents available in SkyWalking, add an **OpenTelemetry Protocol (OTLP)** export to the same configuration, as the [previous post](/blog/2026-09-23-ai-sessionizer-langchain-langgraph/#share-it-with-the-team) shows. The conversations then appear in Horizon's **AI Agents** views under the runtime LangChain. Collection does not change: the agent still sends the [...]
+
+## Try it on your AgentCore agent
+
+### On an agent you already run
+
+If your LangGraph or LangChain agent runs on AgentCore Runtime today, recording it takes four steps, none of them in the agent's logic:
+
+1. **Run Sessionizer where the runtime can reach it**, with the `langsmith-ingest` receiver on, a token, and `listen: 0.0.0.0:1985`. The demo runs it as one ECS task behind an internal ALB.
+2. **Set four environment variables on the runtime**: `LANGSMITH_TRACING=true`, `LANGSMITH_ENDPOINT` at the receiver, `LANGSMITH_API_KEY` as its token, and `LANGSMITH_PROJECT`.
+3. **Use the session id as the conversation**: pass `BedrockAgentCoreContext.get_session_id()` as the LangGraph thread and put it in the run metadata.
+4. **To record file changes too**, add `asz-changes` and `apache-skywalking-asz-langchain` to the image, from the same Sessionizer commit as the server, and run `asz-langchain enable`. Name the tools that write in the recorder's `settings.yaml`, set the three `ASZ_*` variables, and mount one EFS access point into the runtime and into Sessionizer, where the `changes` adapter reads it.
+
+The [LangChain and LangGraph guide](https://skywalking.apache.org/docs/skywalking-ai-sessionizer/next/en/setup/langchain/) covers steps 1 to 3, and the [plugin guide](https://skywalking.apache.org/docs/skywalking-ai-sessionizer/next/en/setup/langchain-plugin/) covers step 4.
+
+### Run the demo
+
+You need an AWS account with the AWS CLI signed in, OpenTofu and Docker. From a clone of the [demo repository](https://github.com/wu-sheng/aws-agentcore-asz-demo):
+
+```sh
+cp infra/terraform/terraform.tfvars.example infra/terraform/terraform.tfvars
+# set asz_ui_cidrs to your IP: curl -s https://checkip.amazonaws.com
+./scripts/up.sh # about ten minutes
+./scripts/invoke.sh # the five turns; prints the session id and the replay page
+./scripts/down.sh # when you are done
+```
+
+- **The model.** Amazon Nova Pro is the default and needs no extra step; `BEDROCK_MODEL_ID=<model id> ./scripts/up.sh` picks another. Claude models need the account's one-time Anthropic use-case form, and AWS does not serve every newer Claude model to every account, so `up.sh` calls the model once and stops before it creates anything if the account cannot use it.
+- **The agent image.** GitHub Actions builds it and publishes it to GitHub Container Registry; `up.sh` copies it into your account's ECR, since AgentCore runs images only from there. Nothing is built on your machine.
+- **The region.** AgentCore's VPC mode works only in [some Availability Zones](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/agentcore-vpc.html): `use1-az1`, `use1-az2` and `use1-az4` in `us-east-1`. Set `availability_zone_ids` if `up.sh` stops at the runtime's subnets.
+- **The cost.** The fixed infrastructure costs about $0.125 an hour while it is up, most of it the NAT gateway and the two load balancers, before AgentCore, Bedrock and storage usage.
+- **The teardown.** `down.sh` deletes everything, the recorded conversations included. AWS keeps AgentCore's network interfaces for hours after the runtime is gone, about ten in our run, and with them the VPC, two subnets and a security group, none of which cost anything. `down.sh` says so and exits; `./scripts/down.sh check` shows the progress, and `./scripts/down.sh --yes` later finishes.
+
+### What to look at
+
+Open the replay page `invoke.sh` printed, then:
+
+1. **The second talk's last model call, Prompt tab.** The first talk is in it, although it ran in another invocation.
+2. **The fifth talk's `write_file` step, Changes tab.** What the tool wrote, next to what the agent said it wrote.
+3. **A turn after the idle timeout.** Wait at least 15 minutes, send one more turn on the same session with `SESSION=<session id> ./scripts/invoke.sh "<question>"`, and open its first model call. The earlier turns are not in it, and the agent answers as if they never happened.
+
+Then point an agent you already run at Sessionizer, and the next time a session surprises someone, read what the model was sent, and what its tools did, on the turn that went wrong.
+
+Questions and findings are welcome in [Apache SkyWalking Discussions](https://github.com/apache/skywalking/discussions), and the source is in the [Apache SkyWalking AI Sessionizer repository](https://github.com/apache/skywalking-ai-sessionizer).
diff --git a/content/blog/2026-10-10-ai-sessionizer-agentcore/prompt-request.png b/content/blog/2026-10-10-ai-sessionizer-agentcore/prompt-request.png
new file mode 100644
index 000000000000..4b14fc411cb7
Binary files /dev/null and b/content/blog/2026-10-10-ai-sessionizer-agentcore/prompt-request.png differ
diff --git a/content/blog/2026-10-10-ai-sessionizer-agentcore/tool-change.png b/content/blog/2026-10-10-ai-sessionizer-agentcore/tool-change.png
new file mode 100644
index 000000000000..c624b747c015
Binary files /dev/null and b/content/blog/2026-10-10-ai-sessionizer-agentcore/tool-change.png differ
diff --git a/content/blog/2026-10-10-ai-sessionizer-agentcore/turn-steps.png b/content/blog/2026-10-10-ai-sessionizer-agentcore/turn-steps.png
new file mode 100644
index 000000000000..848ab3aebef6
Binary files /dev/null and b/content/blog/2026-10-10-ai-sessionizer-agentcore/turn-steps.png differ