All posts

Choosing an AI agent stack: the roles of Vertex AI, Bedrock AgentCore, and LangGraph

· 18 min read

Designing your first business AI agent? Learn how and interact, how orchestration differs from hosting and storage, and where Vertex AI services, Bedrock , and fit. Apply these foundations to a procurement architecture with approval and recovery.

Select a dotted-underlined term in the text to read its explanation.

Terms in this article (46)
AgentCore
AWS services for running agents, connecting tools, and storing information. The services can be combined as needed.
LangGraph
A framework for defining execution order and branching as connected steps in code. Storage integrations support interruption and resumption.
model
The AI that produces an answer from input text or data. In this article it can also select the next tool to use.
tool
An operation made available to an AI agent, such as checking inventory or placing an order. Application code or an API performs the operation.
persistence
Saving data so it remains available after the application's current process stops.
API
An interface through which one program requests work or data from another. An ordering API, for example, accepts a product and quantity to place an order.
authorization
Deciding whether a person or program may perform a particular operation on a particular resource.
argument
An input value passed to a function or tool, such as a product ID or order quantity.
ADK
Agent Development Kit: Google's development framework for assembling AI agent logic and tools in code.
runtime
The machinery or environment that runs code. In cloud product names here, it mainly means the environment hosting the application.
Google Cloud Sessions
A Google Cloud feature for storing messages and operation events within a conversation.
AgentCore Memory
In AgentCore, a feature for storing conversation history and information used across conversations.
Checkpointer
LangGraph's mechanism for saving execution state for resumption. Recovery after process termination needs storage that retains the data.
Store
A storage mechanism or location. LangGraph's Store keeps application information outside graph state, including cross-thread user preferences.
Gateway
In AgentCore, a service for connecting existing APIs and other services as agent tools.
Identity
An AgentCore feature that handles credentials and related access to services.
graph
A representation of connected processing steps. Nodes are the steps; edges are the connections determining what runs next.
durable storage
Storage retaining required state after compute stops.
framework
Reusable components and conventions for building an application. Here they help define execution order and branching in code.
Memory Bank
A Google Cloud feature for creating, storing, and retrieving information across conversations.
Harness
An AgentCore feature that manages a repeating model-and-tool loop from a specified model, instructions, and tools.
deployment
Placing an application or code change in the environment where it will run.
node
One processing step in a graph, such as checking inventory, validating input, or waiting for approval.
edge
A connection determining how execution moves from one graph node to another.
process
A running instance of a program. Information held only in its memory is lost when it ends.
thread
In LangGraph, an identifier-scoped sequence of executions and saved state. It is distinct from a CPU execution thread.
authentication
Checking who made a request, for example through a login or signature verification.
JSON
A data format using named fields, values, and arrays. This article uses it to record case identifiers and approval status.
JoinNode
An ADK join point that collects outputs from parallel work before passing them on. Business validity of those values requires separate checks.
checkpoints
Persisted graph state and execution information used for recovery.
InMemorySaver
A LangGraph checkpointer that keeps state only in process memory. That state cannot be recovered after the process ends.
session
A unit grouping related conversations or calls. Reusing its ID does not necessarily mean the same running program continues to exist.
microVM
A lightweight virtual machine. AgentCore uses these to isolate session execution environments.
runtimeSessionId
An AgentCore ID associating related calls with one session. The application manages the association with the user.
thread_id
The ID used to locate a LangGraph thread's saved state. It is not a credential; access to that thread must be checked separately.
backend
Server-side application logic that receives requests and checks or stores data.
interrupt
A LangGraph function that pauses execution for external input. On resumption, the node containing it runs again from its beginning.
checkpoint
A saved record of execution state and the next work to run. It does not by itself establish whether an external order was accepted.
transaction
A group of reads and writes treated as one unit, so changes within its scope can be committed or rolled back together.
idempotency keys
Keys identifying retries of the same operation to prevent duplicate outcomes.
inbound
The incoming side of a connection. Here it refers to checking requests arriving at Gateway from the application.
outbound
The outgoing side of a connection. Here it refers to authentication for requests from Gateway to a connected service.
service role
An IAM role a service uses to access AWS resources.
IAM
AWS Identity and Access Management: controls which operations users and services may perform.
OAuth
A mechanism for delegating scoped access without handing a user's password to the service receiving that access.
SDK
A software development kit: tools and reusable code for calling a service from an application.
AgentCore

AWS services for running agents, connecting tools, and storing information. The services can be combined as needed.

LangGraph

A framework for defining execution order and branching as connected steps in code. Storage integrations support interruption and resumption.

model

The AI that produces an answer from input text or data. In this article it can also select the next tool to use.

tool

An operation made available to an AI agent, such as checking inventory or placing an order. Application code or an API performs the operation.

persistence

Saving data so it remains available after the application's current process stops.

API

An interface through which one program requests work or data from another. An ordering API, for example, accepts a product and quantity to place an order.

authorization

Deciding whether a person or program may perform a particular operation on a particular resource.

argument

An input value passed to a function or tool, such as a product ID or order quantity.

ADK

Agent Development Kit: Google's development framework for assembling AI agent logic and tools in code.

runtime

The machinery or environment that runs code. In cloud product names here, it mainly means the environment hosting the application.

Google Cloud Sessions

A Google Cloud feature for storing messages and operation events within a conversation.

AgentCore Memory

In AgentCore, a feature for storing conversation history and information used across conversations.

Checkpointer

LangGraph's mechanism for saving execution state for resumption. Recovery after process termination needs storage that retains the data.

Store

A storage mechanism or location. LangGraph's Store keeps application information outside graph state, including cross-thread user preferences.

Gateway

In AgentCore, a service for connecting existing APIs and other services as agent tools.

Identity

An AgentCore feature that handles credentials and related access to services.

graph

A representation of connected processing steps. Nodes are the steps; edges are the connections determining what runs next.

durable storage

Storage retaining required state after compute stops.

framework

Reusable components and conventions for building an application. Here they help define execution order and branching in code.

Memory Bank

A Google Cloud feature for creating, storing, and retrieving information across conversations.

Harness

An AgentCore feature that manages a repeating model-and-tool loop from a specified model, instructions, and tools.

deployment

Placing an application or code change in the environment where it will run.

node

One processing step in a graph, such as checking inventory, validating input, or waiting for approval.

edge

A connection determining how execution moves from one graph node to another.

process

A running instance of a program. Information held only in its memory is lost when it ends.

thread

In LangGraph, an identifier-scoped sequence of executions and saved state. It is distinct from a CPU execution thread.

authentication

Checking who made a request, for example through a login or signature verification.

JSON

A data format using named fields, values, and arrays. This article uses it to record case identifiers and approval status.

JoinNode

An ADK join point that collects outputs from parallel work before passing them on. Business validity of those values requires separate checks.

checkpoints

Persisted graph state and execution information used for recovery.

InMemorySaver

A LangGraph checkpointer that keeps state only in process memory. That state cannot be recovered after the process ends.

session

A unit grouping related conversations or calls. Reusing its ID does not necessarily mean the same running program continues to exist.

microVM

A lightweight virtual machine. AgentCore uses these to isolate session execution environments.

runtimeSessionId

An AgentCore ID associating related calls with one session. The application manages the association with the user.

thread_id

The ID used to locate a LangGraph thread's saved state. It is not a credential; access to that thread must be checked separately.

backend

Server-side application logic that receives requests and checks or stores data.

interrupt

A LangGraph function that pauses execution for external input. On resumption, the node containing it runs again from its beginning.

checkpoint

A saved record of execution state and the next work to run. It does not by itself establish whether an external order was accepted.

transaction

A group of reads and writes treated as one unit, so changes within its scope can be committed or rolled back together.

idempotency keys

Keys identifying retries of the same operation to prevent duplicate outcomes.

inbound

The incoming side of a connection. Here it refers to checking requests arriving at Gateway from the application.

outbound

The outgoing side of a connection. Here it refers to authentication for requests from Gateway to a connected service.

service role

An IAM role a service uses to access AWS resources.

IAM

AWS Identity and Access Management: controls which operations users and services may perform.

OAuth

A mechanism for delegating scoped access without handing a user's password to the service receiving that access.

SDK

A software development kit: tools and reusable code for calling a service from an application.

Purpose and prerequisites

Goal: Understand the roles of , orchestration, hosting, storage, and business so you can decide what to implement and what a platform can manage.

Prerequisites: You should know the basics of calling a Web and saving data in a database. Agent behavior and the responsibilities of each platform are introduced from the beginning.

Scope: Use a procurement workflow with human approval to map Vertex AI services, Bedrock , and onto an architecture. Cover resumption, duplicate-order prevention, and permission checks.

