Nerif: A Python-Native Way to Make Large Language Models Behave Like Ordinary Functions
Large language models (LLMs) can feel like a gifted but unpredictable intern: brilliant one moment, rambling the next.
Existing tools such as LangChain or Dify help, yet they often add layers of abstraction that hide what the model is actually doing.
Nerif takes a different path—one that keeps LLMs firmly inside your Python code while still giving you exact control over prompts, outputs, and performance metrics.
What Nerif Does, in Plain English
- ❀
Turn natural-language questions into True
/False
answers without writing ten-line prompts. - ❀
Return LLM responses as ready-to-use Python data—lists, dictionaries, strings—so you can skip fragile regexes. - ❀
Track cost, latency, and success rate in one line of code, just like printing a variable.
In short, Nerif lets you treat an LLM as just another library while preserving every lever you might need later.
Installation Guide: Three Steps and You Are Running
1. Prerequisites
- ❀
Python 3.9 or newer - ❀
An API key from any provider that speaks the OpenAI-style HTTPS+JSON protocol.
The examples below use OpenAI, but you can swap in Azure, Anthropic, or a local server. - ❀
Two optional environment variables: - ❀
NERIF_DEFAULT_LLM_MODEL
—the chat model you want by default. - ❀
NERIF_DEFAULT_EMBEDDING_MODEL
—the embedding model you want by default.
- ❀
Example for Linux or macOS:
export OPENAI_API_KEY="sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export NERIF_DEFAULT_LLM_MODEL="gpt-4o"
export NERIF_DEFAULT_EMBEDDING_MODEL="text-embedding-3-small"
Windows PowerShell:
setx OPENAI_API_KEY "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
setx NERIF_DEFAULT_LLM_MODEL "gpt-4o"
setx NERIF_DEFAULT_EMBEDDING_MODEL "text-embedding-3-small"
2. Install the Package
pip install nerif
That is the entire setup. No YAML files, no Docker containers, no hidden services.
Quick Start: From Sentence to Boolean in One Function
from nerif.core import nerif
from nerif.model import SimpleChatModel
# The default model is already set to gpt-4o via the environment variable
model = SimpleChatModel()
# Ask a yes/no question
if nerif("the sky is blue"):
print("True")
else:
# If the model says "False", ask why
print("No, ", end="")
print(model.chat("what is the color of the sky?"))
Possible console output:
True
or, at sunset:
No, During sunset, the sky can appear red, orange, or even purple...
How nerif()
Works Internally
-
Builds a concise prompt: “Determine whether the following statement is true or false: {statement}. Answer only true or false.” -
Adds retries and validation so that even if the model says “True, because…” the function still extracts the first token and casts it to a Boolean. -
Records the call in an in-memory metrics registry.
Structured Outputs: Let the LLM Fill Your Dictionary
LLMs love paragraphs; programs love dictionaries.
Nerif bridges the gap without extra parsing code:
from nerif.model import SimpleChatModel
model = SimpleChatModel()
recipe = model.chat(
"Give me a 3-step recipe for iced coffee with ingredients and time.",
format="json"
)
print(recipe)
Typical result:
{
"ingredients": ["coffee", "ice", "milk", "sugar"],
"steps": [
"Brew 200 ml strong coffee and let it cool.",
"Fill a glass with ice cubes.",
"Pour coffee and milk over ice, add sugar to taste."
],
"time_minutes": 5
}
Under the hood:
- ❀
A “Answer in valid JSON only” instruction is appended automatically. - ❀
If the response is malformed, Nerif attempts a single repair pass. - ❀
The final dictionary is returned directly—no wrapper objects to unwrap.
Observability: Know Your Cost Before the Invoice Arrives
Every call through Nerif populates a global metrics object.
You can inspect it at any time:
from nerif.core import nerif
statements = [
"earth is flat",
"2+2=4",
"water boils at 90 °C"
]
for s in statements:
nerif(s)
print(nerif.metrics())
Example output:
{
"total_calls": 3,
"success_rate": 0.6667,
"total_cost_usd": 0.0024,
"avg_latency_ms": 612
}
The same data can be piped into Prometheus, sent to a Slack bot, or simply logged to disk.
No extra services required.
Core Design Principles
-
Minimal Magic
Every prompt, retry policy, and timeout is visible in your source file. -
Composable Functions
nerif()
for judgments,SimpleChatModel().chat()
for free-form text, and optionalEmbeddingModel
for retrieval. -
Metrics as Data
Cost, latency, and success rate are exposed as plain dictionaries—easy to store, graph, or e-mail.
Real-World Use Case: A 40-Line Resume Filter
A 50-person startup receives hundreds of résumés weekly.
With Nerif, the filtering script stays under one screenful:
import os, json
from nerif.core import nerif
from nerif.model import SimpleChatModel
model = SimpleChatModel()
def is_relevant(cv_text: str) -> bool:
return nerif(
f"Does this CV match a senior backend Python position? CV: {cv_text[:2000]}"
)
def extract_info(cv_text: str) -> dict:
return model.chat(
f"Extract name, email, years of Python experience from this CV: {cv_text[:2000]}",
format="json"
)
for filename in os.listdir("cvs"):
with open(f"cvs/{filename}", encoding="utf-8") as f:
cv = f.read()
if not is_relevant(cv):
continue
info = extract_info(cv)
print(json.dumps(info, ensure_ascii=False))
Daily runtime:
- ❀
300–400 calls, < $0.20 - ❀
94 % accuracy reported from nerif.metrics()
- ❀
600 ms average latency, well within HR’s patience threshold
Extending Nerif: Custom Prompts and Models
Need a bespoke prompt or a different provider?
Pass your own template or subclass SimpleChatModel
:
from nerif.model import SimpleChatModel
class FriendlyModel(SimpleChatModel):
def _build_prompt(self, user_message):
return f"You are a helpful assistant. Always answer in JSON.\n{user_message}"
model = FriendlyModel()
response = model.chat("List three fruits.")
Everything else—retry, parsing, metrics—stays the same.
FAQ
Q1: Can I use models other than OpenAI?
Yes. Export NERIF_LLM_BASE_URL
and NERIF_LLM_API_KEY
pointing to any OpenAI-compatible endpoint. Azure, Anthropic, and local llama.cpp servers have all been tested.
Q2: Will upgrading break my code?
Nerif follows semantic versioning. Public APIs are frozen during 1.x; deprecations are announced at least three minor versions in advance.
Q3: Do I still have to write prompts?
For common tasks—truth checks, JSON extractions—Nerif ships with optimized prompts.
For rare cases, you can override or extend them without touching the core library.
Where to Go Next
- ❀
Full documentation: nerif-ai.com - ❀
License: GNU General Public License v3.0—use, modify, and redistribute freely while keeping attribution.
Whether you are automating résumé triage, building a chat bot, or simply tired of coaxing an LLM into returning true
, Nerif offers a calm, Pythonic way to put large language models to work—without surrendering control.