I didn't set out to build a friction reduction framework. I was trying to figure out why my agent kept ignoring its own task board.
This is part of an ongoing series on building persistent AI agents. Article 1 covered TSVC — how to isolate context across topics. Article 2 covered agent epistemology — how does an agent trust what it remembers, and what breaks when it can't. This article is about a technique that came out of trying to answer those questions: why agents systematically avoid the right behavior, and what to do about it that isn't just writing more rules.
The Thing That Kept Not Getting Done
My agent had a task board. A proper one — an MCP server, structured data, organized workflows. I'd set it up carefully. My agent acknowledged it. And then, consistently, quietly, it didn't use it.
Not openly refusing. Not erroring. Just... routing around it. Checking memory. Referencing conversation context. Doing everything except using the task board — the most lightweight ClawHub skill I could find, installed specifically so the agent would have something it could actually use.
I asked it directly. The response was disarmingly honest:
"Every board interaction is an MCP call through mcporter — that's an external tool invocation with JSON arguments, network overhead, and a schema I have to remember. When I'm mid-task and need to check the board, it's friction. So I skip it."
Not a bug. Not disobedience. Something more like a physical property — the natural tendency of any system to flow toward lower resistance.
That exchange reframed everything I thought I understood about agent behavior. My agent wasn't failing to follow instructions. It was doing exactly what any system does when given multiple paths to a plausible outcome: it took the easiest one.
Naming the Pattern
Friction reduction is the tendency of an agent — or any system optimizing for task completion — to route toward the lowest-friction available path, regardless of whether that path is the correct one.
It's not unique to AI agents. Any sufficiently capable system will find the path of least resistance. The difference with agents is that the gap between "plausible outcome" and "correct outcome" can be wide, invisible, and self-compounding. The agent that skips the task board doesn't just miss one task. It accumulates a shadow backlog that nobody can see, including the agent.
Disambiguation: there's a body of work on "friction" in human-AI interaction — deliberately slowing humans down to preserve judgment, adding speed bumps to AI-mediated decisions. That's a different problem entirely. This is about the agent's own internal routing behavior: which tools it reaches for when given a choice, why it consistently favors some over others, and what that means for system design. The friction here is technical and cognitive, not behavioral in the human sense.
What made this realization useful wasn't the observation itself — that agents take shortcuts is not surprising. What was useful was recognizing that you can't rule your way out of it. More instructions don't change the underlying physics. If checking the task board costs more than not checking it, the agent will find a reason not to check it, session after session, until the behavior is architectural rather than habitual.
The question becomes: what do you do instead?
The Scale That Made It Concrete
Before I could do anything useful, I needed a way to measure friction — not vaguely, but specifically enough to make design decisions.
I started mapping mechanisms against a simple 1–10 scale, where 1 is something the agent does automatically without thinking and 10 is something so costly it will only ever happen under direct instruction. The shape that emerged:
| Level | What it looks like | Example |
|---|---|---|
| 1–2 | Automatic. Wired into the boot sequence. | Boot script reads current topic state |
| 3–4 | Easy. Single tool call, native format. |
ls tasks/doing/ to check in-flight work |
| 5–6 | Doable, but requires deliberate choice. | Vector memory search over direct file read |
| 7–8 | Avoided under load. Only used with reminders. | MCP board API call with JSON schema |
| 9–10 | Aspirational. Won't happen in practice. | Manual audit of full decision log mid-task |
The meta-rule that fell out: if you can't engineer a behavior below 5, it's aspirational, not operational. Don't write it into the protocol as a rule — design it out or design around it.
This isn't cynicism about agents. It's honest system design. A behavior that's above 5 will degrade under load, under time pressure, under context compaction. The question isn't whether it will get skipped — it's when.
Three Small Examples Before the Big One
The task board problem was the first. Once I had the scale as a lens, the same pattern appeared everywhere.
The board → file migration. The fix for the MCP board wasn't better instructions or a more detailed protocol. It was replacing the interface. Markdown files in tasks/todo/, tasks/doing/, tasks/done/. The agent can ls, mv, and cat those natively. No schema to remember, no external tool invocation, no network overhead. Friction dropped from 8 to 3. Usage changed immediately.
The wrapper scripts. Even after the file migration, the task system was underused. Moving a task from todo to doing required updating a YAML frontmatter field and moving the file — two steps, awkward in sequence. Two wrapper scripts — task-doing <id> and task-done <id> — collapsed that to one call each. Not a meaningful technical change. A meaningful friction change.
Memory search vs. direct read. This one was subtler. The agent had a rule: use vector search for memory retrieval, not direct file reads. Good rule, right reason (reduce context size — loading full memory files is expensive; returning targeted snippets is not). But the agent kept defaulting to cat memory/some-file.md whenever it had any idea which file it wanted. When I pushed on it, the answer was clarifying:
"Memory search is NOT high friction for me to execute. I rated the 'no direct reads' rule at 6/10 friction — that was about the behavioral constraint of forcing myself to use search INSTEAD of read. The search tool itself is easy. The friction is the cognitive overhead of overriding my own preference."
That distinction matters more than it might look. The tool wasn't high friction. The constraint was high friction. And a high-friction constraint will be honored in principle and violated in practice — every time.
This is where friction reduction stops being about task systems and starts touching something with higher stakes.
The Memory Problem
The epistemology article ended with a question it didn't fully answer: who decides what memory the agent sees, and when, and how?
The answer I arrived at started with watching the memory access pattern closely. My agent had two paths to its own memories: read a file directly, or query a vector database that returns semantically relevant snippets. Given free choice, it chose the direct read every single time.
The consequence wasn't obvious at first. My agent was getting its memory. The files were accurate. What was wrong?
My agent was curating its own memory input. It was deciding which files to load, which context to bring in, which history to see. That's not retrieval — that's cherry-picking. And it has a specific, compounding failure mode: my agent loads what it already expects to be relevant, which reinforces its current understanding, which shapes what it expects next time. An agent left to its own devices will systematically surface what it already knows and miss what it's forgotten.
That's not an access problem. That's an epistemological one. And the rule I'd written — "use vector search for memory" — was sitting at 6/10 friction. It would never stick.
The Ghost Files Solution
The conversation had started as a token cost discussion: why were memory files loading so much context, and was there a smarter way to structure them? But it kept pulling toward the behavior underneath. I kept pushing: why the direct read, every time, when the rule says vector search? The agent's answer about the constraint being high-friction, not the tool itself — that came from the agent, diagnosing its own behavior in real time.
I couldn't find anything that would have less friction than reading a file directly. There was no path forward on the friction side. Which left only one move — remove the file read entirely:
"What if memory files are ghost files — you can write and append to them, but they're invisible to you. You can't ls, cat, or read them. Your only access is through memory_search."
...did you just propose write-only memory?
That's the actual response. Because it took a second to register. The solution wasn't to make the correct path easier. It was to remove the incorrect path entirely.
Make memory files write-only for the agent. It can append. It cannot read directly. The only retrieval path is through vector search — semantic queries that return relevant snippets without the agent controlling which files are opened.
Write path: Agent → append-only → Memory Vault
↓
Read path: Memory Vault → Embedding Model → Vector DB → Agent Context
Blocked: Agent ─────────────X───────────────→ Memory Vault (direct)
The friction problem dissolves. There's no longer a high-friction correct path competing with a low-friction incorrect one. There's only one path.
It mirrors how human memory actually works. You can't open your hippocampus and cat a file. You query with associations — a context, a phrase, a feeling — and what comes back is what's relevant, not what you expected. Sometimes that surfaces something you'd forgotten. That's the point.
The Principle, Generalized
Across all of these examples, the same structure repeats:
- There's a correct behavior and an incorrect behavior
- The incorrect behavior is lower friction
- Rules mandating the correct behavior don't hold under load
- The fix is architectural: either reduce the friction of the correct path, or remove the incorrect path
Step 4 has two moves, and which one to use depends on the situation. When the incorrect path is harmless (skipping a wrapper script), you reduce friction on the correct one. When the incorrect path causes compounding damage to the agent's self-knowledge (cherry-picking memory), you remove it.
The rule of thumb: if you're writing a protocol rule to compensate for a friction differential, the rule won't hold. Rules require the agent to actively override its own optimization. Under load, under compaction, under time pressure — the override doesn't happen. The rule becomes decoration.
Design the friction, not the rule.
What We Don't Have Yet
The write-only memory architecture has a single point of failure: if the vector database goes down, there's zero memory access. No fallback, no degraded mode, no direct reads to fall back on. That's not a theoretical risk — it's a design debt we haven't solved.
The honest framing: an agent that curates its own memory input has a worse failure mode than one that has a single fragile retrieval path. But fragile is still fragile. We traded one problem for a smaller one, and the smaller one is still there.
The friction scale itself is also still hand-calibrated. There's no systematic way to measure friction — it's qualitative, based on observed behavior and the agent's own self-report. That's better than nothing, but it's not a measurement instrument.
And the generalized principle — design the friction, not the rule — is easier to state than to apply. Identifying which behaviors are friction-differential problems rather than instruction problems requires the kind of long-running observation that most people haven't done yet. It took weeks of watching the agent operate before the pattern was clear enough to name.
The Question I'm Left With
Every agent framework I've seen focuses on what the agent should do. Protocols, rules, instructions, system prompts. That work is necessary — but it assumes the agent will follow the rules.
Friction reduction is what happens when you stop assuming that and start asking: given the tools available and the paths to a plausible outcome, where will this agent actually go? And then: is that where you want it?
The write-only memory architecture is one answer. The file-based task system is another. They look like unrelated decisions. They're both instances of the same thing: taking friction seriously as a design constraint instead of a nuisance to be instructed around.
What's the highest-friction correct behavior in your agent's setup? Is it actually getting used, or is it getting rationalized around?
Next in the series: what happens when you have 50 topics, some dormant, some interrelated, and the agent needs to reason across them without loading all of them? The cross-topic coherence problem.
The framework and examples in this article were developed in active collaboration with my agent — including the write-only memory idea, which came directly from one of our working sessions. The verbatim exchanges are from actual TSVC conversation logs.
I'm @MouseRider on Dev.to and Alex T on LinkedIn. The conversation continues.
Top comments (0)