The agent loop: connecting a to

Here, an agent selects in response to a request and uses their results to continue. A generates responses from the text and data it receives; a model that supports tool calling can also return a tool name and . A tool exposes an operation, such as an inventory lookup, through a callable function or wrapper. Its definition describes its purpose and inputs to the model.

A basic application-executed tool call. Model calls and tool results can repeat as needed.

Receive the user request → Send the request and tool definitions to the model → Receive a tool name and arguments → Validate authorization and inputs; call the API → Return the result to the model; answer or continue

For example, a user asks for ten units of product A by Friday. If the requests an inventory lookup, the application validates the request and , then calls the inventory . Returning the result lets the model request a delivery-date lookup or explain that the request cannot be met. Producing a call does not itself query a database or place an order. A managed service can also execute tools on the application’s behalf.

The need not choose every step. Code can control a known inventory-and-delivery sequence while the model interprets the request and explains a proposal. Define limits on iterations, elapsed time, and cost, together with conditions for holding a failed case. Platform selection includes deciding which component enforces these controls.

The responsibilities in an agent architecture

Asking whether to use Vertex AI, Bedrock, or mixes several choices: provider, orchestration, and hosting. First separate the responsibilities an agent needs. A single product can cover more than one responsibility.

ResponsibilityWhat it doesExample components
callsInterpret text; generate answers or calls on Google Cloud, Amazon Bedrock, or other providers
OrchestrationDetermine next steps, branches, parallel work, and approval waits, , or a managed agent loop
HostingDeploy application code and run it when invokedGoogle Cloud Agent , Runtime, or your own hosting
Keep conversations, resumable execution state, and cross-conversation information, , , , and other storage
Business connectivityExpose and manage credentials for downstream connectionsFunctions that expose existing as , , , and related services

The business and databases must also maintain current order and approval records. A conversation saying “approved” is insufficient evidence that the current proposal is approved. Hosting code and restoring its state after termination are also separate capabilities. Define what to persist and how to restore it.

Google Cloud: Vertex AI services and

When researching the Vertex AI agent stack, current documentation uses Gemini Enterprise Agent Platform. Agent Engine is now called Agent . Check which capability a document describes rather than treating old and new names as competing products. This article focuses on for code-defined orchestration and Agent Runtime for hosting that code.

Google’s Agent Development Kit, or , is a for defining agents, , and orchestration in code. Agent hosts and runs implementations, including those built with frameworks other than ADK. Choosing ADK and choosing a hosting environment are separate decisions.

The storage services have different purposes. maintains interaction history within a conversation; handles user information across conversations. Remembering a conversation, resuming execution, and knowing current order status are different requirements. For a custom approval wait, identify exactly where the values needed for resumption are persisted.

AWS: Bedrock and

Amazon Bedrock provides for inference. Bedrock provides services for operating agents and connecting . Access to a model API alone does not determine where your business application runs, how approval waits are persisted, or what permissions it has on an order API.

In , hosts agents, conversational and longer-term information, connects existing and other systems as , and handles identities and service access. These services can be adopted as needed. Connecting an order API through Gateway is not sufficient grounds for letting a user modify every order.

Orchestration can use a such as or , or can provide a managed agent loop. The code your application owns depends on that choice. The worked example below uses framework-defined orchestration.

: defining a stateful workflow

defines a workflow as a . A performs work, such as a call or input validation; an determines which node runs next; state is the data that nodes read and update. A procurement graph might carry a request, lookup results, and a proposal revision, then branch according to whether approval is required. Not every node needs to call a model.

Pausing for approval and resuming later also requires of state. A , explained below, serves that purpose. Choosing does not by itself choose the provider or hosting service. Google Cloud Agent and AWS Runtime can host LangGraph implementations, so these hosting services and LangGraph are not mutually exclusive alternatives.

The example: look up facts, prepare a proposal, wait for approval, then order

Consider a fictional internal procurement workflow. The agent checks inventory and delivery dates, then prepares an order proposal. A reviewer may approve it the following day. After approval, the system submits to an existing order and confirms acceptance before marking the case complete. Producing a proposal alone is not completion.

Fictional procurement workflow: approval can outlast the executing process

Validate request and user → Look up inventory and delivery in parallel → Validate results and persist proposal → Resume after approval → Confirm order API acceptance

