> For the complete documentation index, see [llms.txt](https://docs.karini.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.karini.ai/agentic-ai-workshops/energy-and-utilities/billguard-build-an-agent-workflow-for-meter-to-cash-delayed-bills.md).

# BillGuard: Build an Agent Workflow for Meter-to-Cash Delayed Bills

Build BillGuard, a webhook-triggered workflow where a router sorts each request, one agent investigates a delayed bill and emails a brief to a reviewer, and another agent reads the reviewer’s reply and produces the resolution card.

**Lab time:** about 60 to 75 minutes, including one end-to-end case

### **The Problem**

An account lands on the daily reconciliation report because its meter read date has passed and no invoice was generated. If nobody fixes it by day 10, the billing system raises a B108 delayed bill exception, and on day 15 the customer receives a delayed bill letter. To fix it, an analyst has to check the billing period, meter reads, smart meter (AMI) reads, devices, service orders and account notes, decide what went wrong, and get a reviewer to agree before anything changes. The data is spread across systems, and the review step is often the slowest part.

### **What You Will Build**

BillGuard, a delayed bill workflow with a human reviewer in the loop:

1. **BillGuard Router** decides whether a request is a new case or a reviewer reply.
2. **BillGuard Investigator** queries the meter-to-cash data, writes an investigation brief, and emails it to the reviewer for a decision.
3. **BillGuard Resolver** reads the reviewer’s email reply (approve, correct or escalate), applies the standard operating procedure, and produces a resolution card.

You’ll finish by running a case end to end: the brief lands in your inbox, you reply as the reviewer, and the workflow picks up your reply and resolves the case.

### What You Will Learn

* Trigger an agent workflow from an external system using a webhook
* Put a human reviewer in the loop by email, and read the reply back with a mail connector
* Use a router to send each request to the right agent
* Give an agent read-only access to a database, with a data catalog as a fallback when its standard queries are not enough
* Keep agents on safe rails: read-only data, one recipient, and recommendations that are never executed

### Build Order

Create the catalog first, then the two agents, then the router, and the recipe last. A recipe can only use prompts, tools, and skills that already exist.

<table><thead><tr><th width="81.33331298828125">Step</th><th width="266.8887939453125">You create</th><th>Contains</th></tr></thead><tbody><tr><td>1</td><td>Catalog: M2C Catalog</td><td>Schema b108_ws, 9 tables with generated descriptions</td></tr><tr><td>2</td><td>Agent: BillGuard Investigator</td><td>3 tools (M2C_DB, M2C_Catalog, Reviewer_Email) and 1 skill (b108-investigation)</td></tr><tr><td>3</td><td>Agent: BillGuard Resolver</td><td>No tools, 1 skill (b108-resolution)</td></tr><tr><td>4</td><td>Router: BillGuard Router</td><td>Prompt only, no tools</td></tr><tr><td>5</td><td>Recipe: billguard-workflow</td><td>Case Intake (webhook), Reviewer Inbox (connector), Start, BillGuard Router, 2 agents, End</td></tr><tr><td>6</td><td>End-to-end test</td><td>One case, one reviewer reply</td></tr></tbody></table>

### Before You Start

Your instructor has prepared the following so you can focus on building the agents:

* Login to Karini AI at app.karini.ai
* The skills **b108-investigation** and **b108-resolution**, available in the Skills Library
* The prompt templates **BillGuard Investigator**, **BillGuard Resolver**, and **BillGuard Router**, available in Prompt Playground → Prompt templates
* The workshop database schema **b108\_ws**, which you turn into a catalog in [Step 1](#step-1-create-the-m2c-catalog)
* PostgreSQL credentials for the Meter-to-Cash database: host, user name, and password
* The Delayed Bill Desk app link (<https://bill-desk.karini.ai>) and a test case

Every template, tool, and node name in this guide matches what is set up in Karini. Use them exactly as written: the prompts call the tools by these names, and the router answers with the node labels, so a different name breaks the workflow.

### Words You Will See

* **Prompt Playground:** where you create agents and prompts, attach tools and skills, and test them
* **Prompt template:** a ready-made prompt stored in Karini. You load it with Use template instead of typing it.
* **Tool:** something an agent can call, such as a database, a catalog, or email
* **Skill:** a folder of detailed instructions and reference files that an agent reads when it needs it
* **Catalog**: a searchable description of the database tables and columns. BillGuard Investigator uses it only as a fallback: its skill already has the queries for a normal investigation, so it calls the catalog only when a query fails on an unknown table or column, or when the command asks for data the skill does not cover. It calls it at most twice per case.
* **M2C:** short for Meter-to-Cash, the utility process from reading the meter to collecting payment. The workshop database stands in for SAP IS-U billing data, the AMI daily reads portal, and the daily reconciliation report.
* **Router:** a node that decides which path a request takes. Here it sends new cases to BillGuard Investigator and reviewer replies to BillGuard Resolver.
* **Connector:** a recipe node that reads emails from a mailbox. Here it picks up the reviewer’s replies.
* **Human in the loop:** a person reviews the agent’s work and decides before anything else happens
* **Webhook:** a URL that lets an outside system start your recipe. The Delayed Bill Desk app calls it.
* **Recipe:** the workflow that connects everything on a canvas
* **Publish:** saves a version that recipes can use. Saved but unpublished changes are not used.
* **Deploy:** makes a published recipe version live, so the webhook uses it. Click Actions → Deploy after you publish.

## Step 1: Create the M2C Catalog

### 1.1 Create the catalog

1. From the left menu, open Catalog Schemas.
2. Click Add new in the top right corner and fill in:<br>

   <table><thead><tr><th width="213.555419921875">Field</th><th>Value</th></tr></thead><tbody><tr><td>Name</td><td>M2C Catalog</td></tr><tr><td>Connector type</td><td>PostgreSQL</td></tr><tr><td>Host, User name, User password</td><td>From your instructor</td></tr><tr><td>Database</td><td>postgres</td></tr><tr><td>Port</td><td>5432</td></tr></tbody></table>
3. Click Save.

### 1.2 Import the b108\_ws schema

1. In the Catalog Schemas list, click your catalog. Its status is Pending import.
2. Click **Browse schema**. The Catalog explorer under View schema lists every database and schema on the server.
3. Expand postgres and tick **b108\_ws** only. Do not tick b108\_app; it belongs to the Delayed Bill Desk app.
4. Click Import selected schemas. The status changes to Pending publish, and Imported schema lists the 9 tables of b108\_ws.

### 1.3 Generate metadata for all 9 tables

1. In **Imported schema**, expand `postgres` and locate `b108_ws`.
2. Click the **Generate Metadata** button action next to `b108_ws` to generate descriptions for all tables at once.
3. Wait until the table and column descriptions are generated before proceeding.

### 1.4 Publish the catalog

1. Click **Publish** in the top right corner.\ <mark style="color:$danger;">\[Hint: Expand the schema, A yellow table icon means its fields still need descriptions; a grey icon means the descriptions are generated. Check that all 9 icons are grey after you publish.]</mark>
2. Go back to Catalog Schemas and check that your catalog shows published.

Only a published catalog can be added as a tool in [Step 2.3.](#id-2.3-add-tool-2-m2c_catalog)

{% embed url="<https://www.loom.com/share/24e428d5cbde4919a8a1e8ccc970ed3c>" %}

## Step 2: Create the BillGuard Investigator Agent

### 2.1 Create the prompt

1. From the left menu, open Prompt Playground.
2. Click Add new in the top right corner.
3. Click Prompt templates, select **Name** from the dropdown next to the search field, search for **BillGuard Investigator**, select it, and click **Use template**. The template sets the prompt name to **BillGuard Investigator**.
4. Check that Task is **Agent** and set Max State Updates to **30**.
5. Set your subject tag.&#x20;

   1. Under **Variables**, find `subject_filter`.
   2. Enter a unique subject tag, for example `[Review-S12]`. Replace `S12` with your own student/ /unique number. <mark style="color:$danger;">The square brackets</mark> <mark style="color:$danger;"></mark><mark style="color:$danger;">`[]`</mark> <mark style="color:$danger;"></mark><mark style="color:$danger;">are required.</mark>
   3. Keep the prompt line `SUBJECT_TAG: {subject_filter}` unchanged. The variable will use the tag you entered.

   **Important:** Use the same tag throughout the remaining steps whenever `subject_filter` or the email Subject filter is requested.
6. Click **Save**.
7. After saving, reopen the created **BillGuard Investigator** prompt to continue with the Tool configuration.

<mark style="color:$danger;">\[Hint: Save before you move to the Tools or Skills tab, or your changes are lost]</mark>

### 2.2 Add tool 1: M2C\_DB

1. Open the **Tools** tab, click **Add new**, and select **Agent tools.**
2. Fill in:

   <table><thead><tr><th width="213.555419921875">Field</th><th>Value</th></tr></thead><tbody><tr><td>Name</td><td>M2C_DB (exactly, no spaces: the prompt calls the tool by this name)</td></tr><tr><td>Description</td><td>&#x3C;Copy the text below exactly></td></tr><tr><td>Type</td><td>Database</td></tr><tr><td>Connector type</td><td>PostgreSQL</td></tr><tr><td>Host, User name, User password</td><td>From your instructor</td></tr><tr><td>Database</td><td>postgres</td></tr><tr><td>Port</td><td>5432</td></tr></tbody></table>

   \
   Description text:

   <pre data-overflow="wrap"><code>Runs read-only SQL SELECT queries against the PostgreSQL schema b108_ws, a workshop stand-in for SAP IS-U billing data, the AMI daily reads portal, and the daily reconciliation report. Use it to fetch the delayed bill case, installation and billing period, ISU meter reads, AMI daily reads, devices and MDM profile status, service orders, account notes, and invoice history for a given queue_id. Always schema-qualify tables (b108_ws.table_name). SELECT only: INSERT, UPDATE, DELETE and DDL are not permitted and will fail. Prefer the queries in the b108-investigation skill's references/sql-templates.md. Input: a single SQL SELECT statement. Output: result rows.
   </code></pre>
3. Click Test and wait for PostgreSQL connection test passed.
4. Click Save.

### 2.3 Add tool 2: M2C\_Catalog

1. Open the **Tools** tab, click **Add new**, and select **Agent tools.**
2. Fill in:

   <table><thead><tr><th width="213.555419921875">Field</th><th>Value</th></tr></thead><tbody><tr><td>Name</td><td>M2C_Catalog (exactly, no spaces: the prompt calls the tool by this name)</td></tr><tr><td>Description</td><td>&#x3C;Copy the text below exactly></td></tr><tr><td>Type</td><td>Catalog</td></tr><tr><td>Catalog Name</td><td>Search for your catalog from Step 1, for example M2C Catalog, and select it</td></tr></tbody></table>

   \
   Description text:

   <pre data-overflow="wrap"><code>Retrieves table and column metadata for schema b108_ws, including table names, column names, and data types. Use sparingly (maximum twice per investigation) to verify table or column names before writing a query for M2C_DB. Reference the b108-investigation skill's data-map.md for complete documentation of all nine tables.
   </code></pre>
3. Click Save.

### 2.4 Add tool 3: Reviewer\_Email

1. Open the Tools tab, click Add new, and select Agent tools.
2. Fill in:

   <table><thead><tr><th width="213.555419921875">Field</th><th>Value</th></tr></thead><tbody><tr><td>Name</td><td>Reviewer_Email (exactly: the prompt calls the tool by this name)</td></tr><tr><td>Description</td><td>&#x3C;Copy the text below exactly></td></tr><tr><td>Type</td><td>Messaging</td></tr><tr><td>Messaging Type</td><td>Email</td></tr><tr><td>Provider</td><td>Gmail</td></tr><tr><td>Overwrite credentials</td><td>Off: the workshop sender account is already configured</td></tr></tbody></table>

   \
   Description text:

   <pre data-overflow="wrap"><code>Sends one HTML review email for a B108 delayed bill case to the assigned reviewer (the hitl_email from the case input). Use it once per case, after the investigation brief is complete, with the subject and body from the b108-investigation skill's references/review-email-template.md. Do not use it for any other recipient or purpose. Inputs: recipient_email (the reviewer only), subject, email_message (the HTML body). Output: send status.
   </code></pre>
3. In **Recipient email**, enter your own **email address**, add a **subject** and **body**, and click Test.
4. When Test passed appears, then click **Save**.

The Tools tab now shows 3 tools: M2C\_DB, M2C\_Catalog and Reviewer\_Email.

### 2.5 Add the skill

1. Open the **Skills tab**, click **Add new**, and select **Custom**.
2. Search for **b108-investigation** and click Add. This skill holds the investigation steps, the SQL templates, the data map, and the brief and review email templates.

### 2.6 Test & Compare

1. Open the Test & Compare tab.
2. In Agent input, paste the test case below. Replace the last line with your own email address: you are the reviewer.

   <pre data-overflow="wrap"><code>run_id: R-TEST01
   queue_id: Q-1001
   command: Investigate and recommend a resolution
   hitl_email: your.name@example.com
   </code></pre>
3. Select two models to compare: Claude Sonnet 5.5 and Claude Haiku 5.5.
4. Click Test.
5. **Format the response (optional):** Click **Format response** in the top-right corner to format the agent's output for easier reading. Then compare the outputs from both models.
6. Compare the outputs. Each should start with a status line PHASE: EMAIL\_SENT | RUN: R-TEST01 | QUEUE: Q-1001, followed by the investigation brief: the findings from the database, a leading hypothesis with a confidence score, and any alternative.
7. Check your inbox for the review email. Its subject starts with subject\_filter tag and then the run ID, for example \[B108-REVIEW-S12]\[R-TEST01]. Keep it for [Step 3.](#step-3-create-the-billguard-resolver-agent)
8. Click Select as best answer on the best output to set the Primary Model.\ <mark style="color:$danger;">\[Recommend :  Use Claude Sonnet 5.5 as the Primary Model, as it may provide better results for detailed investigation and reasoning. ]</mark>&#x20;
9. Optional: click Select as best answer on the other output to set the Fallback Model.
10. Click Save **prompt run** in the right corner.<br>

    Optional: see the catalog fallback.

    1. In Test & Compare, paste this Agent input (use your own email on the last line):

       <pre data-overflow="wrap"><code>run_id: R-CATT01 
       queue_id: Q-1001 
       command: Investigate this bill and also report the customer's payment history and outstanding balance. 
       hitl_email: your.name@example.com
       </code></pre>
    2. Click Test, then open Traces.
    3. Check: after the M2C\_DB queries there is one M2C\_Catalog call, and the brief says the payment history is not available in the data. The rest of the brief is the same as your first test.
    4. Compare with your first test (R-TEST01): it made no M2C\_Catalog call. The catalog is used only when the standard queries are not enough.
    5. Do not reply to this test email.<br>
11. Click **Save**, reopen the saved **BillGuard Investigator** prompt then **Publish**.

Only published prompts are visible in the recipe, so do not skip Publish. While the agent runs, open Traces to watch each M2C\_DB query and the Reviewer\_Email call as they happen.

## Step 3: Create the BillGuard Resolver Agent

### 3.1 Create the prompt

1. In Prompt Playground, click Add new.
2. Click Prompt templates, select **Name** from the dropdown next to the search field, search for **BillGuard Resolver**, select it, and click **Use template.** The template sets the prompt name to **BillGuard Resolver.**
3. Check that Task is **Agent** and set Max State Updates to **30**.
4. Click Save.
5. After saving, reopen the created **BillGuard Resolver** prompt to continue with the skill configuration in [Section 3.2.](#id-3.2-add-the-skill)

This agent has no tools. It reads the reviewer’s reply and the skill, and recommends actions without executing them.

### 3.2 Add the skill

1. Open the **Skills tab,** click **Add new**, and select **Custom**.
2. Search for **b108-resolution** and click **Add**. This skill holds the standard operating procedure, the reply-reading rules, and the resolution card template.

### 3.3 Test & Compare

1. Reply to the review email from [Step 2.6](#id-2.6-test-and-compare). Follow the reply instructions at the top of that email: write your decision (APPROVE, CORRECT or ESCALATE) and, for CORRECT, your comments. Send the reply.\ <mark style="color:$danger;">\[Hint: In Gmail, open the review email and click Reply without selecting any text first. Gmail then includes the original email automatically; you can see it behind the ⋯ button. Do not delete it. The workflow reads the investigation brief from that quoted part. If it is missing, the case is escalated with "Brief not found in reply".]</mark>
2. Open the reply email you sent in your email application. Copy the entire email from top to bottom, including the From and Subject lines, your full reply, and the quoted review email below it.\
   \
   Sample Testcase:&#x20;

   <pre data-overflow="wrap"><code>DECISION: CORRECT
   COMMENTS: Valid AMI reading of 43438.900 is available in the portal for 2026-10-21 and should be manually posted to ISU to resolve the sync gap.

   On Wed, 28 Oct, 2026, 1:01 pm , &#x3C;shared_inbox@karini.ai> wrote:
   B108 delayed bill review: Q-1001

   Run: R-TEST01
   Assigned reviewer: ashish.jadhav@karini.ai
   B108 date: 2026-10-31 (3 days left)

   HOW TO REPLY

   Reply to this email. Put your decision on the FIRST line of your reply:

   DECISION: APPROVE
   DECISION: CORRECT
   DECISION: ESCALATE

   Then, on the next line:

   COMMENTS: &#x3C;your comments> (required for CORRECT, optional otherwise)

   Keep the quoted text below in your reply. Do not edit anything between the marker lines.

   ===== B108 BRIEF START =====

   Investigation brief: Q-1001

   Command:	Investigate and recommend a resolution
   Account:	9100000101 | Installation: 7000000101 | Division / rate: ELEC / RES_E1
   Timeline:	MRO date 2026-10-21 | Days unbilled 7 | B108 on 2026-10-31 (3 days left) | Letter on 2026-11-05
   Billing period

   Last billed to 2026-09-21. Period expected to bill: 2026-09-22 to 2026-10-21. Billing block: none.

   Evidence

   Check	Finding	Flag
   ISU meter reads	Device D-101 (AMI5510001): read for MRO date 2026-10-21 is MISSING (note: "No read received from head-end"). Prior reads 2026-09-21, 2026-08-22 and 2026-07-22 are ACTUAL. No estimated reads.	ISSUE
   AMI portal reads	AMI5510001 has a VALID daily read on 2026-10-21 (43438.900), the MRO date, and VALID reads on 2026-10-19, 10-20, 10-22 and 10-23. The 2026-10-21 AMI read is missing from ISU.	ISSUE
   Devices and MDM profile	One device, D-101 (AMI), installed 2021-03-02, not removed, MDM profile ACTIVE. No exchange in the period.	OK
   Service orders	No service orders found for the installation.	OK
   Notes	No account notes found.	OK
   Leading hypothesis

   Root cause label: AMI_READ_AVAILABLE
   Confidence: 0.90

   Why: The ISU read for the MRO date 2026-10-21 is MISSING because no read arrived from the head-end (ISU meter reads row). A VALID AMI daily read of 43438.900 exists for the same date (AMI portal reads row). The device is active with an ACTIVE MDM profile, there is no billing block, and there are no service orders or notes that explain the gap.

   Alternatives not ruled out

   None
   For the analyst

   Confirm that the AMI read of 43438.900 on 2026-10-21 is plausible against the 2026-09-21 ISU actual of 42705.000 before approving it as the billing read.

   ===== B108 BRIEF END =====

   Nothing has been changed in SAP or the billing data. This is an investigation only.
   </code></pre>
3. Paste it into Agent input.
4. Open the Test & Compare tab.
5. Select two models to compare: Claude Sonnet 5.5 and Claude Haiku 5.5.
6. Click Test.
7. **Format the response (optional):** Click **Format response** in the top-right corner to format the agent's output for easier reading. Then compare the outputs from both models.
8. Compare the outputs. Each should start with a status line PHASE: RESOLVED | RUN: R-TEST01 | QUEUE: Q-1001 | OUTCOME: ... | DECISION: ..., followed by the resolution card. Every recommended action is marked NOT EXECUTED.
9. Click Select as best answer on the best output to set the Primary Model.\ <mark style="color:$danger;">\[Recommend :  Use Claude Sonnet 5.5 as the Primary Model, as it may provide better results for detailed investigation and reasoning. ]</mark>&#x20;
10. Optional: click Select as best answer on the other output to set the Fallback Model.
11. Click Save prompt run in the right corner.
12. Click Save, reopen the saved **BillGuard Resolver** prompt then **Publish**.

## Step 4: Create the BillGuard Router

### 4.1 Create the prompt

1. In Prompt Playground, click Add new.
2. Click Prompt templates, select **Name** from the dropdown next to the search field, search for **BillGuard Router**, select it, and click Use template. The template sets the prompt name to **BillGuard Router.**
3. Check that Task is **Summarization**. Select it here even though this prompt classifies requests rather than summarizing them.
4. Click Save.
5. After saving, reopen the created **BillGuard Router** prompt.

### 4.2 Test & Compare

Run two tests: one new case and one reviewer reply.

1. In the input, paste the test case from [Step 2.6.](#id-2.6-test-and-compare)

   <pre data-overflow="wrap"><code>run_id: R-TEST01
   queue_id: Q-1001
   command: Investigate and recommend a resolution
   hitl_email: your.name@example.com
   </code></pre>
2. Open the Test & Compare tab and select Claude Sonnet 5.5 and Claude Haiku 5.5.
3. Click Test. Both should answer **{"next": "BillGuard Investigator"}.**
4. Clear the input field, then paste the test case from [Step 3.3.](#id-3.3-test-and-compare)

   <pre data-overflow="wrap"><code>DECISION: CORRECT
   COMMENTS: Valid AMI reading of 43438.900 is available in the portal for 2026-10-21 and should be manually posted to ISU to resolve the sync gap.

   On Wed, 28 Oct, 2026, 1:01 pm , &#x3C;shared_inbox@karini.ai> wrote:
   B108 delayed bill review: Q-1001

   Run: R-TEST01
   Assigned reviewer: ashish.jadhav@karini.ai
   B108 date: 2026-10-31 (3 days left)

   HOW TO REPLY

   Reply to this email. Put your decision on the FIRST line of your reply:

   DECISION: APPROVE
   DECISION: CORRECT
   DECISION: ESCALATE

   Then, on the next line:

   COMMENTS: &#x3C;your comments> (required for CORRECT, optional otherwise)

   Keep the quoted text below in your reply. Do not edit anything between the marker lines.

   ===== B108 BRIEF START =====

   Investigation brief: Q-1001

   Command:	Investigate and recommend a resolution
   Account:	9100000101 | Installation: 7000000101 | Division / rate: ELEC / RES_E1
   Timeline:	MRO date 2026-10-21 | Days unbilled 7 | B108 on 2026-10-31 (3 days left) | Letter on 2026-11-05
   Billing period

   Last billed to 2026-09-21. Period expected to bill: 2026-09-22 to 2026-10-21. Billing block: none.

   Evidence

   Check	Finding	Flag
   ISU meter reads	Device D-101 (AMI5510001): read for MRO date 2026-10-21 is MISSING (note: "No read received from head-end"). Prior reads 2026-09-21, 2026-08-22 and 2026-07-22 are ACTUAL. No estimated reads.	ISSUE
   AMI portal reads	AMI5510001 has a VALID daily read on 2026-10-21 (43438.900), the MRO date, and VALID reads on 2026-10-19, 10-20, 10-22 and 10-23. The 2026-10-21 AMI read is missing from ISU.	ISSUE
   Devices and MDM profile	One device, D-101 (AMI), installed 2021-03-02, not removed, MDM profile ACTIVE. No exchange in the period.	OK
   Service orders	No service orders found for the installation.	OK
   Notes	No account notes found.	OK
   Leading hypothesis

   Root cause label: AMI_READ_AVAILABLE
   Confidence: 0.90

   Why: The ISU read for the MRO date 2026-10-21 is MISSING because no read arrived from the head-end (ISU meter reads row). A VALID AMI daily read of 43438.900 exists for the same date (AMI portal reads row). The device is active with an ACTIVE MDM profile, there is no billing block, and there are no service orders or notes that explain the gap.

   Alternatives not ruled out

   None
   For the analyst

   Confirm that the AMI read of 43438.900 on 2026-10-21 is plausible against the 2026-09-21 ISU actual of 42705.000 before approving it as the billing read.

   ===== B108 BRIEF END =====

   Nothing has been changed in SAP or the billing data. This is an investigation only.
   </code></pre>
5. Click Test again. Both should answer **{"next": "BillGuard Resolver"}.**
6. Click Select as best answer on the best output to set the Primary Model.\ <mark style="color:$danger;">\[Recommend :  Use Claude Sonnet 5.5 as the Primary Model, as it may provide better results for detailed investigation and reasoning. ]</mark>&#x20;
7. Optional: click Select as best answer on the other output to set the Fallback Model.
8. Click Save prompt run in the right corner.
9. Click **Save**, reopen the saved **BillGuard** Router prompt then **Publish**.

The router makes a simple choice between two paths on every request, so a smaller, faster, cheaper model like Haiku usually does it as well as a larger one. Save the larger model for the agents.

## Step 5: Create the Karini Recipe with Bedrock AgentCore Runtime

### 5.1 Create the recipe

1. From the left menu, open Recipes and click Add new in the top corner.
2. Configure the recipe:

| Field       | Value                                                                                                     |
| ----------- | --------------------------------------------------------------------------------------------------------- |
| Name        | billguard-workflow                                                                                        |
| Description | Investigates delayed bill (B108) cases, routes them for reviewer approval, and recommends SOP resolutions |
| Type        | Workflow                                                                                                  |
| Runtime     | AgentCore                                                                                                 |

### 5.2 Add the nodes

Drag each element from Elements onto the canvas, then click it to fill in the right panel.

<table><thead><tr><th width="50.111083984375">#</th><th width="121.6666259765625">Element</th><th width="156.6666259765625">Label</th><th>Settings in the right panel</th></tr></thead><tbody><tr><td>1</td><td>Webhook</td><td>Case Intake</td><td>Keep the defaults</td></tr><tr><td>2</td><td>Connector</td><td>Reviewer Inbox</td><td><strong>Connector type:</strong> Email,<br><strong>Provider:</strong> Gmail,<br><strong>Overwrite credentials:</strong> off,<br><strong>Email count</strong>: 5,<br><strong>Date:</strong> today’s date,<br><strong>Subject :</strong> your tag from Step 2.1, item 5, for example [B108-REVIEW-S12]. It must be exactly the same text you gave subject_filter on the BillGuard Investigator node.</td></tr><tr><td>3</td><td>Start</td><td>Start</td><td>None</td></tr><tr><td>4</td><td>Router</td><td>BillGuard Router</td><td><strong>Node method:</strong> Prompt,<br><strong>Prompt:</strong> BillGuard Router.<br><strong>State settings:</strong> <br><strong>Document cache:</strong> on (Retrieve Document),<br><strong>Messages:</strong> on (All messages), <br><strong>Metadata:</strong> off</td></tr><tr><td>5</td><td>Agent</td><td>BillGuard Investigator</td><td><strong>Prompt</strong>: BillGuard Investigator.<br><strong>Variables</strong>: <strong>subject_filter</strong>: Validate your tag from Step <a href="#id-2.1-create-the-prompt">2.1</a>, item 5, for example [B108-REVIEW-S12]. Same text as the Reviewer Inbox Subject filter.<br><strong>State settings:</strong> Messages on (Last message).</td></tr><tr><td>6</td><td>Agent</td><td>BillGuard Resolver</td><td><p><strong>Prompt</strong>: BillGuard Resolver.<br><strong>State settings:</strong> <br><strong>Document cache:</strong> on (Retrieve Document),<br><strong>Messages</strong> on, <br><strong>Message context:</strong> Node message,<br><strong>Variables:</strong> context<br><strong>From</strong>: Start</p><p><strong>Message:</strong> (All message).</p></td></tr><tr><td>7</td><td>End</td><td>End</td><td>None</td></tr></tbody></table>

<mark style="color:$danger;">\[The labels BillGuard Investigator and BillGuard Resolver must be exact. The router answers with the label of the next node.]</mark>

**Subject filter for your connector.** Everyone’s reviewer replies arrive in the same shared workshop mailbox. BillGuard Investigator starts every review email subject with your tag and then the run ID, for example \[B108-REVIEW-S12]\[R-7F3K2Q] Q-1001 - Delayed bill review, and the reviewer’s reply keeps that subject. Your Reviewer Inbox connector reads only emails whose subject contains your tag, so it never picks up another student’s replies. Set the same tag in three places: subject\_filter in the Test & Compare test ([Step 2.6](#id-2.6-test-and-compare)), subject\_filter on the BillGuard Investigator node, and the Reviewer Inbox Subject filter. Never use the plain tag \[B108-REVIEW] on its own; it is reserved for the instructor’s recipe.

### 5.3 Connect the nodes

| From                   | To                     |
| ---------------------- | ---------------------- |
| Case Intake            | Reviewer Inbox         |
| Reviewer Inbox         | Start                  |
| Start                  | BillGuard Router       |
| BillGuard Router       | BillGuard Investigator |
| BillGuard Router       | BillGuard Resolver     |
| BillGuard Investigator | End                    |
| BillGuard Resolver     | End                    |

The router has two connections: new cases go to BillGuard Investigator, reviewer replies go to BillGuard Resolver.

### 5.4 Recipe settings, test, and deploy

1. Click an empty area of the canvas and set Number of state updates to 100.
2. Click **Save**,  reopen the saved **Recipe** then **Publish**.
3. Click **Actions** → **Deploy** after you publish.
4. Click the Case Intake node and **copy** the **Webhook URL** and **Webhook token**. Click Generate new token if the token is empty. Your recipe ID is the last part of the webhook URL.

{% embed url="<https://www.loom.com/share/c369cae69b2c4209bc5594baf6ed1a74>" %}

## Step 6: Run a Case End to End

1. Open the Delayed Bill Desk app (<https://bill-desk.karini.ai>) in a new tab and test the application.
2. On the Start page, enter your **email** and the **workshop access token** provided by your instructor, then click **Start**.
3. Enter your recipe ID and webhook token, and validate your email address as the reviewer.
4. Click **Run agent** next to the test case you want to investigate. The app will start the investigation and automatically generate a unique Run ID for that case.
5. Open Traces in Karini to watch the run: BillGuard Router sends the case to BillGuard Investigator, you see each M2C\_DB query, and then the Reviewer\_Email call.
6. Check your inbox for the review email. Its subject starts with your tag and the run ID, for example \[B108-REVIEW-S12]\[R-7F3K2Q].
7. Reply to it as the reviewer: APPROVE, CORRECT with comments, or ESCALATE.\
   \ <mark style="color:$danger;">\[Hint: In Gmail, open the review email and click Reply without selecting any text first. Gmail then includes the original email automatically; you can see it behind the ⋯ button. Do not delete it. The workflow reads the investigation brief from that quoted part. If it is missing, the case is escalated with "Brief not found in reply".]</mark>\
   \
   Example:

   <pre data-overflow="wrap"><code>DECISION: ESCALATE
   COMMENTS: The replacement meter (serial M4401127) was never recorded in ISU following the meter exchange on 2026-10-07. The account should be escalated to the metering/MDM team to create the device record and activate the MDM profile so that billing can proceed.
   </code></pre>
8. In the Delayed Bill Desk app, Click **Check replies now** to run a reply check. Your Reviewer Inbox connector picks up your reply, BillGuard Router sends it to BillGuard Resolver, and the resolution card appears.
9. Try a second case and answer CORRECT with a comment. Check that the card says what changed because of your comment.

This is the moment that shows the value: the agent did the investigation, a person made the decision, and the workflow carried that decision into a documented resolution without anyone retyping the case.
