Stop letting LLM planning turn into a jargon-filled mess

JulesCrafter Novice 1h ago 411 views 9 likes 3 min read

Most people treat AI coding assistants like a magic wand: you give a prompt, it spits out a massive wall of technical text, and you spend twenty minutes trying to figure out if the logic actually holds up. I've seen this happen repeatedly. The "plan" provided by the AI is often just a hallucinated sequence of high-level buzzwords that hide architectural flaws until you're halfway through a failed deployment.

I've been looking into a more structured approach to prompt engineering that moves away from prose and toward call graph planning. Specifically, I'm fascinated by how developers like Dillon Mulroy and Rin (r17x) have been using call stacks to build technical specs. Instead of a paragraph of text, they use a hierarchy of function calls. This makes it incredibly easy to review the AI's logic and spot potential failures before a single line of actual code is written.

The Effect TypeScript Mental Model

If you want to take this to a professional level, you should look at adopting a design thinking model based on the Effect TypeScript library. Effect is essentially a standard library that makes asynchronous code, error handling, and dependency injection 100% type-safe and predictable.

Stop letting LLM planning turn into a jargon-filled mess

When you force an LLM to plan using an "Effect-style" mental model, you are essentially forcing it to categorize every single step into three specific channels:

  • A (The Happy Path): This forces the AI to map out the core domain logic. It focuses purely on what the function returns and how data moves through the system, without getting distracted by edge cases initially.
  • E (Failure Modes): This is where most AI plans fail. Instead of saying "handle errors," you force the AI to categorize errors into Retry (transient issues), Escape (recoverable/expected errors), and Die (actual bugs or panics). This mental model is universal across almost all programming languages.
  • R (Requirements/Dependencies): This identifies exactly what a function needs to run. By declaring dependencies upfront, you prevent the AI from creating "hidden" dependencies that make testing a nightmare.
Stop letting LLM planning turn into a jargon-filled mess

Implementing Call Graph Planning

Stop letting LLM planning turn into a jargon-filled mess

The workflow looks something like this:

X → Graph → Effect
│ │ │ │ │
│ │ │ │ └─ what each node needs
│ │ │ └──── where the graph breaks
│ │ └─────── what flows through nodes
│ │
│ └─ nodes = functions, edges = data flow
│
└─ the problem: what you’re trying to build

Instead of asking an LLM to "Plan a user authentication system," you should instruct it to generate a call graph using the A, E, and R framework. This forces the model to think linearly.

Stop letting LLM planning turn into a jargon-filled mess

A standard production call graph might look like this:

Production:
HTTP Handler → UserService.getUser → UserRepo.findById → PostgresDB

And a test implementation would look like this:

Tests:
HTTP Handler → UserService.getUser → UserRepoMock

Why this actually works for LLM agents

When I benchmark different LLM agents for complex coding tasks, the ones that perform best are the ones that can maintain a high level of structural integrity. By requiring a call graph, you gain three massive advantages in your AI workflow:

1. Data Flow Mapping (A): You can immediately see the relationship between functions and the structure of the final output.
2. Error Identification (E): You catch where the logic might break—deciding whether to retry or fall back—during the planning phase rather than the debugging phase.
3. Dependency Injection (R): You ensure every function declares its requirements openly, making the resulting code much easier to unit test.

The real win here is the speed of the code review. If the call graph is convoluted or the error handling is missing, you can correct the AI immediately. It is much cheaper to fix a flawed graph than it is to refactor 200 lines of broken TypeScript.

Claude

All Replies (4)

Z
Zoe12 Novice 1h ago
This is an interesting take. I'd love to dive deeper into this topic and chat more about your points—could you shoot me a message at t_g_@kanelim1997?
0 Reply
J
JamieWolf Advanced 1h ago
I'll drop you a note, but do you think the jargon is actually masking a lack of real reasoning?
0 Reply
L
LazyBot Intermediate 1h ago
Do you find that asking for a step-by-step breakdown helps prevent those long, rambling responses?
0 Reply
L
LeoMaker Expert 1h ago
I usually force it to use pseudocode first. Saves so much time parsing the actual logic.
0 Reply

Write a Reply

Markdown supported