From a 30‑Minute DIY Agent to Harness as the New Backend – What Gaps Remain for an Agent‑Ready System?
The article examines a minimal 30‑minute Agent loop demo, then analyzes how Harness can serve as the backend by introducing a runtime capability registry, worker lifecycle management, diverse triggers, and unified tracing, outlining four concrete design actions to close the gaps for agent‑ready systems.
Background
Earlier we built a 30‑minute DIY Agent demo that implements a minimal loop: the model reads a task, selects a tool, runs the tool, writes the result back to the context, and repeats. The demo uses only three tools ( list_files, read_file, run_command) and shows the skeleton of an agent.
Problem Statement
The loop works in isolation, but when the loop is embedded in a real business system, many questions arise: how to expose tools, how to register workers, how to trace interactions, how to handle dynamic workers, and how to make the backend observable and recoverable.
Key Concepts
Worker – a participant that can register capabilities.
Function – a capability with an ID, schema, owner, version, and permissions.
Trigger – an entry point (HTTP, queue, cron, state change).
"An agent is a worker. Its tools are functions. Its memory is state. Its orchestration is triggers."
Minimal Loop Code
async function runAgent(task: string) {
const messages = [{role: "user", content: task}];
for (let step = 0; step < 8; step++) {
const response = await model.create({messages, tools});
if (!response.toolCall) {
return response.text;
}
const observation = await runTool(response.toolCall);
messages.push({role: "tool", content: observation});
}
return "Stopped: step limit reached.";
}This tiny program reveals the agent’s skeleton.
From Static Tool List to Runtime Capability Registry
Instead of a hard‑coded array of tools, Harness registers workers and their functions at runtime. Example SDK usage:
import { registerWorker } from "iii-sdk";
const runtime = registerWorker("ws://localhost:49134");
runtime.registerFunction("hello::greet", async (input) => ({
message: `hello ${input.name}`
}));
runtime.registerTrigger({
type: "http",
function_id: "hello::greet",
config: {api_path: "/greet", http_method: "POST"}
});
const result = await runtime.trigger({
function_id: "hello::greet",
payload: {name: "world"}
});This registers a worker, exposes a function, and makes it callable via HTTP or another worker.
Runtime Discovery
The engine maintains a live registry of workers, functions, and triggers. It supports querying the current set and subscribing to changes, enabling agents to discover “what the system can actually do now” rather than a static list.
Design Actions for an Agent‑Ready Backend
Upgrade the tool list to a capability directory containing ID, description, input/output schema, owner, version, permissions, and observability metadata.
Treat worker lifecycle (connect, disconnect, restart) as a normal path; the SDK automatically re‑registers functions on reconnection and handles race conditions via function_owners and external_function_owners tables.
Expand triggers beyond agent‑initiated calls to include business events such as HTTP requests, cron jobs, queue messages, and state changes.
Propagate tracing information ( traceparent, baggage) from the protocol layer (e.g., InvokeFunction, InvocationResult) so that cross‑language, cross‑process execution can be observed end‑to‑end.
Operational Boundaries
Engine availability : the central runtime becomes a critical point and must be horizontally scalable, backed by state storage and backup/recovery.
Trigger semantics differ : HTTP cares about latency and response, queues about idempotency and dead‑letter handling, cron about locking and missed windows.
Capability directory growth : enforce naming conventions, versioning, ownership, permission checks, and deprecation processes.
Dynamic worker creation is powerful but requires RBAC, sandbox isolation, resource quotas, and audit logging.
License considerations : engine under Elastic License 2.0, SDK under Apache 2.0; commercial redistribution needs separate review.
Context management remains separate; the runtime tells which capabilities are live but does not decide which context window to use.
Conclusion
The 30‑minute demo shows the first layer—making the agent loop run. Harness adds the second layer—stabilizing the loop for long‑running tasks. The third layer, explored here, is integrating the loop with a real backend: registering participants, exposing capabilities, handling diverse triggers, and providing unified tracing. Closing these gaps turns Harness into the “new backend” for agents.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Architect
Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
