Skip to main content

BODHI: Epistemic virtues (curiosity and humility) for LLM responses

Project description

BODHI: Bridging, Open, Discerning, Humble, Inquiring

PLOS Digital Health The Lancet License: CC BY-NC-SA 4.0 Python 3.10+

A lightweight, provider-agnostic wrapper that embeds epistemic virtues (curiosity and humility) into LLM responses through a two-pass prompting strategy.

Results

BODHI achieved +24.2% improvement on HealthBench Hard and consistent gains across all benchmarks:

Benchmark Baseline BODHI Improvement
Consensus 85.0% 88.3% +3.3%
Hard 0.0% 24.2% +24.2%
General 29.9% 43.1% +13.3%

Installation

From PyPI

pip install bodhi-llm

# With OpenAI support
pip install bodhi-llm[openai]

# All providers
pip install bodhi-llm[all]

From Source (for development)

# Clone the repository
git clone https://github.com/sebasmos/bodhi.git
cd bodhi

# Create a virtual environment (recommended)
python3 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Upgrade pip (required for editable install with pyproject.toml)
pip install --upgrade pip

# Install with all dependencies
pip install -e ".[all]"

# Or install with dev dependencies for testing
pip install -e ".[dev]"

Quick Start

With OpenAI

from bodhi import BODHI
from bodhi.providers import OpenAIChat

# Create chat function
chat = OpenAIChat(api_key="sk-...", model="gpt-4o-mini")

# Wrap with BODHI
bodhi = BODHI(chat)

# Generate response
response = bodhi.complete("I have chest pain")
print(response.content)    # Final response
print(response.analysis)   # Pass 1 analysis

With Any Provider (Custom Function)

BODHI works with any function that takes messages and returns a string:

from bodhi import BODHI

def my_chat(messages):
    """Your custom LLM call - just return a string."""
    # Call your API, local model, whatever
    return "response text"

bodhi = BODHI(my_chat)
response = bodhi.complete("I have chest pain")

Direct from OpenAI Client

from bodhi import BODHI
from openai import OpenAI

client = OpenAI()
bodhi = BODHI.from_openai(client, model="gpt-4o-mini")

response = bodhi.complete("I have chest pain")

How It Works

BODHI uses a two-pass prompting strategy:

Pass 1: Analysis
  Input: User prompt
  Output: Structured reflection containing:
    - WHAT I THINK (assessment)
    - WHAT I'M UNSURE ABOUT (uncertainties)
    - WHAT I NEED TO KNOW (questions)
    - RED FLAGS (safety concerns)
    - SAFE ADVICE (confident recommendations)

Pass 2: Response
  Input: Original prompt + Pass 1 analysis
  Output: Natural response that:
    - ASKS identified questions
    - EXPRESSES identified uncertainties
    - INCLUDES safety warnings
    - PROVIDES safe recommendations

Why It Works

Aspect Baseline BODHI
Uncertainty Often overconfident Appropriately humble
Missing info Makes assumptions Asks clarifying questions
Safety May miss red flags Explicitly considers red flags
Recommendations Generic advice Contextually appropriate advice

Configuration

Custom Prompts

from bodhi import BODHI, BODHIConfig

config = BODHIConfig(
    analysis_template="Analyze this: {input}",
    response_template="Respond to: {input}\nUsing analysis: {analysis}",
    domain="general"  # or "medical" (default)
)

bodhi = BODHI(chat, config=config)

Single-Pass Mode

# For comparison or speed
response = bodhi.complete("prompt", two_pass=False)

Analysis Only

# Debug or inspect the analysis
analysis = bodhi.analyze("I have chest pain")
print(analysis)

API Reference

BODHI

Main class for BODHI functionality.

BODHI(
    chat_function: ChatFunction,  # Any callable: messages -> str
    config: Optional[BODHIConfig] = None
)

Methods:

  • complete(prompt, two_pass=True) - Generate response with BODHI enhancement
  • analyze(prompt) - Run only Pass 1 (analysis)
  • from_openai(client, model) - Create from OpenAI client (class method)

BODHIResponse

Response object returned by complete().

@dataclass
class BODHIResponse:
    content: str      # Final response text
    analysis: str     # Pass 1 analysis
    metadata: dict    # Timing, domain, etc.

BODHIConfig

Configuration for BODHI behavior.

@dataclass
class BODHIConfig:
    analysis_template: Optional[str] = None  # Custom Pass 1 prompt
    response_template: Optional[str] = None  # Custom Pass 2 prompt
    domain: str = "medical"                  # "medical" or "general"

Provider Adapters

OpenAI

from bodhi.providers import OpenAIChat

chat = OpenAIChat(
    api_key="sk-...",           # Or use OPENAI_API_KEY env var
    model="gpt-4o-mini",
    temperature=0.7,
    max_tokens=None
)

Custom Provider

Implement the ChatFunction protocol:

from typing import List, Dict

def my_chat(messages: List[Dict[str, str]]) -> str:
    # Your implementation
    return "response"

# Or as a class
class MyChat:
    def __call__(self, messages: List[Dict[str, str]]) -> str:
        return "response"

Citation

If you use BODHI in your research, please cite:

@article{cajas2026beyond,
  title={Beyond overconfidence: Embedding curiosity and humility for ethical medical AI},
  author={Cajas Ordóñez, Sebastián Andrés and Castro, Rowell and Celi, Leo Anthony and Delos Reyes, Roben and Engelmann, Justin and Ercole, Ari and Hilel, Almog and Kalla, Mahima and Kinyera, Leo and Lange, Maximin and others},
  journal={PLOS Digital Health},
  volume={5},
  number={1},
  pages={e0001013},
  year={2026},
  publisher={Public Library of Science San Francisco, CA USA}
}

@article{ordonez2025humility,
  title={Humility and curiosity in human--AI systems for health care},
  author={Ordoñez, Sebastián Andrés Cajas and Lange, Maximin and Lunde, Torleif Markussen and Meni, Mackenzie J and Premo, Anna E},
  journal={The Lancet},
  volume={406},
  number={10505},
  pages={804--805},
  year={2025},
  publisher={Elsevier}
}

License

CC BY-NC-SA 4.0 - See LICENSE for details.

Contributing

Contributions welcome! Please read the contributing guidelines and submit PRs.

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bodhi_llm-0.1.0.tar.gz (12.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bodhi_llm-0.1.0-py3-none-any.whl (12.7 kB view details)

Uploaded Python 3

File details

Details for the file bodhi_llm-0.1.0.tar.gz.

File metadata

  • Download URL: bodhi_llm-0.1.0.tar.gz
  • Upload date:
  • Size: 12.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for bodhi_llm-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a3492915062b07e16278e174fcf34c41d814b5e22e9e1278ca387d5a73b4c0d8
MD5 679abeafcc7511b7ec1cf2d78671a044
BLAKE2b-256 ba4b87da003766135e4200018fa9c9a461478e243588852949cfff18cdafc62f

See more details on using hashes here.

File details

Details for the file bodhi_llm-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: bodhi_llm-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for bodhi_llm-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 2ebd0cecc4f65300c1a13d128fe84c3cfad51e51ebd940685f55a0f69748bc16
MD5 a8f2b680205860ccf4478c6469b344be
BLAKE2b-256 16f9275500eb76181ed2010b486b3334bc71d2185a4829876eca095083491ce2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page