Bell Eapen MD, PhD.

Bringing Digital health & Gen AI research to life!

Why DHTI Chains Matter: Moving Beyond Single LLM Calls in Healthcare AI (Part II)

Large Language Models (LLMs) are powerful, but a single LLM call is rarely enough for real healthcare applications. Out of the box, LLMs lack memory, cannot use tools, and cannot reliably perform multi‑step reasoning—limitations highlighted in multiple analyses of LLM‑powered systems. In clinical settings, where accuracy, context, and structured outputs matter, relying on a single prompt‑response cycle is simply not viable.

Healthcare workflows require the retrieval of patient data, contextual reasoning, validation, and often the structured transformation of model output. A single LLM call cannot orchestrate these steps. This is where chains become essential.

Chains

Image credit: FASING Group, CC BY-SA 4.0 https://creativecommons.org/licenses/by-sa/4.0, via Wikimedia Commons

What Are Chains, and Why Do They Matter?

A chain is a structured workflow that connects multiple steps—LLM calls, data transformations, retrieval functions, or even other chains—into a coherent pipeline. LangChain describes chains as “assembly lines for LLM workflows,” enabling multi‑step reasoning and data processing that single calls cannot achieve.

Chains allow developers to:

  • Break complex tasks into smaller, reliable steps
  • Enforce structure and validation
  • Integrate external tools (e.g., FHIR APIs, EMR systems)
  • Maintain deterministic flow in safety‑critical environments

In healthcare, this is crucial. For example, generating a patient‑specific summary may require:

  1. retrieving data from an EMR,
  2. cleaning and structuring it,
  3. generating a clinical narrative, and
  4. validating the output.

A chain handles this entire pipeline.


Sequential, Parallel, and Branch Flows

Modern LLM applications often require more than linear processing. LangChain supports three major flow types:

✅ Sequential Chains

Sequential chains run steps in order, where the output of one step becomes the input to the next. They are ideal for multi‑stage reasoning or data transformation pipelines.

✅ Parallel Chains

Parallel chains run multiple tasks at the same time—useful when extracting multiple data elements or generating multiple outputs concurrently. LangChain’s RunnableParallel enables this pattern efficiently.

✅ Branching Chains

Branch flows allow conditional logic—different paths depending on model output or data state. This is essential for clinical decision support, where logic often depends on patient‑specific conditions.

Together, these patterns allow developers to build robust, production‑grade AI systems that go far beyond simple prompt engineering.


Implementing Chains in LangChain and Hosting Them on LangServe

LangChain provides a clean, modular API for building chains, including prompt templates, LLM wrappers, and runnable components. LangServe extends this by exposing chains as FastAPI‑powered endpoints, making deployment straightforward.

This combination—LangChain + LangServe—gives developers a scalable, observable, and maintainable way to deploy multi‑step GenAI workflows.


DHTI: A Real‑World Example of Chain‑Driven Healthcare AI

DHTI embraces these patterns to build GenAI applications that integrate seamlessly with EMRs. DHTI uses:

  • Chains for multi‑step reasoning
  • LangServe for hosting GenAI services
  • FHIR for standards‑based data retrieval
  • CDS‑Hooks for embedding AI output directly into EMR workflows

This standards‑based approach ensures interoperability and makes it easy to plug GenAI into clinical environments without proprietary lock‑in. DHTI makes sharing chains remarkably simple by packaging each chain as a modular, standards‑based service that can be deployed, reused, or swapped without touching the rest of the system. Because every chain is exposed through LangServe endpoints and integrated using FHIR and CDS‑Hooks conventions, teams can share, version, and plug these chains into different EMRs or projects with minimal friction.

Explore the project here:

DHTI: a reference architecture for Gen AI in healthcare and a skill platform for vibe coding!
https://github.com/dermatologist/dhti
0 forks.
13 stars.
8 open issues.

Recent commits:


Try DHTI and Help Democratize GenAI in Healthcare

DHTI is open‑source, modular, and built on widely adopted standards. Whether you’re a researcher, developer, or clinician, you can use it to prototype safe, interoperable GenAI workflows that work inside real EMRs.

More examples for chains


✅ 1. Clinical Note → Problem List → ICD-10 Coding

Why chaining helps

A single LLM call struggles because:

  • The task is multi‑step: extract problems → normalize → map to ICD‑10.
  • Each step benefits from structured intermediate outputs.
  • Errors compound if the model tries to do everything at once.

Sequential Runnable Example

Step 1: Extract the structured problem list from the free‑text note
Step 2: Normalize problems to standard clinical terminology
Step 3: Map each normalized problem to ICD‑10 codes

This mirrors real clinical coding workflows and allows validation at each step.

Sequential chain sketch

  1. extract_problems(note_text)
  2. normalize_terms(problem_list)
  3. map_to_icd10(normalized_terms)

