Random things I do

Workflow vs Agents

Workflow vs Agents

When we automate tasks with LLMs, there are two types:

  1. Workflow-based applications.
  2. Agent-based applications.

First lets define the skeleton of automating tasks with LLMs.

Task (f): This is "like" a function. Where we give input and we want to get an output. If we can breakdown a task into composable steps (f1, f2, f3, ...)

then f = f1 o f2 o f3 o ...

Example 1: Airport Security Task

Task: Security check at the airport, where an officer checks your ID card and flight boarding pass to verify your identity.

INPUT: ID card, flight boarding pass, Person Live photo OUTPUT: Pass/Fail (Boolean Output1 and Output2)

                                  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                  โ”‚    START    โ”‚
                                  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                         โ”‚
                      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                      โ”‚                                     โ”‚
                      โ–ผ                                     โ–ผ
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ”‚ ID VERIFIER  โ”‚                  โ”‚ FLIGHT DETAILS     โ”‚
              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                  โ”‚   VERIFIER         โ”‚
                      โ”‚                         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                      โ”‚
         โ”‚            โ”‚            โ”‚                      โ”‚
         โ–ผ            โ–ผ            โ–ผ                      โ–ผ
    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚  live  โ”‚  โ”‚   id    โ”‚  โ”‚ flight  โ”‚          โ”‚   flight    โ”‚
    โ”‚  foto  โ”‚  โ”‚  image  โ”‚  โ”‚ boar.   โ”‚          โ”‚   boar.     โ”‚
    โ””โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜  โ”‚  pass   โ”‚          โ”‚   pass      โ”‚
        โ”‚            โ”‚       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ”‚            โ–ผ                                    โ”‚
        โ”‚       โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                              โ–ผ
        โ”‚       โ”‚ extract โ”‚                         โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
        โ”‚       โ”‚   id#   โ”‚                         โ”‚ extract โ”‚
        โ”‚       โ•ฐโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ•ฏ                         โ”‚ details โ”‚
        โ”‚            โ”‚ id#                          โ•ฐโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ•ฏ
        โ”‚    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                          โ”‚
        โ”‚    โ”‚                โ”‚                          โ–ผ
        โ”‚    โ–ผ                โ–ผ                   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚ โ—‡โ”€โ”€โ”€โ”€โ”€โ—‡         โ—‡โ”€โ”€โ”€โ”€โ”€โ—‡                โ”‚  - name      โ”‚
        โ”‚ โ”‚ get โ”‚         โ”‚ get โ”‚                โ”‚  - flight #  โ”‚
        โ”‚ โ”‚photoโ”‚         โ”‚name โ”‚                โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ”‚ โ”‚from โ”‚         โ”‚from โ”‚                       โ”‚
        โ”‚ โ”‚id dbโ”‚         โ”‚id dbโ”‚                       โ”‚
        โ”‚ โ—‡โ”€โ”€โ”€โ”€โ”€โ—‡         โ—‡โ”€โ”€โ”€โ”€โ”€โ—‡                       โ”‚
        โ”‚    โ”‚     db_photo   โ”‚                         โ”‚
        โ”‚    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                         โ”‚
        โ–ผ             โ”‚                                 โ”‚
   โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ        โ”‚                                 โ”‚
   โ”‚similarityโ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                 โ”‚
   โ”‚  check  โ”‚                                          โ”‚
   โ•ฐโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ•ฏ                                          โ”‚
        โ”‚                                               โ”‚
        โ”‚              โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ                     โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚ equality โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                       โ”‚  check   โ”‚
                       โ•ฐโ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ•ฏ
                            โ”‚
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ”‚                            โ”‚
              โ–ผ                            โ–ผ
       BOOLEAN OUTPUT1              BOOLEAN OUTPUT2

The above task can be automated like this:

Workflow Breakdown

The process starts at START and branches into two parallel verification paths:

ID VERIFIER Path

Inputs:

Steps:

  1. extract id#: Extract the ID number from the id image
  2. get photo from id db: Query the ID database using the extracted id# to retrieve the stored photo (db photo)
  3. get name from id db: Query the ID database using the extracted id# to retrieve the stored name
  4. similarity check: Compare the live foto with the db photo from the database
  5. BOOLEAN OUTPUT1: Result of the photo similarity check (True/False)

FLIGHT DETAILS VERIFIER Path

Inputs:

Steps:

  1. extract details: Extract information from the boarding pass:
    • Name
    • Flight number
  2. Data display node contains the extracted details

Convergence and Final Verification

equality check: Compare the name retrieved from the ID database (from ID VERIFIER path) with the name extracted from the flight boarding pass (from FLIGHT DETAILS VERIFIER path)

BOOLEAN OUTPUT2: Result of the name equality check (True/False)

Here the steps we have are:

  1. extract id#
  2. get photo from id db
  3. get name from id db
  4. "foto" similarity check
  5. extract details
  6. equality check

Here we can clearly define the order of the steps and the dependencies. For optimization, we are running steps (2-4) and (3-5) in parallel. However, both parallel branches must wait for step 1 to complete first.

Key Insight: Whenever you can break down a task into a deterministic DAG (Directed Acyclic Graph) structure with clearly defined step ordering and dependencies, we call that a WORKFLOW.

๐Ÿ’ก WORKFLOW = Deterministic task breakdown with explicit dependencies and execution order

Lets take a look at another example.

Example 2: Medical Diagnosis Agent

Task: Diagnose a patient's condition based on symptoms

INPUT: Initial symptoms, patient age, medical history
OUTPUT: Diagnosis with confidence level and treatment recommendations

Why This Requires an Agent (Not a Workflow)

Unlike the airport security example where we knew all the steps upfront, medical diagnosis cannot be predetermined because:

Two Patient Scenarios

Let's see how the same initial complaint leads to completely different diagnostic paths:

Scenario A: 28-year-old with fever and dry cough