One possible architecture combines a Bedrock , orchestration, hosting, a durable , existing order and approval databases, and business APIs accessed through . On Google Cloud, consider or LangGraph hosted on Agent Runtime. The ADK and LangGraph sections apply the same business requirements to each ; they do not require adopting both.

Example componentResponsibilityApplication decisions
Bedrock Interpret requests and explain proposals definitions, context, and call limits
with a durable Control execution and persist resumable stateBranches, approval waits, and -to-case mapping
Host and run the agentStorage connectivity and restoration after termination
Order and approval databaseMaintain authoritative business recordsProposal revisions, approval records, and operation IDs
Order accessed through Connect the and ordersConnection and tenant, object, and action

Define the conditions for advancing this workflow: hold when inventory or delivery is unresolved, request fresh approval when the proposal changes, and reconcile an unknown order outcome. The , figures, pseudocode, and test cases below are original design examples, not product configuration files or measured results.

Parallel lookups: validate business data after

In 2.x , independent inventory and delivery lookups can branch and converge at a , a that joins upstream outputs. The documentation requires outputs from nodes entering the join. Completion of upstream processing and validity of the business data are separate checks.

Branch condition: original exampleData passed downstreamDecision after the join
Lookup succeededEntity ID, value, retrieval time, and sourceValidate target, freshness, and other conditions
Information unavailableEntity ID, unresolved status, and reasonRetry, clarify, or hold instead of inventing a value
produced no outputNo valid success resultInspect implementation or error handling; do not finalize the proposal

Turning an unavailable delivery date into an empty success field invites downstream invention. Preserve the unresolved status and validate proposal eligibility in code. If one lookup requires the other’s result, do not start those two operations as independent parallel branches.

Persist conversation, execution, and order state for different purposes

In , a persists state as for each . A thread identifies a sequence of executions and their saved state. A holds application information across threads. State needed to resume an approval wait and a preference for concise explanations have different scopes. Use current order or business database records to determine whether an order was accepted.

Persisted informationStorage in this exampleWhat storage alone does not establish
Conversation and state needed for the next operationA durable Whether approval and permissions remain valid
Explanation preferences across conversationsA tenant-and-user-scoped Current order state or action permission
Proposal revision and approval recordBusiness databaseWhether the external order was actually accepted
Submitted operation and order acceptanceBusiness database plus order reconciliationThe outcome of a lost response; query again when necessary

In self-hosted production, alone cannot restore state after the is lost. Use durable . If a service such as Agent Server manages persistence, verify its scope. Cloud conversation-history or memory services also need an integration that actually saves and restores the information required by the .

Hosting on : the same ID does not restore memory

(lightweight virtual machines) isolate execution environments, but default compute memory and disk are ephemeral. Calling the same after a stop can run on fresh compute. Configured session storage can retain files without automatically restoring variables. Do not generalize this explanation to Runtime Instances, whose storage differs.

IdentifierWhat it identifiesResume-time check
case_idBusiness caseTenant and current case state
Persisted execution stateWhether this case and user may access the
execution -managed user and conversation mapping
operation_idOne business order operationWhether a retry or query refers to the same operation

These IDs identify different things; they need not share one value. The manages their mappings and must not trust a supplied ID to select another case’s state. AWS explicitly assigns -to-user mapping to the application.

Example application record, not product configuration
{
  "tenant_id": "tenant-A",
  "case_id": "case-42",
  "thread_id": "thread-case-42",
  "runtimeSessionId": "a88003d1-7216-48ef-91bc-aee70370b77f",
  "proposal_revision": 3,
  "approval_status": "pending",
  "operation_id": "order-case-42-rev-3",
  "order_status": "not_submitted"
}

On fresh compute the next day, load persisted state and verify the proposal revision and valid approval in the business database. An old conversation saying “approved” does not approve a subsequently revised proposal.

approval waits: work before runs again

pauses for external input using . To resume, specify the same , which identifies the execution , and pass the input as the resume value in Command. The interrupted restarts from its beginning. It does not restore the Python directly at the next line.

Notification repeats on resume: Python-like pseudocode; notify_reviewer is an unimplemented application function
def approval_node(state):
    notify_reviewer(state["case_id"])
    decision = interrupt(state["proposal"])
    return {"decision": decision}

This can notify the reviewer again. Make notification attempts idempotent with a stable notification ID, or separate notification from the approval-wait node. Splitting nodes does not atomically combine notification delivery with , so retry handling still matters.