✅ 2. Clinical Decision Support: Medication Recommendation With Safety Checks

Why chaining helps

A single LLM call might hallucinate or skip safety checks. A chain allows:

  • Independent verification steps
  • Parallel evaluation of risks
  • Branching logic based on findings

Parallel Runnable Example

Given a patient with multiple comorbidities:

Parallel tasks:

  • Evaluate renal dosing requirements
  • Check drug–drug interactions
  • Assess contraindications
  • Summarize guideline‑based first‑line therapies

All run simultaneously, then merged.

Parallel chain sketch

{

  renal_check: check_renal_function(patient),

  ddi_check: check_drug_interactions(patient),

  contraindications: check_contraindications(patient),

  guideline: summarize_guidelines(condition)

}

→ combine_and_recommend()

This mirrors how pharmacists and CDS systems work: multiple independent checks feeding into a final recommendation.


✅ 3. Triage Assistant: Symptom Intake → Risk Stratification → Disposition

Why chaining helps

Triage requires conditional logic:

  • If red‑flag symptoms → urgent care
  • If moderate risk → telehealth
  • If low risk → self‑care

A single LLM call tends to blur risk categories. A branching chain enforces structure.

Branch Runnable Example

Step 1: Extract structured symptoms
Step 2: Risk stratification
Branch:

  • High risk → generate urgent-care instructions
  • Medium risk → generate telehealth plan
  • Low risk → generate self‑care guidance

Branch chain sketch

symptoms = extract_symptoms(input)

risk = stratify_risk(symptoms)

if risk == “high”:

    return urgent_care_instructions(symptoms)

elif risk == “medium”:

    return telehealth_plan(symptoms)

else:

    return self_care_plan(symptoms)

This mirrors real triage protocols (e.g., Schmitt/Thompson).


✅ Summary Table

ScenarioWhy a Chain HelpsBest Runnable Pattern
Clinical note → ICD‑10 codingMulti-step reasoning, structured outputsSequential
Medication recommendation with safety checksIndependent safety checks, guideline lookupParallel
Triage assistantConditional logic, different outputs based on riskBranch

IV. DocumentReference hook in CQL execution

The GitHub repository below is a fork of the CQL Execution Framework, which provides a TypeScript/JavaScript library for executing Clinical Quality Language (CQL) artifacts expressed as JSON ELM. The fork introduces an experimental feature supporting LLM-based assertion checking on DocumentReference. The framework enables execution of CQL logic within different data models, such as QDM and FHIR, but does not provide direct support for data models or terminology services. The library implements various features from CQL 1.4 and 1.5 but has some limitations, such as incomplete support for specific datatypes and functions.

Kedro for multimodal machine learning in healthcare 

Healthcare data is heterogenous with several types of data like reports, tabular data, and images. Combining multiple modalities of data into a single model can be challenging due to several reasons. One challenge is that the diverse types of data may have different structures, formats, and scales which can make it difficult to integrate them into a single model. Additionally, some modalities of data may be missing or incomplete, which can make it difficult to train a model effectively. Another challenge is that different modalities of data may require different types of pre-processing and feature extraction techniques, which can further complicate the integration process. Furthermore, the lack of large-scale, annotated datasets that have multiple modalities of data can also be a challenge. Despite these challenges, advances in deep learning, multi-task learning and transfer learning are making it possible to develop models that can effectively combine multiple modalities of data and achieve reliable performance. 

Pipelines Kedro for multimodal machine learning

Kedro for multimodal machine learning

Kedro is an open-source Python framework that helps data scientists and engineers organize their code, increase productivity and collaboration, and make it easier to deploy their models to production. It is built on top of popular libraries such as Pandas, TensorFlow and PySpark, and follows best practices from software engineering, such as modularity and code reusability. Kedro supplies a standardized structure for organizing code, handling data and configuration, and running experiments. It also includes built-in support for version control, logging, and testing, making it easy to implement reproducible and maintainable pipelines. Additionally, Kedro allows to easily deploy the pipeline on cloud platforms like AWS, GCP or Azure. This makes it a powerful tool for creating robust and scalable data science and data engineering pipelines. 

I have built a few kedro packages that can make multi-modal machine learning easy in healthcare. The packages supply prebuilt pipelines for preprocessing images, tabular and text data and build fusion models that can be trained on multi-modal data for easy deployment. The text preprocessing package currently supports BERT and CNN-text models. There is also a template that you can copy to build your own pipelines making use of the preprocessing pipelines that I have built. Any number and combination of data types are supported. Additionally, like any other kedro pipeline, these can be deployed on kubeflow and VertexAI. Do comment below if you find these tools useful in your research. 

Dark Mode

kedro-multimodal (this link opens in a new window) by dermatologist (this link opens in a new window)

Template for multi-modal machine learning in healthcare using Kedro. Combine reports, tabular data and image using various fusion methods.

Using OpenFaaS containers in Kubeflow 

OpenFaas

OpenFaaS is an open-source framework for building serverless functions with containers. Serverless functions are pieces of code that are executed in response to a specific event, such as an HTTP request or a message being added to a queue. These functions are typically short-lived and only run when needed, which makes them a cost-effective and scalable way to build cloud-native applications. OpenFaaS makes it easy to build, deploy, and manage serverless functions. OpenFaaS CLI minimizes the need to write boilerplate code. You can write code in any supported language and deploy it to any cloud provider. It provides a set of base containers that encapsulates the ‘function’ with a webserver that exposes its HTTP service on port 8080 (incidentally the default port for Google Cloud Run). OpenFaaS containers can be directly deployed on Google Cloud Run and with the faas CLI on any cloud provider. 

OpenFaaS ® – Serverless Functions Made Simple

Kubeflow

Kubeflow is a toolkit for building and deploying machine learning models on Kubernetes. Kubeflow is designed to make it easy to build, deploy, and manage end-to-end machine learning pipelines, from data preparation and model training to serving predictions and implementing custom logic. It can be used with any machine learning framework or library. Google’s Vertex AI platform can run Kubeflow pipelines. Kubeflow pipeline components are self-contained code that can perform a step in the machine learning workflow. They are packaged as a docker container and pushed to a container registry that the Kubernetes cluster can access. A Kubeflow component is a containerized command line application that takes input and output as command line arguments.  

OpenFaaS containers expose HTTP services, while Kubeflow containers provide CLI services. That introduces the possibility of tweaking OpenFaaS containers to support CLI invocation, making the same containers usable as Kubeflow components. Below I explain how a minor tweak in the OpenFaaS templates can enable this. 

Let me take the OpenFaaS golang template as an example. The same principle applies to other language templates as well. In the golang-middleware’s main.go, the following lines set the main route and start the server. This exposes the function as a service when the container is deployed on Cloud Run.

 
	http.HandleFunc("/", function.Handle),  

	listenUntilShutdown(s, healthInterval, writeTimeout) 

I have added the following lines [see on GitHub] that expose the same function on the command line for Kubeflow.  

	if len(os.Args) < 2 {,  

		listenUntilShutdown(s, healthInterval, writeTimeout) 

	} else { 

		dat, _ := os.ReadFile(os.Args[1]) 

		_dat := function.HandleFile(dat) 

		_ = os.WriteFile(os.Args[2], _dat, 0777) 

	} 

If the input and output file names are supplied on the command line as in kubeflow, it reads from and writes to those files. The kubeflow component definition is as below: 

implementation:
  container:
    image: <image:version>
    command: [
        'sh',
        '-c',
        'mkdir --parents $(dirname "$1") && /home/app/handler "$0" "$1"',
    ]
    args: [{inputPath: Input 1}, {outputPath: Output 1}]

With this simple tweak, we can use the same container to host the function on any cloud provider as serverless functions and Kubeflow components.  You can pull the modified template from the repo below.

Open-source for healthcare

This post is meant to be an instruction guide for healthcare professionals who would like to join my projects on GitHub.

eHealth Programmer Girl

What is a contribution?

Contribution is not always coding. You can clean up stuff, add documentation, instructions for others to follow etc. Issues and feature requests should be posted under the ‘issues’ tab and general discussions under the ‘Discussions’ tab if one is available.

How do I contribute.

How do I develop

  • The .devcontainer folder will have the configuration for the docker container for development.
  • Version bump action (if present) will automatically bump version based on the following terms in a commit message: major/minor/patch. Avoid these words in the commit message unless you want to trigger the action.
  • Most repositories have GH actions to generate and deploy documentation and changelog.

What do I do next

  • My repositories (so far) are small enough for beginners to get the big picture and make meaningful contributions.
  • Don’t be discouraged if you make mistakes. That is how we all learn.

There’s no better time than now to choose a repo to contribute!

Clinical knowledge representation for reuse

The need for computerized clinical decision support is becoming increasingly obvious with the COVID-19 pandemic. The initial emphasis has been on ‘replacing’ the clinician which for a variety of reasons is impossible or impractical. Pragmatically, clinical decision support systems could provide clinical knowledge support for clinicians to make time-sensitive decisions with whatever information they have at the point of patient care.

Siobhán Grayson, CC BY-SA 4.0 https://creativecommons.org/licenses/by-sa/4.0, via Wikimedia Commons