Scenario B: 55-year-old with fatigue and unexplained weight loss

                                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                    โ”‚   START     โ”‚
                                    โ”‚  + symptoms โ”‚
                                    โ”‚  + age      โ”‚
                                    โ”‚  + history  โ”‚
                                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                           โ”‚
                                           โ–ผ
                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                              โ”‚  TOOL: symptom_analyzerโ”‚
                              โ”‚  Extract key symptoms  โ”‚
                              โ”‚  & severity scores     โ”‚
                              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                          โ”‚
                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                    โ”‚                                             โ”‚
        [Patient A: fever + cough]                   [Patient B: fatigue + weight loss]
                    โ”‚                                             โ”‚
                    โ–ผ                                             โ–ผ
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚ AGENT REASONING:      โ”‚                    โ”‚ AGENT REASONING:     โ”‚
        โ”‚ Acute respiratory +   โ”‚                    โ”‚ Chronic systemic +   โ”‚
        โ”‚ Recent pandemic       โ”‚                    โ”‚ Age 55+ = concern    โ”‚
        โ”‚ โ†’ Check infection     โ”‚                    โ”‚ โ†’ Check metabolic    โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                    โ”‚                                           โ”‚
                    โ–ผ                                           โ–ผ
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚ TOOL: vital_checker   โ”‚                    โ”‚ TOOL: vital_checker โ”‚
        โ”‚ Temp: 101.2ยฐF         โ”‚                    โ”‚ BP: normal          โ”‚
        โ”‚ SpO2: 96%             โ”‚                    โ”‚ HR: 52 bpm (LOW)    โ”‚
        โ”‚ Resp: 22/min          โ”‚                    โ”‚ Temp: 97.1ยฐF (LOW)  โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                    โ”‚                                           โ”‚
                    โ–ผ                                           โ–ผ
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚ AGENT REASONING:      โ”‚                    โ”‚ AGENT REASONING:    โ”‚
        โ”‚ Fever confirmed +     โ”‚                    โ”‚ Low HR + Low temp = โ”‚
        โ”‚ Good O2 = likely      โ”‚                    โ”‚ HYPOTHYROID pattern โ”‚
        โ”‚ upper respiratory     โ”‚                    โ”‚ Weight loss unusual โ”‚
        โ”‚ โ†’ Pandemic test first โ”‚                    โ”‚ โ†’ Thyroid labs      โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                    โ”‚                                           โ”‚
                    โ–ผ                                           โ–ผ
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚ TOOL: covid_test      โ”‚                    โ”‚ TOOL: lab_order     โ”‚
        โ”‚ Result: POSITIVE      โ”‚                    โ”‚ TSH, T3, T4         โ”‚
        โ”‚                       โ”‚                    โ”‚                     โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                    โ”‚                                           โ”‚
                    โ–ผ                                           โ–ผ
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚ AGENT REASONING:      โ”‚                    โ”‚ TOOL: lab_results   โ”‚
        โ”‚ Confirmed COVID-19    โ”‚                    โ”‚ TSH: 0.1 (very LOW) โ”‚
        โ”‚ No severe symptoms    โ”‚                    โ”‚ T4: HIGH            โ”‚
        โ”‚ โ†’ Check risk factors  โ”‚                    โ”‚ T3: HIGH            โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                    โ”‚                                           โ”‚
                    โ–ผ                                           โ–ผ
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚ TOOL: history_checker โ”‚                    โ”‚ AGENT REASONING:    โ”‚
        โ”‚ No chronic conditions โ”‚                    โ”‚ WAIT! High thyroid  โ”‚
        โ”‚ Vaccinated            โ”‚                    โ”‚ but WEIGHT LOSS?    โ”‚
        โ”‚                       โ”‚                    โ”‚ Should gain weight! โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                    โ”‚ โ†’ HYPERthyroid      โ”‚
                    โ”‚                                โ”‚ โ†’ Check antibodies  โ”‚
                    โ–ผ                                โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                              โ”‚
        โ”‚ DIAGNOSIS:            โ”‚                              โ–ผ
        โ”‚ COVID-19 (mild)       โ”‚                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚                       โ”‚                    โ”‚ TOOL: antibody_test โ”‚
        โ”‚ RECOMMENDATION:       โ”‚                    โ”‚ Anti-TSH receptor   โ”‚
        โ”‚ - Home isolation      โ”‚                    โ”‚ Result: POSITIVE    โ”‚
        โ”‚ - Symptomatic care    โ”‚                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ”‚ - Monitor O2          โ”‚                              โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                              โ–ผ
                                                     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                                     โ”‚ AGENT REASONING:    โ”‚
                                                     โ”‚ TSH-receptor Ab +   โ”‚
                                                     โ”‚ Confirms Graves'    โ”‚
                                                     โ”‚ โ†’ Check for         โ”‚
                                                     โ”‚ complications       โ”‚
                                                     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                                                โ”‚
                                                                โ–ผ
                                                     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                                     โ”‚ TOOL: symptom_scan  โ”‚
                                                     โ”‚ Check: tremors,     โ”‚
                                                     โ”‚ heat intolerance,   โ”‚
                                                     โ”‚ eye changes         โ”‚
                                                     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                                                โ”‚
                                                                โ–ผ
                                                     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                                                     โ”‚ DIAGNOSIS:          โ”‚
                                                     โ”‚ Graves' Disease     โ”‚
                                                     โ”‚ (Hyperthyroidism)   โ”‚
                                                     โ”‚                     โ”‚
                                                     โ”‚ RECOMMENDATION:     โ”‚
                                                     โ”‚ - Endocrinology ref โ”‚
                                                     โ”‚ - Anti-thyroid meds โ”‚
                                                     โ”‚ - Beta blockers     โ”‚
                                                     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Why An Agent Is Essential

Tool Execution Comparison

Patient A Path:

symptom_analyzer โ†’ vital_checker โ†’ covid_test โ†’ history_checker โ†’ DONE
(4 tools, linear path)

Patient B Path:

symptom_analyzer โ†’ vital_checker โ†’ lab_order โ†’ lab_results 
    โ†’ [PIVOT] โ†’ antibody_test โ†’ symptom_scan โ†’ DONE
