Building Goal-Mode Agent Loops | Generated by AI

Home 2026.07

Question: In agent frameworks like Hermes (Nous Research), how do you actually use “goal mode” / long-horizon task execution — and how do you build the same pattern into your own CLI agents (ww, iclaw, zz)?

Answer:

1. What Hermes actually does (mechanism, not hype)

Nous Research’s Hermes Agent is an open-source AI agent framework released under the MIT license that runs a five-stage learning loop: execute, evaluate, extract reusable reasoning patterns as named skills, refine those skills, and retrieve relevant skills for new tasks, with five sandbox backends — local, Docker, SSH, Singularity, and Modal. The differentiator vs. something like OpenClaw is that Hermes treats skill formation as part of the agent’s own operating loop rather than depending on an external skill marketplace — after a complex task it writes a structured skill document capturing procedure, pitfalls, and verification steps, then improves that skill on future runs.

The “goal mode” long-horizon mechanism specifically works like this:

⚠️ Caveat: several of the sources describing this (aiprofitboardroom.com, juliangoldieaiautomation.com, aisuccesslabjuliangoldie.com) are the same SEO content-mill author repeating near-identical templates — treat specific numbers (ROI claims, £/month savings) as marketing, not verified facts. The mechanism itself (judge-based turn-budgeted loop, /goal commands, config path) is corroborated across independent write-ups (i-scoop.eu, openhosst.com) so I’d trust the architecture description more than the case-study numbers.

The two failure modes worth internalizing before you copy this pattern: vague goals where the judge can’t determine completion — be specific about what “done” means — and using the default turn budget for big goals, since 20 turns won’t finish a 50-step task.

2. This is a general pattern — build it yourself in ~80 lines

You don’t need Hermes to get this. The core primitive is: actor loop + judge/critic + turn budget + persisted state. Academic work formalizes this as a planner-actor split — a planner receives the task instruction, decomposes it into a reference sub-goal graph before execution, then tracks progress by comparing the actor’s trajectory against that graph, intervening with corrective feedback when the actor deviates or stalls. This is directly usable in your CLI agents.

# goal_loop.py — minimal Hermes-style goal harness for ww/iclaw/zz
import json, os, time
from anthropic import Anthropic

client = Anthropic()
STATE_PATH = ".goal_state.json"

def load_state():
    if os.path.exists(STATE_PATH):
        return json.load(open(STATE_PATH))
    return None

def save_state(s):
    json.dump(s, open(STATE_PATH, "w"), indent=2)

def judge(goal: str, transcript: str) -> dict:
    """Conservative judge — fail-open on error (per Hermes semantics)."""
    try:
        resp = client.messages.create(
            model="claude-opus-4-8",  # use a stronger model as judge than the actor
            max_tokens=300,
            system=(
                "You are a strict completion judge. Given a GOAL and a TRANSCRIPT of "
                "an agent's work, respond ONLY with JSON: "
                '{"done": bool, "blocked": bool, "reason": str}. '
                "Mark done=true only if the deliverable is explicitly produced, or "
                "blocked=true if further progress is genuinely impossible."
            ),
            messages=[{"role": "user", "content": f"GOAL:\n{goal}\n\nTRANSCRIPT:\n{transcript}"}],
        )
        return json.loads(resp.content[0].text)
    except Exception:
        return {"done": False, "blocked": False, "reason": "judge_error_fail_open"}

def actor_step(goal: str, history: list, tools: list) -> str:
    resp = client.messages.create(
        model="claude-sonnet-5",
        max_tokens=2000,
        system=f"Standing goal: {goal}\nWork one concrete step closer to completion. "
                f"State clearly if you believe the goal is now complete.",
        messages=history,
        tools=tools,
    )
    # ... handle tool_use blocks, append tool_result, etc. (omitted for brevity)
    text = "".join(b.text for b in resp.content if b.type == "text")
    history.append({"role": "assistant", "content": resp.content})
    return text

def run_goal(goal: str, tools: list, max_turns: int = 20, resume: bool = False):
    state = load_state() if resume else None
    history = state["history"] if state else []
    turn = state["turn"] if state else 0

    while turn < max_turns:
        turn += 1
        out = actor_step(goal, history, tools)
        transcript = "\n".join(m.get("content", "") if isinstance(m.get("content"), str) else str(m) for m in history)

        verdict = judge(goal, transcript)
        print(f"[turn {turn}/{max_turns}] judge={verdict}")

        if verdict["done"] or verdict["blocked"]:
            save_state({"history": history, "turn": turn, "status": "finished", "reason": verdict["reason"]})
            return verdict

        save_state({"history": history, "turn": turn, "status": "running"})
        time.sleep(1)  # backoff / rate-limit hygiene

    save_state({"history": history, "turn": turn, "status": "paused"})
    print(f"⏸ Goal paused — {turn}/{max_turns} turns used. Call run_goal(..., resume=True) to continue.")
    return {"done": False, "blocked": False, "reason": "turn_budget_exhausted"}

Notes on why each piece matters for your context:

3. Where to go deeper (matches your MoE/agent-architecture direction)

For your CLI tools specifically: I’d wire the judge() fail-open pattern and turn-budget pause/resume into zz or ww first since it’s ~80 lines and framework-agnostic, before adopting Hermes wholesale — you get the same long-horizon capability without taking on a dependency whose ecosystem is, per the comparison piece, smaller and younger than OpenClaw’s, with security posture not yet proven at scale.

References:


Back Donate