Providing clinical decision support requires some formal way of representing clinical knowledge and complex algorithms for sophisticated inference. In knowledge management terms, the information requires to be transformed into actionable knowledge. Knowledge needs to be represented and stored in a way conducive to easy inference (knowledge reuse)​1​. I have been exploring this domain for a considerable period of time, from ontologies to RDF datasets. With the advent of popular graph databases (especially Neo4J ), this seems to be a good knowledge representation method for clinical purposes.

To cut a long story short, I have been working on building a suite of JAVA libraries to support knowledge extraction, annotation and transformation to a graph schema for inference. I have not open-source it yet as I have not decided on what license to use. However, I am posting some preliminary information here to assess interest. Please give me a shout, if you share an interest or see some potential applications for this. As always, I am open to collaboration.

The JAVA package consists of three modules. The ‘library’ module wraps the NCBI’s E-Utils API to harvest published article abstracts if that is your knowledge source. Though data extraction from the clinical notes in EMR’s is a recent trend, it is challenging because of unstructured data and lack of interoperability. The ‘qtakes’ module provides a programmable interface to my quick-ctakes or the quarkus based apache ctakes, a fast clinical text annotation engine. Finally, the graph module provides the Neo4J models, repositories and services for abstracting as a knowledge graph.

The clinical knowledge graph (ckb) consists of entities such as Disease, Treatment and Anatomy and appropriate relationships and cypher queries are defined. The module exposes services that can be consumed by JAVA applications. It will be available as a maven artifact once I complete it.

UPDATE: May 30, 2021: The library (ckblib) is now available under MPL 2.0 license (see below). Feel free to use it in your research.

Tools to create a clinical knowledge graph from biomedical literature. Includes wrappers for NCBI Eutils, cTakes annotator and Neo4J
https://github.com/dermatologist/ckblib
4 forks.
16 stars.
9 open issues.

Recent commits:

  1. 1.
    Toward a Theory of Knowledge Reuse: Types of Knowledge Reuse Situations and Factors in Reuse Success. Journal of Management Information Systems. Published online May 31, 2001:57-93. doi:10.1080/07421222.2001.11045671
Cite this article as: Eapen BR. (April 28, 2021). Clinical knowledge representation for reuse. Retrieved January 31, 2026, from https://nuchange.ca/2021/04/clinical-knowledge-representation-for-reuse.html.

COVID vaccination tracking with blockchain

COVID vaccine rollout has the potential to bring relief to billions of people around the world. But as encouraging as these programs may be, it is extremely important to note that a vaccine cannot be as effective if it is not effectively distributed and trusted by the public.

SPQR10, CC BY-SA 4.0 https://creativecommons.org/licenses/by-sa/4.0, via Wikimedia Commons

IBM Blockchain has a vaccine distribution network for manufacturers to proactively monitor for adverse events and improve recall management. Moderna is planning to explore vaccine traceability with the IBM blockchain.

The International Air Transport Association (IATA) is planning to launch a system of digital ‘passports’ as proof that passengers have been vaccinated against COVID-19. Blockchain technology could offer a better data-storage system for such vaccination records. A decentralized blockchain ledger would be anonymous, immutable and transparent and the entries can be publicly audited.

A vaccine blockchain system could support vaccine traceability and smart contract functions and can be used to address the problems of vaccine expiration and vaccine record fraud. Additionally, the use of machine learning models can provide valuable recommendations to immunization practitioners and recipients, allowing them to choose better immunization methods and vaccines as recommended by this study. A blockchain-based system developed by Singapore-based Zuellig Pharma can help governments and healthcare providers manage vaccine distribution and administration. UK hospitals are using blockchain to track the temperature of coronavirus vaccines.

In my opinion, a blockchain application in healthcare should satisfy the following characteristics:

  1. Both patient and provider should have an interest in the decentralized storage of the concerned piece of information. One party may be neutral, but there should not be a collision of interests.
  2. One or more third parties should have an interest in this information and may have a reason not to trust the patient or provider.
  3. The information should be a dynamic time-bound list that requires periodic updating.
  4. The privacy concern related to the concerned information should be minimal.
  5. The information should not be easy to measure or procure from other sources.

Vaccination satisfies the above criteria and as such blockchain may be a good solution for this problem. Before the COVID-19 pandemic, I had played a bit with solidity and made a web application with three different views:

  1. Provider view: From this view, a provider can extend an offer to save the information on the blockchain to a patient.
  2. Patient view: From this view, a patient can accept an offer extended by a provider.
  3. Lookup view: To look up information on any patient.

Vac-chain is a prototype of on-chain storage of vaccination information on Ethereum blockchain using smart contracts in solidity using the truffle Drizzle box (React/Redux).

Cite this article as: Eapen BR. (March 24, 2021). COVID vaccination tracking with blockchain. Retrieved January 31, 2026, from https://nuchange.ca/2021/03/covid-vaccination-tracking-with-blockchain.html.