Skip to main content

Agent framework for small models — template-based structured output, JSON repair, and workflow visualization.

Project description

Agno

Small Models. Big Impact.

Agent framework for small models (1–7B parameters). Kern generates simple fill-in-the-blanks JSON templates instead of complex JSON Schema, so small models actually produce valid structured output.

Install

pip install kern-ai

With extras:

pip install kern-ai[openai]       # OpenAI-compatible models
pip install kern-ai[ollama]       # Ollama
pip install kern-ai[anthropic]    # Claude
pip install kern-ai[google]       # Gemini
pip install kern-ai[ddg,mcp]      # DuckDuckGo search + MCP tools
pip install kern-ai[all]          # Everything

Quick Start

Basic Agent

from kern.agent import Agent
from kern.models.openai import OpenAIChat

agent = Agent(
    model=OpenAIChat(id="gpt-4o-mini"),
    instructions="You are a helpful assistant.",
)

result = agent.run("What is the capital of France?")
print(result.content)  # "Paris"

Structured Output

from pydantic BaseModel, Field
from kern.agent import Agent
from kern.models.openai import OpenAIChat


class BookReview(BaseModel):
    title: str = Field(description="Book title")
    rating: int = Field(description="Rating out of 5")
    summary: str = Field(description="One-paragraph summary")
    recommended: bool


agent = Agent(
    model=OpenAIChat(id="gpt-4o-mini"),
    output_schema=BookReview,
)

result = agent.run("Review 'The Hitchhiker's Guide to the Galaxy'")
print(result.content)
# BookReview(
#     title="The Hitchhiker's Guide to the Galaxy",
#     rating=5,
#     summary="...",
#     recommended=True
# )

Running with Local Models

Kern shines with local small models via OpenAI-compatible servers (llama.cpp, LM Studio, vLLM, Ollama):

from kern.agent import Agent
from kern.models.openai import OpenAIChat

# Connect to any OpenAI-compatible local server
model = OpenAIChat(
    id="local-model",                    # model name (ignored by some servers)
    base_url="http://127.0.0.1:8080/v1", # your local server
    api_key="not-needed",                # placeholder for local inference
)

agent = Agent(model=model, output_schema=BookReview)
result = agent.run("Review 'Dune' by Frank Herbert")

Models

Kern supports any OpenAI-compatible model provider:

Provider Install Usage
OpenAI kern-ai[openai] from kern.models.openai import OpenAIChat
Anthropic kern-ai[anthropic] from kern.models.anthropic import Claude
Google Gemini kern-ai[google] from kern.models.google import Gemini
Ollama kern-ai[ollama] from kern.models.ollama import Ollama
Groq kern-ai[groq] from kern.models.groq import Groq
Cerebras kern-ai[cerebras] from kern.models.cerebras import Cerebras
Mistral kern-ai[mistral] from kern.models.mistral import MistralChat
Azure kern-ai[azure] from kern.models.azure import AzureOpenAIChat
Any OpenAI-compatible OpenAIChat(base_url="...", api_key="...")

Agents

System Instructions

agent = Agent(
    model=model,
    instructions=[
        "You are a math tutor for high school students.",
        "Always show your work step by step.",
        "Use LaTeX notation for equations.",
    ],
)

Agent with Tools

from kern.agent import Agent
from kern.tools.duckduckgo import DuckDuckGoTools

agent = Agent(
    model=model,
    tools=[DuckDuckGoTools()],
    instructions="Search the web to answer questions.",
)

result = agent.run("What's the latest news about quantum computing?")

Agent Teams

from kern.agent import Agent
from kern.team import Team

researcher = Agent(name="Researcher", model=model, tools=[DuckDuckGoTools()])
writer = Agent(name="Writer", model=model, instructions="Write clear, engaging prose.")

team = Team(
    name="Content Team",
    mode="coordinate",   # agents collaborate
    members=[researcher, writer],
)

result = team.run("Write a brief on AI safety")

Multi-turn Conversations

agent = Agent(model=model)

# Each call continues the conversation
r1 = agent.run("My name is Alice")
r2 = agent.run("What's my name?")  # remembers "Alice"

Streaming

agent = Agent(model=model)

for chunk in agent.run("Explain photosynthesis", stream=True):
    print(chunk.content, end="", flush=True)

Structured Output (Templates)

This is where Kern differs from other frameworks. Instead of sending complex JSON Schema ($defs, properties, anyOf, allOf), Kern generates flat fill-in-the-blanks templates.

Simple Models

class Recipe(BaseModel):
    name: str
    ingredients: list[str]
    cook_time_minutes: int

Template sent to the model:

{ "name": "string", "ingredients": ["string"], "cook_time_minutes": "integer" }

Nested Models

class Address(BaseModel):
    street: str
    city: str
    zip_code: str

class Person(BaseModel):
    name: str
    address: Address

Template:

{
  "name": "string",
  "address": { "street": "string", "city": "string", "zip_code": "string" }
}

Union Types

from typing import Union

class TextBlock(BaseModel):
    text: str

class CodeBlock(BaseModel):
    code: str
    language: str

class Page(BaseModel):
    blocks: list[Union[TextBlock, CodeBlock]]

Template — both alternatives shown flat:

{ "blocks": [{ "text": "string" }, { "code": "string", "language": "string" }] }

Literal Enums

from typing import Literal

class Article(BaseModel):
    title: str
    status: Literal["draft", "published", "archived"]

Template:

{"title": "string", "status": "draft"|"published"|"archived"}

Field Descriptions

class Quiz(BaseModel):
    question: str = Field(description="The quiz question")
    options: list[str] = Field(description="4 multiple choice options")
    answer: int = Field(description="Index of the correct option (0-3)")

Template includes a separate descriptions block so the model knows what each field means.

JSON Repair

Small models produce malformed JSON — missing quotes, trailing commas, broken escapes. Kern fixes it automatically:

from kern.repair import extract_json

# Handles markdown code blocks, leading text, LaTeX, malformed JSON
data = extract_json("""
Here's the result:
```json
{"title": "Hello World", "items": [1, 2, 3,]}

""")

{"title": "Hello World", "items": [1, 2, 3]}


### LaTeX Protection

When models output math like `\frac{a}{b}`, JSON parsers break because `\f` is a form-feed escape character. Kern doubles backslashes before parsing:

```python
from kern.repair import extract_json

data = extract_json('{"formula": "\\frac{1}{2} + \\theta"}')
# Parsed correctly — LaTeX preserved

Tools

from kern.tools import (
    DuckDuckGoTools,    # pip install kern-ai[ddg]
    ExaTools,           # pip install kern-ai[exa]
    FirecrawlTools,     # pip install kern-ai[firecrawl]
    TavilyTools,        # pip install kern-ai[tavily]
    GitHubTools,        # pip install kern-ai[github]
    MCPTools,           # pip install kern-ai[mcp]
    YFinanceTools,      # pip install kern-ai[yfinance]
    NewspaperTools,     # pip install kern-ai[newspaper]
    CalculatorTools,    # built-in
    PythonTools,        # built-in
    FileTools,          # built-in
)

Custom Tools

from kern.tools import Toolkit

class MyTools(Toolkit):
    def __init__(self):
        super().__init__(name="my_tools")
        self.register(self.get_weather)

    def get_weather(self, city: str) -> str:
        """Get the current weather for a city."""
        return f"The weather in {city} is sunny and 72°F"

agent = Agent(model=model, tools=[MyTools()])

Storage

from kern.agent import Agent
from kern.storage.agent.postgres import PgAgentStorage  # kern-ai[postgres]

agent = Agent(
    model=model,
    storage=PgAgentStorage(
        table_name="agent_sessions",
        db_url="postgresql://localhost:5432/mydb",
    ),
)

Supported: Postgres, SQLite, Redis, MongoDB, GCS, Firestore, MySQL.

Knowledge Bases

from kern.knowledge.text import TextKnowledgeBase
from kern.vectordb.pgvector import PgVector  # kern-ai[pgvector]

knowledge = TextKnowledgeBase(
    vector_db=PgVector(
        table_name="recipes",
        db_url="postgresql://localhost:5432/mydb",
    ),
)

agent = Agent(model=model, knowledge=knowledge)
agent.knowledge.load(references=["path/to/recipes.txt"])

Workflows

from kern.workflows import Workflow

class ResearchWorkflow(Workflow):
    research_step: Agent = Field(...)
    write_step: Agent = Field(...)

    def run(self, topic: str):
        research = self.research_step.run(f"Research {topic}")
        article = self.write_step.run(f"Write about: {research.content}")
        return article

wf = ResearchWorkflow(
    research_step=Agent(name="Researcher", tools=[DuckDuckGoTools()]),
    write_step=Agent(name="Writer"),
)
result = wf.run(topic="renewable energy")

License

Apache License 2.0

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

kern_ai-0.1.1.tar.gz (1.8 MB view details)

Uploaded Source

Built Distribution

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

kern_ai-0.1.1-py3-none-any.whl (2.2 MB view details)

Uploaded Python 3

File details

Details for the file kern_ai-0.1.1.tar.gz.

File metadata

  • Download URL: kern_ai-0.1.1.tar.gz
  • Upload date:
  • Size: 1.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for kern_ai-0.1.1.tar.gz
Algorithm Hash digest
SHA256 40df96f4aef358730fc0e46c4648a7208f9b42b39465709821ad66205e60cf96
MD5 36e98cc5e4d8db5ec82d9e6b48fe3fea
BLAKE2b-256 e838e6d18c2d8cde0598b8e8227593523f6779d275c0dc9f5f267489ea0d8a33

See more details on using hashes here.

Provenance

The following attestation bundles were made for kern_ai-0.1.1.tar.gz:

Publisher: publish.yml on ndxrocks/kern

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

File details

Details for the file kern_ai-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: kern_ai-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 2.2 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for kern_ai-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9ce6b8f2f2b89cd68be3bf37bcaf18cbf7e0588581d2104ccbb478b8277ffa1e
MD5 282c327af045ff3e9e679b3b6b1133f3
BLAKE2b-256 62c28110b004de8887441d0f7150c03fe5290077f3ebf6487fd5165cac307953

See more details on using hashes here.

Provenance

The following attestation bundles were made for kern_ai-0.1.1-py3-none-any.whl:

Publisher: publish.yml on ndxrocks/kern

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