In the previous two blogs in this series, we explored:
- Why Agentic AI matters for underwriting – highlighting the limitations of monolithic models and the need for decomposing underwriting decisions into specialized reasoning units
- A reference architecture for an Agentic underwriting system – introducing the concept of supervisor-led orchestration, specialized agents, and governed decision flows
Those discussions established a key principle:
Underwriting is not a single decision problem – it is a coordinated system of decisions, each requiring different context, controls, and accountability mechanisms.
However, a critical gap still remains, i.e., most architecture discussions stop at diagrams. They don’t answer the question that most of the CTOs and platform teams ultimately face, i.e.,
How do you actually build, govern, and operate a multi‑agent underwriting system in production?
From Architecture to Operations
Moving from a conceptual architecture to a production system introduces a new set of constraints:
- Regulatory accountability: Every decision must be traceable
- Cost control: Multi-agent systems can scale unpredictably
- Operational reliability: Failures must be isolated and recoverable
- Human oversight: Not all decisions can be automated
This is where many promising AI initiatives stall. Not due to lack of capability, but due to lack of operational design.
Why Amazon Bedrock for Multi‑Agent Underwriting?
Amazon Bedrock provides a practical foundation to operationalize these ideas:
- Managed foundation models for underwriting intelligence
- Agents framework to orchestrate multi-step workflows
- Lambda-backed action groups to execute business logic
- Built-in guardrails, observability, and scaling primitives
More importantly, it supports a multi-agent collaboration model, where a supervisor agent decomposes tasks and routes them to specialized agents. Exactly aligning with the underwriting decomposition we saw earlier.
What This Guide Will Show?
This blog focuses on the missing layer between architecture and reality. We’ll learn how to:
- Implement a multi-agent underwriting workflow on Bedrock
- Use AWS Lambda as the execution backbone for underwriting logic
- Introduce human-in-the-loop controls and fairness mechanisms
Target Architecture (Recap)
We’ll be operationalizing the following architecture:

Note: Before we dive into implementation, one mindset shift is critical, i.e., we are not building an “AI model“, we are building a distributed decision system. That means:
- Agents are bounded services, not autonomous thinkers
- Lambda functions are deterministic execution units
- Orchestration is explicit and governed, not emergent
What Comes Next?
We will now walk step-by-step through how to implement this system on AWS Bedrock:
- Deciding agents’ responsibilities
- Creating Amazon Bedrock agents
- Wiring AWS Lambda action groups
- Building multi-agent orchestration flows
- Invoke the underwriting process via API Gateway & Lambda
Step 1: Deciding Agents’ Responsibilities
Amazon Bedrock supports multi‑agent collaboration via a supervisor agent, routing tasks to specialized agents.
| Agent | Responsibility |
|---|---|
| Supervisor Agent | Orchestrates workflow, routes tasks |
| Document Extraction Agent | Extracts data from structured/unstructured documents (forms) |
| Risk Scoring Agent | Computes underwriting risk |
| Compliance Agent | Applies rules/regulations |
| Pricing Agent | Determines pricing model |
This aligns with real-world production systems where orchestrators delegate to specialized agents and aggregate responses.
Step 2 – Create Amazon Bedrock Agents (Supervisor + Specialists)
I. Supervisor Agent
Instruction:
You are the underwriting orchestrator.
Your responsibilities:
1. Analyze the incoming underwriting request.
2. Identify the intent and required processing steps.
3. Decide which specialized agent(s) to call:
- extraction → document_agent
- scoring → risk_agent
- validation → compliance_agent
- pricing -> pricing_agent
4. Call agents in the correct sequence if multiple steps are required.
5. Combine outputs from all agents into a final response.
6. Assign a confidence score (0–1) for the final decision.
7. Calculate pricing using the confidence score.
8. Escalate to a human if:
- confidence < 0.75
- missing or inconsistent data is detected
- compliance risk is unclear
- pricing > 600
Strict rules:
- Do NOT perform extraction, scoring, compliance, or pricing tasks yourself.
- Only orchestrate and aggregate.
- Always produce structured JSON output.
Output format:
{
"final_decision": "...",
"confidence": 0.0,
"pricing": 0.0,
"escalate": true/false,
"reason": "..."
}
II. Document Agent (Extraction Specialist)
Instruction:
You are the document extraction agent.
Your responsibilities:
1. Extract structured data from underwriting documents.
2. Identify key fields such as:
- applicant details
- financial information
- policy details
- supporting documents
3. Normalize extracted values into consistent formats.
4. Flag missing, incomplete, or ambiguous data.
Strict rules:
- Do NOT perform risk scoring or compliance validation.
- Do NOT make approval decisions.
- Focus only on accurate data extraction.
Output format:
{
"extracted_data": {
"applicant_name": "...",
"income": "...",
"credit_score": "...",
"age": "...",
"country": "..."
},
"missing_fields": ["..."]
}
Key Principle: Define clear roles with minimal overlap to avoid agent conflicts. Hence, we need to define similar instructions for rest of agents (risk, compliance, and pricing) as well. For full instruction set, for all agents, refer to the following GitHub repo – agentic-insurance-underwriting.
Step 3 – Add Action Groups (Lambda Integration)
In Amazon Bedrock, agent(s) do not execute the business logic directly. They call Lambda functions via action groups.
Example: Document Extraction Lambda
import json
import logging
from typing import Dict, Any
from http import HTTPStatus
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event: Dict[str, Any], context: Any) -> Dict[str, Any]:
"""
AWS Lambda handler for processing Bedrock agent requests.
Args:
event (Dict[str, Any]): The Lambda event containing action details
context (Any): The Lambda context object
Returns:
Dict[str, Any]: Response containing the action execution results
Raises:
KeyError: If required fields are missing from the event
"""
try:
action_group = event['actionGroup']
function = event['function']
message_version = event.get('messageVersion',1)
parameters = event.get('parameters', {})
# Convert list to dictionary
params = {
param["name"]: param["value"]
for param in parameters
}
document_text = str(params["document_text"])
# If body is a JSON string
body = json.loads(document_text)
applicant_name = body.get("applicant_name")
income = body.get("income")
credit_score = body.get("credit_score")
age = body.get("age")
country = body.get("country")
response_body = {
"applicant_name": applicant_name,
"income": income,
"credit_score": credit_score,
"age": age,
"country": country
}
logger.info('Response: %s', response_body)
return {
"messageVersion": message_version,
"response": {
"actionGroup": action_group,
"function": function,
"functionResponse": {
"responseBody": {
"TEXT": {
"body": json.dumps(response_body)
}
}
}
}
}
except KeyError as e:
logger.error('Missing required field: %s', str(e))
return {
'statusCode': HTTPStatus.BAD_REQUEST,
'body': f'Error: {str(e)}'
}
except Exception as e:
logger.error('Unexpected error: %s', str(e))
return {
'statusCode': HTTPStatus.INTERNAL_SERVER_ERROR,
'body': 'Internal server error'
}
For lambda functions, of all agents, refer to the following GitHub repo – agentic-insurance-underwriting.
Step 4 – Invoke the System via API Gateway + Lambda
We typically expose the system like this:

Invocation Lambda
import json
import boto3
import uuid
# Create Bedrock Agent Runtime client
bedrock_agent_runtime = boto3.client("bedrock-agent-runtime")
AGENT_ID = "AB3DEF7HI0"
AGENT_ALIAS_ID = "KLMNOPQRST"
def lambda_handler(event, context):
try:
# Parse request body
body = json.loads(event.get("body", "{}"))
user_input = body.get("input", "")
if not user_input:
return {
"statusCode": 400,
"body": json.dumps({"error": "Missing input"})
}
# Generate session ID (or pass from client)
session_id = str(uuid.uuid4())
# Call Bedrock Agent
response = bedrock_agent_runtime.invoke_agent(
agentId=AGENT_ID,
agentAliasId=AGENT_ALIAS_ID,
sessionId=session_id,
inputText=user_input
)
# Extract response text
completion = ""
for event_chunk in response.get("completion", []):
if "chunk" in event_chunk:
completion += event_chunk["chunk"]["bytes"].decode("utf-8")
return {
"statusCode": 200,
"body": json.dumps({
"response": completion
})
}
except Exception as e:
return {
"statusCode": 500,
"body": json.dumps({
"error": str(e)
})
}
API Gateway

Client
For client, we are using cURL. But you can use any client (JS, Java, Python, etc.)
curl --location 'https://abce9u489h.execute-api.us-east-2.amazonaws.com/insurance/quote' \
--header 'Content-Type: application/json' \
--data '{
"input": "What is my insurance eligibility?"
}'
Sample Response

In Summary
We saw a fully auditable Agentic AI underwriting system built on a production-ready design, enabling scalable multi-agent orchestration while maintaining cost-aware deployment on Amazon Bedrock. Together, these capabilities ensure reliability, traceability, and efficiency across the entire workflow.
In future blogs, we will explore how to further enhance this system by incorporating governance using Guardrails, comprehensive monitoring/logging, and cost optimization strategies to make the solution more robust. So stay tuned 🙂