Skip to main content

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

Project description

BODHI: Bridging, Open, Discerning, Humble, Inquiring

PyPI 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.

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-llms.git
cd bodhi-llms

# 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

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.3.tar.gz (17.4 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.3-py3-none-any.whl (15.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: bodhi_llm-0.1.3.tar.gz
  • Upload date:
  • Size: 17.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for bodhi_llm-0.1.3.tar.gz
Algorithm Hash digest
SHA256 a7fc0b3500a2c935aff675cac01fd92773e2e1cfd0b9b98b52c31ef91a4fcc61
MD5 4889983ce9c009c249a7e88109710490
BLAKE2b-256 1681c26d1a94676e83c33a5093208ebcc141fd9b36169b81a4cd84ba628e0f7f

See more details on using hashes here.

Provenance

The following attestation bundles were made for bodhi_llm-0.1.3.tar.gz:

Publisher: publish.yml on sebasmos/bodhi-llms

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

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

File metadata

  • Download URL: bodhi_llm-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 15.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for bodhi_llm-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 cdc13108fbe19e57ed3d7e63b4bf47a0c9511c8e6046bd8f5c96613e84c24a6b
MD5 107d726c3536ad67d4ebc6c8eee784fa
BLAKE2b-256 71ece7311a76100d498be3ac4f22957191de234bb189c2b15c0f96b036f82573

See more details on using hashes here.

Provenance

The following attestation bundles were made for bodhi_llm-0.1.3-py3-none-any.whl:

Publisher: publish.yml on sebasmos/bodhi-llms

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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