NashTech Blog

Operationalizing an Agentic-AI Underwriting System on Amazon Bedrock

Table of Contents

In the previous two blogs in this series, we explored:

  1. Why Agentic AI matters for underwriting – highlighting the limitations of monolithic models and the need for decomposing underwriting decisions into specialized reasoning units
  2. 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:

  1. Deciding agents’ responsibilities
  2. Creating Amazon Bedrock agents
  3. Wiring AWS Lambda action groups
  4. Building multi-agent orchestration flows
  5. 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.

AgentResponsibility
Supervisor AgentOrchestrates workflow, routes tasks
Document Extraction AgentExtracts data from structured/unstructured documents (forms)
Risk Scoring AgentComputes underwriting risk
Compliance AgentApplies rules/regulations
Pricing AgentDetermines 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 🙂

Picture of Himanshu Gupta

Himanshu Gupta

Himanshu Gupta is a Principal Architect passionate about building scalable systems, AI‑driven solutions, and high‑impact digital platforms. He enjoys exploring emerging technologies, writing technical articles, and creating accelerators that help teams move faster. Outside of work, he focuses on continuous learning and sharing knowledge with the tech community.

Leave a Comment

Your email address will not be published. Required fields are marked *

Suggested Article

Scroll to Top