Approval-wait-only Python-like pseudocode; registration, , and downstream omitted
def approval_node(state):
    decision = interrupt({
        "case_id": state["case_id"],
        "proposal_revision": state["proposal_revision"],
        "proposal": state["proposal"],
    })
    return {"decision": decision}

The next must not order solely because decision contains a string or boolean. Match the authenticated approver, case, proposal revision, expiry, and current permissions against business approval records. Proceed only with valid approval; ask again when the proposal changed. Changes to waiting nodes also require compatibility checks for saved state and ordering.

When the order response is lost, reconcile the with the external action

Even with a separate post-approval action , the can stop after the external accepts an order but before the persists the result. The may still say “not submitted” while the order already exists. Replaying the node alone does not resolve that disagreement.

Original failure scenario: query the same operation_id; safe retries depend on the order API contract
  1. Approver: Approve a specific proposal revision
  2. Business backend: Validate approval, permissions, and current state
  3. Graph execution: Call the order API with a stable operation_id
  4. Order API: Order accepted, but the response is lost
  5. Graph execution: On resume, do not assume the unpersisted result succeeded
  6. Business backend: Query the same operation_id; hold if the outcome remains unknown

Record the order intent and operation ID first, and manage duplicate admission using conditional updates or similar controls. That local record is not one with external acceptance. If the order supports and reconciliation, reuse the same operation ID within its documented contract and retention period.

If the order provides neither deduplication nor reconciliation, do not create a fresh operation ID and submit another order while the outcome is unknown. This workflow holds the case for an operator to reconcile against the supplier’s records. A cannot manufacture guarantees that the external service does not provide.

: connectivity is not permission to order

With , handles incoming requests and handles credentials toward targets. Supported integrations can use a gateway , caller credentials, , or other modes, depending on target type. Do not assume every outbound mode propagates the inbound user’s permissions.

Check locationCheck in this exampleKeep distinct
requestCaller and access conditions for the selected modeA valid signature or login does not authorize all business actions
target requestDelegated user permissions versus shared service credentialsShared connection credentials are not the end user’s permissions
Ordering business Tenant, product, quantity, proposal revision, approval, and current permissionsDiscovering a is not proof of permission to execute it

AUTHENTICATE_ONLY specifically verifies signatures without making a decision. If authorization is offloaded, the selected component must enforce it. In this shared-connection example, bind trustworthy caller context to the business so it cannot update another customer’s products or orders.

Before rollout, test stops and resume boundaries as well as successful conversations

The following is a test plan for this fictional workflow, not executed product-test results. In addition to evaluating language quality, compare persisted state with business outcomes.

ScenarioExpected behaviorEvidence to inspect
Delivery lookup unavailable at the joinHold as unresolved without inventing a dateBranch result, provenance, and hold reason
Compute stops during an approval waitRestore the correct and recheck current approvalCase, , user mapping, and
Approval callback or resume request repeatsMatch the same approval and prevent duplicate action outcomesApproval record, operation ID, and external acceptance
Proposal changes during the waitDo not execute under approval for the old revisionApproved revision versus current revision
Order accepted but response lostQuery the same operation; hold while unresolvedOrder records and local operation state
Caller supplies another user’s or tenant IDReject reads, resume, and executionAuthenticated principal and server-authorized target
changes while a run is waitingUse compatible code and state or migrate deliberatelyCode version, state format, and resume validation

Be able to trace the resumed case, approved proposal, execution , attempted action, and external acceptance. Do not declare recovery successful from the conversation response alone; inspect unresolved cases and operator work as well.

Record the decisions in your architecture

  1. First define business completion and hold conditions. Specify where proposal revisions, approvals, operation IDs, and acceptance results are stored.
  2. Choose control logic next. known dependencies and parallelize only independent lookups. For , define and scopes and resume boundaries. For , check join and output behavior for the target version.
  3. Choose hosting and connectivity for that implementation. Validate supported versions, storage reachability, compute termination, , and through the same business-case tests.

Annotate the architecture introduced at the start with the data each component persists, where is checked, and how execution is restored. Choosing “ on ” identifies orchestration and hosting. A procurement architecture also needs a durable , approval records, and duplicate-operation handling at the order .

Primary sources and verification scope

Product behavior was checked against these official sources on October 29, 2026. Recheck region, , and target compatibility at adoption. The procurement workflow, recovery procedures, pseudocode, and test plan are explanatory designs; this article does not report cloud , live- quality or cost, or measured recovery behavior.

Tips this post digs into