Choosing an AI agent stack: the roles of Vertex AI, Bedrock AgentCore, and LangGraph
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.
AWS services for running agents, connecting tools, and storing information. The services can be combined as needed.
A framework for defining execution order and branching as connected steps in code. Storage integrations support interruption and resumption.
The AI that produces an answer from input text or data. In this article it can also select the next tool to use.
An operation made available to an AI agent, such as checking inventory or placing an order. Application code or an API performs the operation.
Saving data so it remains available after the application's current process stops.
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.
Deciding whether a person or program may perform a particular operation on a particular resource.
An input value passed to a function or tool, such as a product ID or order quantity.
Agent Development Kit: Google's development framework for assembling AI agent logic and tools in code.
The machinery or environment that runs code. In cloud product names here, it mainly means the environment hosting the application.
A Google Cloud feature for storing messages and operation events within a conversation.
In AgentCore, a feature for storing conversation history and information used across conversations.
LangGraph's mechanism for saving execution state for resumption. Recovery after process termination needs storage that retains the data.
A storage mechanism or location. LangGraph's Store keeps application information outside graph state, including cross-thread user preferences.
In AgentCore, a service for connecting existing APIs and other services as agent tools.
An AgentCore feature that handles credentials and related access to services.
A representation of connected processing steps. Nodes are the steps; edges are the connections determining what runs next.
Storage retaining required state after compute stops.
Reusable components and conventions for building an application. Here they help define execution order and branching in code.
A Google Cloud feature for creating, storing, and retrieving information across conversations.
An AgentCore feature that manages a repeating model-and-tool loop from a specified model, instructions, and tools.
Placing an application or code change in the environment where it will run.
One processing step in a graph, such as checking inventory, validating input, or waiting for approval.
A connection determining how execution moves from one graph node to another.
A running instance of a program. Information held only in its memory is lost when it ends.
In LangGraph, an identifier-scoped sequence of executions and saved state. It is distinct from a CPU execution thread.
Checking who made a request, for example through a login or signature verification.
A data format using named fields, values, and arrays. This article uses it to record case identifiers and approval status.
An ADK join point that collects outputs from parallel work before passing them on. Business validity of those values requires separate checks.
Persisted graph state and execution information used for recovery.
A LangGraph checkpointer that keeps state only in process memory. That state cannot be recovered after the process ends.
A unit grouping related conversations or calls. Reusing its ID does not necessarily mean the same running program continues to exist.
A lightweight virtual machine. AgentCore uses these to isolate session execution environments.
An AgentCore ID associating related calls with one session. The application manages the association with the user.
The ID used to locate a LangGraph thread's saved state. It is not a credential; access to that thread must be checked separately.
Server-side application logic that receives requests and checks or stores data.
A LangGraph function that pauses execution for external input. On resumption, the node containing it runs again from its beginning.
A saved record of execution state and the next work to run. It does not by itself establish whether an external order was accepted.
A group of reads and writes treated as one unit, so changes within its scope can be committed or rolled back together.
Keys identifying retries of the same operation to prevent duplicate outcomes.
The incoming side of a connection. Here it refers to checking requests arriving at Gateway from the application.
The outgoing side of a connection. Here it refers to authentication for requests from Gateway to a connected service.
An IAM role a service uses to access AWS resources.
AWS Identity and Access Management: controls which operations users and services may perform.
A mechanism for delegating scoped access without handing a user's password to the service receiving that access.
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.
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.
| Responsibility | What it does | Example components |
|---|---|---|
| calls | Interpret text; generate answers or calls | on Google Cloud, Amazon Bedrock, or other providers |
| Orchestration | Determine next steps, branches, parallel work, and approval waits | , , or a managed agent loop |
| Hosting | Deploy application code and run it when invoked | Google Cloud Agent , Runtime, or your own hosting |
| Keep conversations, resumable execution state, and cross-conversation information | , , , , and other storage | |
| Business connectivity | Expose and manage credentials for downstream connections | Functions 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.
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 component | Responsibility | Application decisions |
|---|---|---|
| Bedrock | Interpret requests and explain proposals | definitions, context, and call limits |
| with a durable | Control execution and persist resumable state | Branches, approval waits, and -to-case mapping |
| Host and run the agent | Storage connectivity and restoration after termination | |
| Order and approval database | Maintain authoritative business records | Proposal revisions, approval records, and operation IDs |
| Order accessed through | Connect the and orders | Connection 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 example | Data passed downstream | Decision after the join |
|---|---|---|
| Lookup succeeded | Entity ID, value, retrieval time, and source | Validate target, freshness, and other conditions |
| Information unavailable | Entity ID, unresolved status, and reason | Retry, clarify, or hold instead of inventing a value |
| produced no output | No valid success result | Inspect 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 information | Storage in this example | What storage alone does not establish |
|---|---|---|
| Conversation and state needed for the next operation | A durable | Whether approval and permissions remain valid |
| Explanation preferences across conversations | A tenant-and-user-scoped | Current order state or action permission |
| Proposal revision and approval record | Business database | Whether the external order was actually accepted |
| Submitted operation and order acceptance | Business database plus order reconciliation | The 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.
| Identifier | What it identifies | Resume-time check |
|---|---|---|
| case_id | Business case | Tenant and current case state |
| Persisted execution state | Whether this case and user may access the | |
| execution | -managed user and conversation mapping | |
| operation_id | One business order operation | Whether 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.
{
"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.
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.
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.
- Approver: Approve a specific proposal revision
- Business backend: Validate approval, permissions, and current state
- Graph execution: Call the order API with a stable operation_id
- Order API: Order accepted, but the response is lost
- Graph execution: On resume, do not assume the unpersisted result succeeded
- 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 location | Check in this example | Keep distinct |
|---|---|---|
| request | Caller and access conditions for the selected mode | A valid signature or login does not authorize all business actions |
| target request | Delegated user permissions versus shared service credentials | Shared connection credentials are not the end user’s permissions |
| Ordering business | Tenant, product, quantity, proposal revision, approval, and current permissions | Discovering 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.
| Scenario | Expected behavior | Evidence to inspect |
|---|---|---|
| Delivery lookup unavailable at the join | Hold as unresolved without inventing a date | Branch result, provenance, and hold reason |
| Compute stops during an approval wait | Restore the correct and recheck current approval | Case, , user mapping, and |
| Approval callback or resume request repeats | Match the same approval and prevent duplicate action outcomes | Approval record, operation ID, and external acceptance |
| Proposal changes during the wait | Do not execute under approval for the old revision | Approved revision versus current revision |
| Order accepted but response lost | Query the same operation; hold while unresolved | Order records and local operation state |
| Caller supplies another user’s or tenant ID | Reject reads, resume, and execution | Authenticated principal and server-authorized target |
| changes while a run is waiting | Use compatible code and state or migrate deliberately | Code 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
- First define business completion and hold conditions. Specify where proposal revisions, approvals, operation IDs, and acceptance results are stored.
- 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.
- 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.
- Google Cloud — Agents overview: ADK, Agent Runtime, Sessions, and Memory Bank
- AWS — Tool use with Amazon Bedrock models
- LangGraph — Overview
- Google Cloud — Agent Runtime framework quickstart
- Google Cloud — Agent Platform release notes
- Google ADK — Graph routes and JoinNode
- AWS — Amazon Bedrock AgentCore overview
- AWS — Bedrock Agents Classic maintenance mode
- AWS — AgentCore Runtime sessions
- AWS — Gateway inbound authorization
- AWS — Gateway outbound authorization
- LangGraph — Persistence: Checkpointer and Store
- LangGraph — Checkpointers
- LangGraph — Interrupts and node replay
Tips this post digs into
- Choose the framework and the Vertex AI hosting layer separately
- Give every ADK join branch an output and a failure policy
- Design AgentCore session isolation separately from durability
- Separate LangGraph Checkpointer state from Store data
- Resuming a LangGraph interrupt replays the node from its beginning
- Separate AgentCore Gateway inbound authorization from target authentication