Natalie is an AI agent, powered by Google Gemini, that takes two drug names and produces a structured comparison of their molecular properties and safety signals, plus an AI-written summary of the patterns linking the two.
For every comparison the agent autonomously calls two database tools for each drug (2 tools Γ 2 drugs = 4 tool calls) via Gemini function calling, then assembles the returned data into a side-by-side table.
natalie_examples.md.| Tool | Source | Returns |
|---|---|---|
natalie_get_molecular_properties(drug) |
PubChem PUG REST | Formula, molecular weight, LogP, H-bond donors/acceptors, TPSA, rotatable bonds |
natalie_get_safety_signals(drug) |
openFDA | Top adverse reactions (with counts), boxed-warning flag, total reports, warnings excerpt |
Both sources are free and require no API key. Only Gemini needs a key.
1. Landing page β enter two drugs; the agentβs key/model/data-sources are shown in the sidebar.

2. Autonomous tool calls + comparison table β Natalie reports the 4 database tool calls it made, then the assembled side-by-side table.

3. AI summary β a 3β5 sentence summary connecting molecular properties to safety signals.

Get a free key at https://aistudio.google.com/apikey, then put it in .env:
GEMINI_API_KEY=your_key_here
(A template is in .env.example. The default model is gemini-flash-latest,
a stable alias that always maps to a current Gemini Flash model.)
./natalie_run.sh
This creates a virtual environment, installs dependencies, runs the two
documented example comparisons (writing natalie_examples.md), and launches the
web app at http://localhost:8501.
./natalie_run.sh setup # create venv + install deps only
./natalie_run.sh app # launch the Streamlit web app
./natalie_run.sh examples # regenerate natalie_examples.md
./natalie_run.sh compare aspirin ibuprofen # one-off CLI comparison
βββββββββββββββββββββββββββββββββββββββββββββββ
two drugs βββΆ β NatalieAgent.compare(drug_a, drug_b) β
β β
β 1. Gemini function-calling loop β
β Gemini autonomously decides to call: β
β natalie_get_molecular_properties(A) ββββΆ PubChem
β natalie_get_safety_signals(A) ββββΆ openFDA
β natalie_get_molecular_properties(B) ββββΆ PubChem
β natalie_get_safety_signals(B) ββββΆ openFDA
β β
β 2. Capture the real tool results and build β
β the structured side-by-side table β
β (numbers come straight from the tools β β
β never hallucinated) β
β β
β 3. Gemini writes the 3β5 sentence summary β
β from the verified table β
βββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
table + summary + tool-call log
Design note: Gemini genuinely performs the tool calls (autonomous function calling), but the table cells are filled from the captured tool outputs, not from model free-text β so every value in the table is real data. Gemini is then asked to summarize only that verified table.
| File | Purpose |
|---|---|
natalie_tools.py |
The two database tools (PubChem + openFDA) |
natalie_agent.py |
The Gemini agent: function-calling loop, table builder, summary |
natalie_app.py |
Streamlit web UI |
natalie_examples.py |
Generates the documented example runs |
natalie_screenshot.py |
Captures the README screenshots (Playwright) |
natalie_run.sh |
One-command runner |
natalie_examples.md |
Output: documented example runs |
.env / .env.example |
Gemini API key configuration |
requirements.txt |
Python dependencies |
See natalie_examples.md for full documented runs
(aspirin vs ibuprofen, acetaminophen vs naproxen), each showing the 4 autonomous
tool calls, the comparison table, and the AI summary. Try your own with:
./natalie_run.sh compare warfarin heparin
Natalie is an educational / research tool. openFDA adverse-event counts reflect reporting volume, not causation or incidence, and are heavily influenced by how widely a drug is used. Nothing here is medical advice.