Skip to content

What is Protege?

Protege is a mini-framework for building agentic applications — products with an AI agent inside them. It ships as a Rails engine you mount into your own app. The agent isn't a separate service you call out to; it runs in your process, shares your models and jobs, and reaches the outside world the way a colleague would — over email.

The mental model: hiring a colleague

When someone joins a team you do two things. You give them an email address so they can communicate, and you give them access to a workspace so they can do the work. Protege is exactly that split:

  • Email is the channel — the agent's mouth and ears. Inbound mail arrives through Action Mailbox; replies go out over SMTP. The agent has a real address and threads conversations like anyone else.
  • Your Rails app is the workspace — the agent's hands. It acts on your app through tools you write: plain Ruby classes that call your models, services, and jobs directly.

Everything else in Protege is in service of that model. Rails supplies the plumbing for free: Active Job runs the asynchronous work, Action Mailbox receives the mail, and ActiveRecord persists every thread and message.

The running example: The Scoop

These docs build one example throughout — The Scoop, an ice cream company running its support and order management on Protege. Its Rails app already has Customer, Order, Flavor, and Refund models. Onto that we hire two agents:

  • Sundae (support@thescoop.com) — the customer-facing agent: answers questions, looks up orders, issues refunds, reads a photo a customer attached.
  • Scout (ops@thescoop.com) — an internal agent, locked to company senders, that runs scheduled duties like the morning low-stock report.

Each concept below is introduced by giving Sundae or Scout something new. The tutorial grows The Scoop capability by capability; the reference documents every surface.

The LOGI model

Protege organizes an agentic system into four responsibilities — Loop, Orchestrator, Gateway, Inference. Each maps to a concrete part of the engine, and each is independent: you can swap the model without touching your tools, add a tool without touching the inference loop, and add scheduled behavior without touching inbound handling.

LayerResponsibilityIn the engine
LoopAutonomous work on a schedule — the agent initiatesProtege::Loop — responsibilities + cron dispatch
OrchestratorThe inference cycle — assemble context, call the model, run tools, persistProtege::Orchestrator::Harness
GatewayThe protocol edge — email in and out, routing, guardsProtege::Gateway + Protege::AgentMailbox
InferenceThe model, behind a normalized request/responseProtege::Provider adapters

The Architecture section covers each layer in depth. For the original conceptual framing, see The era of agentic application frameworks.

The request lifecycle

When a customer emails Sundae, here is the path from inbound message to reply:

Inbound email (customer → support@thescoop.com)
   │  Action Mailbox

Protege::AgentMailbox ──► persona lookup · access check · recursion guard · bounce-if-unrouted
   │  Gateway.accept_smtp_message

Protege::InferenceJob            (enqueued via Active Job)


Orchestrator::Harness
   ├─ resolver chain ──► assembles context (system prompt, customer record, thread history)
   ├─ provider tool loop ──► model ⇄ tools (LookupOrder, ProcessRefund, …), bounded by max_tool_turns
   └─ persists every message (Protege::Message / EmailThread) and tool call (ToolUse)


send_email tool ──► outbound SMTP ──► the reply lands back in the customer's thread

The same tool loop serves both inbound email and Scout's scheduled work, through two harness subclasses — ReplyHarness (shown above) and ResponsibilityHarness. A scheduled run carries no inbound message; its responsibility_resolvers chain assembles the whole turn instead.

The extension surfaces

You build an agent by writing four kinds of plain-Ruby extension in app/. The engine discovers and wires them for you.

SurfaceBase classWhat it doesDiscovery
ToolsProtege::ToolActions the model can take in your appAuto (subclasses)
ProvidersProtege::ProviderLLM backend adaptersBy provider_id
ResolversProtege::ResolverAssemble the context sent to the modelAdded to a persona chain
HooksProtege::HookReact to lifecycle eventsAuto (subclasses)

Alongside them, personas (Protege::Persona subclasses) are the agent identities behind each email address, and responsibilities are their scheduled duties. Everything is ordinary Rails, so you test it the way you test the rest of your app.

Where to go next

  • Build it: the tutorial starts from rails new and ends with Sundae and Scout in production.
  • Look something up: the Extensions and Reference sections document every surface.
  • Understand the internals: the Architecture section walks each LOGI layer.