Agents
An agent is the unit of code and state that Golem runs. You define an agent type, a class with constructor parameters, state, and methods. Golem runs any number of agents of that type, each with its own memory, filesystem, and history. A user, an order, a chat session, a document, or an AI assistant can each be an agent.
Defining an agent type
An agent type declares its constructor parameters, its methods, and the state its methods work on. This counter keeps a count and exposes two methods:
TypeScript
import { z } from "zod";
import { defineAgent, method } from "@golemcloud/golem-ts-sdk";
export const CounterAgent = defineAgent({
name: "CounterAgent",
id: { name: z.string() },
methods: {
increment: method({ input: {}, returns: z.number() }),
getCount: method({ input: {}, returns: z.number(), readOnly: true }),
},
});
export const CounterAgentImpl = CounterAgent.implement({
init: () => ({ count: 0 }),
methods: {
increment() {
this.count += 1;
return this.count;
},
getCount() {
return this.count;
},
},
});The state is an ordinary field. There is no database call and no save step: Golem keeps the state durable, as described in Durable execution.
You build one or more agent types into a component, the WebAssembly binary that you deploy. An application is a set of components plus a golem.yaml manifest, deployed to an environment such as local or prod.
Agent identity
An agent is identified by its agent type and its constructor arguments. These are two different agents, each with its own count:
CounterAgent("alice")
CounterAgent("bob")Every call to CounterAgent("alice") reaches the same agent, whether it comes from the CLI, an HTTP endpoint, or another agent. Golem creates an agent the first time it is called; there is no separate “create” step, and deploying an application does not start any agents.
From the command line:
golem agent invoke 'CounterAgent("alice")' incrementChoose constructor parameters to match the thing the agent represents. One agent per user keeps a user’s state in one place; one agent per conversation gives each conversation its own state. In a multi-tenant application, include the tenant in the constructor parameters, as in ReportAgent("acme", "q3"), so each tenant’s agents have separate memory and files.
What each agent owns
Each agent has its own:
- Memory. No other agent can read or change it.
- Filesystem. Files are private to the agent. The manifest can seed new agents with initial files.
- Oplog. A durable log of everything the agent has done, used for recovery and inspection.
- Permissions. A wallet of permission cards that decides which effects the agent may perform. See Permissions.
- Configuration and secrets, as declared in the manifest.
Agents share data only deliberately: by calling each other’s methods, or through PostgreSQL or MySQL databases, key-value stores, and blob storage that their permissions allow. Agents written in TypeScript, Effect, and Rust can also use an embedded SQLite database that belongs to the agent.
One invocation at a time
An agent handles one method call at a time, in order, so its code needs no locks. Other calls wait in the agent’s queue. For parallel work, use more agents, such as one per user or per task.
For long-running work, such as an agent loop that runs for minutes, a common design is to run the work in its own agent, started with a trigger call, and report progress through a stream or a read-only method, so the agent that users talk to stays responsive. golem agent interrupt pauses a running agent; the interrupted call continues when the agent is next used.
A method marked read-only, such as getCount above, can be answered from a cache: when a cached result exists, the call returns it without waiting in the queue; otherwise the method runs in the queue like any other call. Golem rejects outgoing HTTP, calls to other agents, and storage writes inside a read-only method. It does not stop the method from changing fields or files, so keep read-only methods free of side effects.
Durable and ephemeral agents
| Mode | Behavior | Typical use |
|---|---|---|
| Durable (default) | State, files, and in-progress work survive failures and persist between calls. | Users, orders, conversations, long-running tasks |
| Ephemeral | Every call gets a fresh instance; nothing persists after the call. | Stateless request handlers |
The mode is set on the agent type. A durable counter called three times returns 1, 2, 3; the same counter as an ephemeral agent returns 1, 1, 1.
A caller can also create a phantom agent: a separate agent with the same constructor arguments, distinguished by a generated ID. Phantoms are useful for running several independent copies of the same job.
How agents are isolated
Each agent runs as its own WebAssembly instance. Many agents share one Golem server process, with no container or virtual machine per agent, so each agent is lightweight.
Open full-size image in a new tab.
Open full-size image in a new tab.WebAssembly gives each agent its own memory, and an agent can reach files, the network, other agents, or tools only through calls to the Golem host. The host checks each of those calls against the agent’s permissions. Per-agent memory and disk limits apply.
TypeScript and Effect agents, and Scala agents compiled with Scala.js, run on a JavaScript runtime built on QuickJS and compiled to WebAssembly, not on Node.js. It provides fetch, web streams, and Node-compatible core modules, so most plain-JavaScript npm packages work; packages with native addons do not. Rust, MoonBit, and Go agents compile directly to WebAssembly.
No agent can start a host process or load a native library. To run a shell, Node.js, npm, or the TypeScript compiler, an agent calls the corresponding tool.
Next
Durable execution: how Golem keeps an agent’s state and in-progress work through failures.
Related guides: