Health AI Platform Architecture
The Health AI Platform is easiest to understand as four interacting layers:
- Data - patient, lab, protocol, event, and research inputs
- Decisioning - workflow rules and tool selection
- Execution - APIs, tools, notifications, and ingestion pipelines
- Learning - embeddings, research retrieval, and ML service boundaries
Internally, we refer to this as 4D Chess because the platform does not make a single isolated decision. It moves across four dimensions at once:
- Clinical context
- Workflow state
- Tool availability
- Knowledge and model outputs
4D Chess mental model
Dimension 1: Clinical context
This is the patient-specific state pulled from the Patient Graph or supplied directly to the workflow runtime:
- Profile
- Labs
- Protocols
- Events
- Medications
- Check-ins
const context = {
patientId: 'patient-42',
data: {
biomarker: { TSH: 4.2 },
medications: ['metformin'],
genetics: { MTHFR: 'C677T/C677T' },
},
};Dimension 2: Workflow state
A workflow does not just read patient data. It also evaluates previous step results.
That lets later steps react to earlier decisions without introducing imperative branching code.
steps:
- id: check-tsh
type: check_biomarker
action:
type: check_value
params:
biomarker: TSH
threshold: 2.5
operator: ">"
- id: recommend-selenium
type: recommend_supplement
condition: "check-tsh.result === true"
action:
type: recommend
params:
supplement: Selenium
dosage: 200mcgDimension 3: Tool availability
The runtime may have access to a tool set, but not every workflow can call every tool.
The current run_tool step checks whether a tool ID is available in context.tools before it proceeds.
const result = await workflow.execute({
patientId: 'patient-42',
tools: ['product-search', 'save-note'],
});Dimension 4: Knowledge and ML
The platform can attach knowledge and analytics around the workflow:
- Research papers are chunked and embedded
- Semantic retrieval can enrich downstream prompts or analysis
- The Python ML service provides a service boundary for heavier numerical work
import { MLClient } from '@loop/ml-client';
const ml = new MLClient({ baseUrl: 'http://localhost:8000' });
const health = await ml.healthCheck();System view
Input Sources
|
+-- Patient Graph API
+-- Research PDFs / Payload CMS
+-- Direct app context
+-- External integrations
|
v
Workflow Definition + Runtime Context
|
+-- Conditions
+-- Step dispatch
+-- Step results
+-- Available tools
|
v
Actions
|
+-- Recommendations
+-- Lab orders
+-- Notifications
+-- Tool execution boundary
+-- Research ingestion
|
v
Knowledge + ML Layer
|
+-- Embeddings
+-- Semantic search
+-- ML health endpoint / future analyticsRepository mapping
| Layer | Primary code |
|---|---|
| Workflow orchestration | packages/workflow-engine |
| Clinical data | apps/patient-graph, packages/patient-graph, packages/patient-graph-client |
| Agent tools | apps/luna/src/lib/tools |
| Research ingestion | packages/ai/src/ingestion/research-paper-pipeline.ts |
| ML service boundary | apps/ml-service, packages/ml-client |
Request flow example
This example shows how the pieces fit together when a patient’s lab result should trigger a recommendation:
import { WorkflowEngine } from '@loop/workflow-engine';
import { PatientGraphClientImpl } from '@loop/patient-graph-client';
const patientGraph = new PatientGraphClientImpl({
baseUrl: process.env.PATIENT_GRAPH_API_URL!,
getAuthToken: async () => process.env.PATIENT_GRAPH_API_KEY!,
});
const workflow = WorkflowEngine.load({
id: 'thyroid-assessment-v1',
name: 'Thyroid Assessment',
version: '1.0.0',
steps: [
{
id: 'check-tsh',
type: 'check_biomarker',
action: {
type: 'check_value',
params: { biomarker: 'TSH', threshold: 2.5, operator: '>' },
},
},
{
id: 'recommend-selenium',
type: 'recommend_supplement',
condition: 'check-tsh.result === true',
action: {
type: 'recommend',
params: { supplement: 'Selenium', dosage: '200mcg' },
},
},
],
});
const profile = await patientGraph.getPatientContext('user_123');
if (profile.ok) {
const result = await workflow.execute({
patientId: 'user_123',
data: {
biomarker: { TSH: 4.2 },
medications: ['metformin'],
},
});
console.log(result.executedSteps);
console.log(result.recommendations);
}Boundaries that matter
Workflow engine is deterministic
The workflow engine does not depend on an LLM to evaluate conditions or dispatch built-in step types.
That makes it the right place for:
- Threshold checks
- Repeatable branching
- Safe recommendation scaffolding
- Testable orchestration
Tool execution is currently a boundary, not a full shared registry
The workflow engine has a run_tool step type, but the current implementation is a stub intended for a future shared tool registry.
Luna has a real tool registry today, but that registry is specific to the Luna app.
// Current behavior of run_tool is effectively:
{ executed: true, toolId, params }Research ingestion exists, but wiring is partial
The @loop/ai ingestion pipeline can:
- extract PDF text
- chunk by section
- generate embeddings
- return structured chunk output
However, the admin hook currently uses a placeholder wrapper that returns an error until the full export is restored.
ML is intentionally narrow in this snapshot
The Python ML service is a real service boundary, but the current checked-in API surface is the health route.
That means architecture docs should describe ML as an integration seam, not as a broad production endpoint catalog yet.
Designing with 4D Chess
When you add a new health AI capability, evaluate it across all four dimensions:
| Question | Why it matters |
|---|---|
| What patient context does it need? | Avoid hidden data dependencies |
| What workflow state should it inspect? | Keep branching deterministic |
| Which tools may it call? | Control runtime scope safely |
| What knowledge or ML output does it depend on? | Separate retrieval, scoring, and orchestration concerns |
Next steps
- Continue with Workflows
- Review Patient Graph integration
- Study the Workflow Engine
- See the DSL reference