I’ve just wrapped up a phase of work, so it’s a good time to write up some recent dev notes and the thinking behind them.

Back in early April this year, I got an email from Richard, one of the maintainers of Hive. We traded views on AI agents.

Here’s what I wrote back, translated from the Chinese original:

Hi Richard,

I apologize for the delayed response; your email was mistakenly filtered into my spam folder.

First of all, I'm very pleased that you've noticed my development work. I will briefly share my perspective on AI agents and their applications, but this is strictly my personal view. If you have different thoughts or opinions, I welcome you to reply so we can discuss and exchange ideas.

Regarding the currently popular AI agents, I actually haven't used similar types of agents, such as OpenClaw, at this stage. The reason is that for most of my current needs and habitual use cases, I can handle them by creating workflows myself through AI-coding. I currently don't require an agent to automate every task for me, perhaps simply because I haven't yet encountered a scenario where that specific need arises.

I've observed that many users in the community don't clearly distinguish between the respective functions of workflows and AI agents, which is why we often see complaints about excessive token consumption. In reality, many requirements follow fixed process patterns. For these scenarios, it is highly suitable to organize them into workflows that are executed via crontab or event triggers. In this context, token usage is zero, and the stability of the process is significantly increased.

I have been following the Hive project, but I haven't had a chance to dive into it yet, and I apologize if that is disappointing. I have looked at some of the project's content, and I believe if I have a future use case, I will prioritize adopting it. I will certainly reach out at that time to discuss and exchange thoughts with you on any functional matters.

Thank you.

BR, Tai

And his reply

Hey Tai,

We’ve observed the same thing when running automation ourselves. In the majority of cases, a workflow—or an AI-powered workflow (with an LLM in certain steps, combined with programmed logic)—can already do the job perfectly. For software engineers like you and me, this is very easy to build. That’s because we have the skills to creatively solve problems, but many people don’t.

Our idea is that there should be an agent (we call it the “queen agent”) that acts as the creative problem solver—first trying to understand and solve the problem on its own, and then handing it off to a graph-based workflow.

It’s perfectly fine - in fact, I’m glad to hear you don’t need to use agents yet. I think the whole industry is still evolving and finding its direction. Let’s stay in touch. I’d be happy to discuss if you come across interesting use cases where agents add value.

Best,

Richard

Sent with Shortwave

At the time I had no situation that genuinely called for an agent, so my grasp of it was still pretty shallow.

That changed recently. I started putting an agent into a system I’m building, to do some work for me.

Take scraper work as an example. I have a workflow that pulls from data source A, cleans the data, and writes it into the persistence layer. What I can’t be sure of is whether the source format has changed. So I need an agent routine: when the workflow fails, it triggers the agent to read the error log and work out what went wrong. Then it commits, opens a PR (possibly even auto-merges), tells me which fixes it made, and updates the accumulated knowledge base.

Defining the Terms: Workflow & Agent

Before I get into my actual use case, I think we should draw a clear boundary between Workflow and Agent.

  • Workflow: LLMs and tools are orchestrated along code paths written in advance.
  • Agent: The model decides at runtime what to do and which tools to call, in service of some broader goal.

In other words, the line between the two isn’t whether AI is involved. It’s whether control of the flow lives at compile time or at runtime.

Take the scraper above. Even if I drop an LLM into the flow to interpret and align field semantics, it’s still a workflow, because the whole path was locked in the moment I wrote the code. The definition earns its keep here: it stops you from dumping the entire thing into an agent just because one step needs AI. Doing that burns a huge amount of tokens and makes behaviour far less stable.

Using Gyo to See What’s Really There

A deterministic happy path plus an agentic exception path. That’s what this example actually is.

Scraper behaviour is fixed. Run it 100 times and 99 of those runs take the same path. For those 99 what I want is stability, low cost, and reproducible output, and nothing fits that better than a workflow. Making it an agent means paying LLM costs on every single run, with different output each time, which makes it hard to tell whether this run came out better or worse than the last.

The remaining 1 is open-ended diagnosis: I don’t know what broke, I don’t know which files need touching, and it’s whatever unexpected thing happened this time. That undefinable case is where the agent belongs.

Groundwork Before You Call the Agent

When handling unexpected failures, we need to hand the agent as much information and error classification as we can. Otherwise it has no way to diagnose the problem and fix our workflow.

Error Classification

We have to spell out exactly which kinds of errors a scraper commonly hits.

  • Transient: 503, 429, timeout and friends. In principle these should never reach the agent, just retry the workflow.
  • Structural change: the selector changed, fields moved, the json schema changed. This needs the agent to step in.
  • Semantic change: everything returns 200, but where you expected 100 records you suddenly get 3. Catching this depends on field contracts and schema assertions (more on that below), and then the agent.
  • Source gone: login required now, or a paywall went up. Nothing to be done here, a human has to make the call.

Silent Failure

The worst thing a scraper can do is fail without throwing. One day a field starts coming back as an empty string, or a date format shifts, or pagination changes behaviour (100 rows per page becomes 20). Without an explicit contract and schema assertions, all of that gets treated as a normal value, flows into the parser, and ends up sitting in the persistence layer.

So the workflow has to define these failures as explicitly as it can. Those checks and validations are themselves part of the workflow: highly deterministic, reproducible behaviour. They pay off in overall stability.

Without that layer of checks up front, the agent never even gets triggered, and your data rots fast.

Give It Enough Clues

What else can we do so the agent has a real shot at fixing things? Think about how a human would go about it.

  • Keep the raw payload that failed. It becomes the source of truth for TDD-style verification of that fix.
  • The most recent successful payload, and its result.
  • Summary information such as an error fingerprint.
  • The before and after state around the key parsing steps.

Basically, whatever we humans used to do for error handling, whatever trace information we kept, keep the same things for the agent. Give it enough context to work out what went wrong and attempt a fix.

As for what counts as an accepted fix, beyond the TDD idea, the existing test and validation suite has to pass in full too.

Agent

An agent’s own behaviour is far more abstract than a workflow’s. Take a claude code routine: what we get to hand it is instructions and tools. Writing those instructions takes real design work, spelling out which skills and CLIs it should reach for, all in an attempt to keep the agent’s behaviour inside some boundary.

Before Auto-Merging: Authority Tiers and Guardrails

If you want the agent to open a PR and have that PR merged automatically, giving you a genuinely self-healing workflow, the precondition is a clear set of authority tiers and guardrails.

Roughly, we can split authority tiers into L0 through L3:

  • L0: open an issue only, change nothing. (Irreversible, e.g. anything that ripples into external systems.)
  • L1: open a PR, human reviews. (Reversible but costly, e.g. contract changes, retroactive data migrations, adding or removing environment variables.)
  • L2: a limited set of error categories, auto-merge allowed if validation passes. (Reversible and verified, e.g. changing a selector, adjusting field alignment logic.)
  • L3: fully automatic, with validation and monitoring in place, and automatic rollback if it blows up in production. (Reversible and auto-revertible, e.g. nothing that touches an existing contract.)

Mapped against this post by 十年大博士, the tiers here happen to key off whether something can be rolled back, rather than off how hard the task is.

On top of that, fixing a parser is relatively hard for an agent, while deleting an assertion rule is trivially easy. We can’t predict whether an agent, trying to get the job done, will take the shortcut and loosen or even remove assertions just to ship something fast.

So we also need guardrails: contract definitions, schema assertions, test validation. The moment any diff touches those boundaries, it’s forced down to L1 and requires human review.

Once the agent is handed a clear rating standard, its behaviour stops being quite so unconstrained.

Closing Thoughts

A few simple takeaways from this example.

  • The dividing line between workflow and agent comes down to whether control flow is decided at compile time or at runtime.
  • A deterministic happy path plus an agentic exception path. This is the clearest workflow + agent pattern I’ve actually built so far, and it matches what I had in mind all along: the work that used to require a human is the work you hand to the AI agent.
  • Across different domains you still lean on a lot of domain knowledge and judgment to constrain an agent and make it run well. In this scraper example, if you’d never written a scraper before, it would be hard to know which details matter or how to tier the agent’s permissions. The good news is that with AI’s help, picking up domain knowledge has gotten much faster and easier.

From the openclaw hype in March and April to now, the people still playing with agents have gotten a lot more mature about how they plan things. Agent frameworks themselves keep getting better designed too. What was once suspected of being a token-maxxing capital conspiracy (to sell shovels, first manufacture the demand) has turned into real cases of people using AI tools to improve their lives and get more done. That’s genuinely good to see.

It’s no longer about inventing requirements for AI’s sake. The situation comes first, then you refine it step by step into a task you can delegate to AI, and eventually less and less human involvement is needed.

The interesting part is that looking back at Richard’s email, what he described is exactly the opposite path from mine.

  • Richard’s queen agent: agent first. The agent understands the problem, then produces a graph-based workflow.
  • Me: agent last. Workflow first, then an agent built specifically for the exception path.

I don’t think the two conflict. Both are workflow and agent working together, just viewed from a different angle, and they depend on different levels of model maturity. Richard wants AI in the lead, clarifying an abstract situation and producing a reliable workflow. I keep a fixed workflow and only build an agent for the exceptions, for those unexpected abstract cases. In terms of difficulty, the latter (mine) is a good deal easier, and it demands less maturity from the model, which makes it easier to actually put into practice.

I’m looking forward to AI getting more mature, or to humans being willing to let go a bit more, so we can follow Richard’s lead and let AI run the whole thing.