Stop letting LLM planning turn into a jargon-filled mess Developers Dillon Mulroy and Rin (r17x) are using call graph planning with an Effect TypeScript mental model to structure LLM prompts, categorizing steps into happy path (A), failure modes (E), and requirements (R) to improve code review speed and catch errors before coding. This approach forces LLMs to map data flow and dependencies explicitly, reducing debugging time and making code easier to test. Stop letting LLM planning turn into a jargon-filled mess 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. 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. Implementing Call Graph Planning 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. 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. Next Cloudinary's credit system is a massive trap for anyone running → /en/threads/8257/ All Replies (3) @kanelim1997 /en/users/kanelim1997/ ?