(6 tools, with mid-course correction)

Key Decision Points (Why Predetermined DAG Fails)

  1. After symptom_analyzer:

    • Agent must choose between infectious disease tools vs. metabolic panels
    • Choice depends on: age, acuity, symptom pattern
  2. After vital_checker (Patient B):

    • Low HR + Low temp suggests hypothyroid
    • But agent keeps open mind (doesn't commit to diagnosis yet)
  3. After lab_results (Patient B) - CRITICAL PIVOT:

    • Results CONTRADICT initial hypothesis!
    • Hypothyroid would show HIGH TSH + LOW T4
    • Actually shows LOW TSH + HIGH T4 = Hyperthyroid
    • Weight loss now makes sense (hypermetabolic state)
    • Agent must backtrack reasoning and take new path
  4. Dynamic tool selection:

    • Patient A: Never needed thyroid tests, antibody tests, or symptom scans
    • Patient B: Never needed respiratory tests
    • Impossible to know upfront which tools to use

Non-Deterministic Edges

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ START โ”‚ โ”‚ โ”‚ โ”‚ - symptoms โ”‚ โ”‚ - age โ”‚ โ”‚ - history โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚ โ–ผ โ—‡โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—‡ โ”‚ vitals โ”‚ โ”‚ _check โ”‚ โ—‡โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—‡ โ”‚ * vitals โ–ผ โ—‡โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—‡ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚ covid โ”‚ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ โ”‚ CASE NOTES/ โ”‚ โ”‚ _test โ”‚ โ”‚ โ”‚ โ”‚ AGENT MEMORY โ”‚ โ—‡โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—‡ โ”‚ Diagnosis โ”‚- - - >โ”‚ TOOL SET โ”‚ โ–ฒ โ”‚ Agent โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚ - CRUD of memory โ”‚ โ”” โ”€ โ”€ โ”€ โ”€ โ”€ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ โ”‚ - Summarise history โ”‚ โ—‡โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—‡ โ”‚ โ”‚ - Get a specific โ”‚ โ”‚ lab โ”‚ โ”‚ โ”‚ detail. โ”‚ โ”‚ _order โ”‚ โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ—‡โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—‡ โ”‚ โ–ฒ โ”‚ โ”” โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€โ”ค โ—‡โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—‡ โ”‚ โ”‚ antibody โ”‚ โ”‚ โ”‚ _tst โ”‚ โ”‚ โ—‡โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—‡ โ”‚ โ–ฒ โ”‚ โ”” โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€ โ”€โ”ค โ”‚ โ—‡โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—‡ โ”‚ โ”‚ ask โ”‚ โ”‚ โ”‚ _patient โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ—‡โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—‡

The Impossibility of Workflow Approach

A workflow would need to:

1. Check ALL possible symptoms โŒ (expensive, time-consuming)
2. Run ALL possible tests โŒ (harmful to patient, costly)
3. Have branches for every disease combination โŒ (exponential complexity)

An agent instead:

1. โœ“ Reasons about probabilities
2. โœ“ Selects minimal necessary tests
3. โœ“ Adapts when findings contradict hypothesis
4. โœ“ Uses domain knowledge to guide exploration
5. โœ“ Terminates when confidence threshold reached

Key Insight: Medical diagnosis requires an intelligent agent that can dynamically plan its investigation strategy based on what it learns at each step. The DAG cannot be drawn before execution - it emerges through the agent's reasoning process.

๐Ÿ’ก AGENT = Non-deterministic task breakdown where the execution path is determined dynamically based on findings at each step

How do we build this with DSPy?

EXAMPLE 1: Airport Security Task

import dspy

# DISCLAIMER: as of nov 2025, this doesn't work because dspy doesn't support image input/output. But just for the sake of example, let's pretend it does.
class ExtractIdNumber(dspy.Signature):
    """Extract the ID number from the ID card"""
    id_card: Image = dspy.InputField()
    id_number: str = dspy.OutputField()

class SimilarityCheck(dspy.Signature):
    """Check if the live foto is similar to the photo from the ID database"""
    live_foto: Image = dspy.InputField()
    db_photo: Image = dspy.InputField()
    is_similar: bool = dspy.OutputField()

class AirportSecurityTask(dspy.Module):
    def __init__(self):
        super().__init__()
        self.extract_id_number = dspy.ChainOfThought(ExtractIdNumber)
        self.similarity_check = dspy.ChainOfThought(SimilarityCheck)

    def forward(self, live_foto: Image, id_card: Image, flight_boarding_pass: Image) -> bool:
        id_number = self.extract_id_number.run(id_card)
        # Run face match and name match in parallel
        import concurrent.futures
        
        with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
            # Submit face match task
            face_match_future = executor.submit(
                lambda: (
                    self.get_photo_from_id_db(id_number),
                    lambda db_photo: self.similarity_check(live_foto, db_photo)
                )
            )
            
            # Submit name match task
            name_match_future = executor.submit(
                lambda: (
                    self.get_name_from_id_db(id_number),
                    self.extract_flight_details(flight_boarding_pass)
                )
            )
            
            # Get face match result
            db_photo, similarity_fn = face_match_future.result()
            is_similar = similarity_fn(db_photo)
            
            # Get name match result
            name, flight_details = name_match_future.result()
            is_name_equal = name == flight_details['name']

        return is_similar and is_name_equal

    @staticmethod
    def get_photo_from_id_db(id_number: str) -> Image:
        pass

    @staticmethod
    def get_name_from_id_db(id_number: str) -> str:
        pass

    @staticmethod
    def extract_flight_details(flight_boarding_pass: Image) -> Dict[str, str]:
        pass

EXAMPLE 2: Medical Diagnosis Agent

import dspy
from typing import Dict, List, Optional, Any
from dataclasses import dataclass

# Define the tools available to the agent

@dataclass
class PatientData:
    symptoms: List[str]
    age: int
    medical_history: List[str]

class Diagnosis:
    diagnosis: str
    confidence: int

class MedicalDiagnosisAgentSign(dspy.Signature):
    """Analyze patient symptoms and extract key symptoms with severity scores"""
    symptoms: List[str] = dspy.InputField(desc="List of patient symptoms")
    age: int = dspy.InputField(desc="Patient age")
    medical_history: List[str] = dspy.InputField(desc="Patient medical history")
    diagnosis: List[Diagnosis] = dspy.OutputField(desc="List of possible diagnoses")

def check_vitals():
    """Check patient vital signs"""
    pass

def covid_test():
    """Check if the patient has COVID-19"""
    pass

def lab_order():
    """Order laboratory tests"""
    pass

def ask_patient_questions(questions: List[str]) -> List[str]:
    """Ask the patient questions to get more information"""
    pass


class MedicalDiagnosisAgent(dspy.Module):
    """A Medical Diagnosis Agent."""

    def __init__(self, memory: Memory):
        super().__init__()

        self.memory_tools = MemoryTools(memory)
        mem_tools = [
            store_memory,
            search_memories,
            get_all_memories,
            update_memory,
            delete_memory
        ] # lets assume that these are the memory tools that we want to use.
        self.tools = [check_vitals, covid_test, lab_order, ask_patient_questions, get_current_time, *mem_tools]

        self.react = dspy.ReAct(
            signature=MedicalDiagnosisAgentSign,
            tools=self.tools,
            max_iters=6
        )

    def forward(self, symptoms: List[str], age: int, medical_history: List[str]) -> List[Diagnosis]:
        """Diagnose the patient's condition."""
        return self.react(symptoms=symptoms, age=age, medical_history=medical_history)

Why I use DSPy for building automations with LLMs?

My task breakdown into sub-tasks is focused on the composable functions' input-output, that is what defines a sub-task for me. In this library, I can exactly define the sub-tasks perfectly as per my task breakdown. Thereby making it the most intuitive way to build automations with LLMs (for me, and in my opinion for everyone else too).