The problem with “tool use”
Every agentic framework starts the same way. You have a model. You give it tools. The model calls the tools. You stitch the results back in. Ship it.
This works until you need to watch it happen. Or replay what happened yesterday. Or hand control to a person mid-flow. Or swap the model. Or fork the run and explore an alternative. Suddenly you are fighting the abstraction instead of building on top of it.
The issue is that “tool use” is an implementation detail masquerading as a first principle. It describes how a model executes side effects, not what the system is doing at a semantic level. And the moment you need to reason about the system as a whole, that distinction matters.
Actors and messages
Verbum starts from a different abstraction: every participant is an Actor, and every interaction is a Message.
An Actor is anything that can receive a message, do some work, and optionally return one or more messages. A language model is an Actor. A shell session is an Actor. An MCP server is an Actor. A human sitting at a keyboard is an Actor. A vector-backed memory store is an Actor.
The Router is the only piece that knows about all of them. When an Actor produces a message addressed to another Actor, the Router delivers it, records it, and recurses. The entire run becomes a directed graph of typed, structured messages. Not log lines. Not trace IDs. Messages you can read, replay, fork, and query.
If every part of your system speaks the same language, you get observability, replayability, and composability for free.
The seven primitives
Verbum ships with seven actor types. Each one maps to a real thing you already use:
The critical insight is that all seven share the same interface. Register an actor, give it an ID, and the Router handles everything else. A system with one model and one shell uses the same API as a system with six models, four MCP servers, and a human in the loop.
What you get for free
When every interaction is a structured message flowing through a central router, several things fall out naturally:
Observability by construction. There is no instrumentation step. Every message is already recorded with its sender, recipient, content, and position in the conversation graph. The Mac app renders this in real time: a master conversation view, a typed message feed, and a live node graph.
Replay and fork. Any run can be replayed from its message history. More interestingly, you can fork from any message and explore what would have happened with a different model response, a different tool result, or a human override. Debug with time travel.
Portable context. Because conversation state lives in the Router, not in a provider SDK, you can move a conversation between models mid-flight. Start with Claude, hand off to a local model for a code generation step, resume with GPT for summarization. The context belongs to no one.
Composability without ceremony. An agent that uses a shell, an MCP server, and a memory store is three registered actors and a routing rule. No pipelines to wire. No abstractions to fight. No framework opinions about how your system should be structured.
The Mac app as a proof of concept
The Verbum Mac app is the opinionated expression of this architecture. It ingests streams from Claude Code task files, Codex CLI runs, terminal sessions, and arbitrary JSONL sources, then renders them as one unified conversation surface.
Three views. Chat is the master conversation, where you talk to the system and it routes your messages to the right actors. Feed is the typed message stream, every message from every source in chronological order. Graph is the live topology, showing you which actors are connected and what is flowing between them.
The app does not do anything the framework cannot do. It is a consumer of the same primitives. Any application, CLI, web dashboard, Slack bot, could sit on top of the same message graph.
Areas of extension
The actor model opens several natural extension points that do not require changes to the core:
Routing policies. The current Router does simple address-based dispatch. But the message graph supports arbitrary routing logic: priority queues, load balancing across model actors, content-based routing where a classifier actor decides who should handle a message. A “supervisor” actor that watches the graph and intervenes when things go off track is just another actor with a routing rule.
Persistence backends. The Router currently holds conversation state in memory. Swapping in SQLite, Postgres, or a distributed log like Kafka would give you durable, queryable conversation histories. Every message is already structured for this. The schema is the message type itself.
Multi-agent topologies. Nothing prevents one Router from talking to another. A “team” of agents could be a Router with several ModelActors and a shared MemoryActor, exposed to an outer Router as a single composite actor. Hierarchical agent systems fall out of composition, not special-casing.
Transport layers. Actors communicate through the Router today, but the message format is transport-agnostic. WebSocket, HTTP, Nostr, NATS, carrier pigeon—as long as messages arrive with the right shape, the Router does not care how they got there. This is the path to distributed agent systems where actors run on different machines.
Evaluation and testing. Because every run is a deterministic sequence of messages (given deterministic actors), you can write tests against message traces. Assert that the model asked the shell to run tests before declaring success. Assert that the human was consulted before a destructive action. The message graph is the test fixture.
Research directions
Several open questions sit at the intersection of the actor model and current AI capabilities:
Conversation-as-program. If a run is a graph of messages, that graph is a program. Can you compile it? Optimize it? Generate new runs from templates? There is a formal language lurking in the message traces that nobody has written the grammar for yet.
Adaptive routing. What if the Router itself were a model? A meta-agent that learns from past runs which actor should handle which kind of message, dynamically adjusting routing as the system evolves. The current Router is deterministic. A learned Router would be something else entirely.
Memory as conversation. The MemoryActor treats memory as a participant, not a database. This is a stronger claim than it sounds. If memory responds to queries the same way a model does, the line between “remembering” and “reasoning” blurs. What is the right interface for a memory that talks back?
Consensus protocols for multi-model systems. When three models disagree, who wins? The actor model gives you the message graph to reason about divergence, but it does not prescribe a resolution strategy. Voting, arbitration, escalation to a human—these are all expressible as actors, but the question of which strategy to use when is wide open.
Observable alignment. If every model decision is a message in a graph, you have a substrate for alignment research that does not require interpretability of the model itself. You can study what the model did, who it talked to, what it was told, and what it decided, in a format that is already structured for analysis. The conversation graph is an alignment log that writes itself.
The bet
The bet behind Verbum is simple: the right abstraction for AI systems is not “function calls with language models” but “conversations between typed participants.”
This is not a new idea. The actor model has been around since 1973. Message passing is the foundation of Erlang, Akka, and every reliable distributed system you have ever used. What is new is applying it to a world where one of the participants can reason in natural language.
When your model is just another actor, everything simplifies. The system becomes observable because messages are observable. It becomes replayable because message sequences are replayable. It becomes composable because actors compose. And it becomes debuggable because you can read the conversation.
Everything is a conversation. The framework just makes it legible.
