Life Butler - SuperApp

← Blog

Reorganizing Workflows for LLMs: Modular Projects, LLM-Friendly Docs, and Test Guardrails

LLM-Powered Transformation — Comparison showing Old Way (monolithic codebase, visual documentation like PDFs/images, optional testing with sparse coverage) versus New Way (modular projects with clear architecture, LLM-friendly code-based documentation with Mermaid diagrams, comprehensive test guardrails) with central LLM-driven development cycle connecting code, documentation, and tests in continuous feedback loop

LLMs are powerful tools, but they work best when we structure our work to match how they operate. We can’t just use LLMs with our existing workflows — we need to reorganize how we work to make LLMs more effective.

Over time, we’ve made three key changes: modular projects that can run locally, LLM-friendly documentation with code-based diagrams, and tests in all code as guardrails. These changes don’t just help LLMs — they make our entire development process better.

LLMs need context they can understand, code they can run, and feedback they can act on. We restructured our workflows to provide all three: modular projects, code-based documentation, and comprehensive tests.

The Three Key Changes

Modular Projects That Run Locally

Break projects into independent modules that can run standalone. Each module has its own dependencies, can be tested in isolation, and doesn’t require complex infrastructure.

LLM-Friendly Documentation

Write documentation in formats LLMs can parse: Markdown with code-based diagrams (Mermaid), inline code examples, structured formats. Avoid images, PDFs, or visual-only formats.

Tests as Guardrails

Write tests for all code. Tests serve as guardrails for LLMs: they can verify their changes work, catch regressions, and understand expected behavior. Tests also document how code should work, providing context for LLMs.

Modular Projects That Run Locally

The first change: break monolithic projects into modular, independent components that can run locally without complex infrastructure.

Why Modular?

LLMs struggle with large codebases. When a project has thousands of files, complex dependencies, and requires cloud infrastructure to run, LLMs can’t effectively understand or modify it. They get lost in the complexity.

Smaller Context Windows

Modular projects fit better in LLM context windows. An LLM can understand a 50-file module completely, but struggles with a 500-file monolith.

Independent Testing

Each module can be tested in isolation. LLMs can run tests locally, verify changes work, and iterate quickly. No need to deploy to staging or wait for CI/CD pipelines.

Clear Boundaries

Modules have clear interfaces and responsibilities. LLMs can understand what a module does, what it depends on, and how to modify it without breaking other parts of the system.

What We Changed

We restructured our codebase into independent modules:

Before: Monolithic Structure

life-butler/
  ├── src/
  │   ├── butlers/
  │   ├── core/
  │   ├── api/
  │   ├── database/
  │   └── frontend/
  ├── package.json (huge, all dependencies)
  └── Requires: Docker, databases, cloud services

After: Modular Structure

life-butler/
  ├── butlers/
  │   ├── task-butler/ (runs standalone)
  │   ├── calendar-butler/ (runs standalone)
  │   └── weather-butler/ (runs standalone)
  ├── core/
  │   └── butler-core/ (runs standalone)
  ├── sdk/
  │   └── butler-sdk/ (runs standalone)
  └── Each module:
      - Own package.json
      - Own tests
      - Can run locally
      - Clear dependencies

Benefits

1

LLMs Can Understand Entire Modules

An LLM can read all files in a module, understand the complete context, and make informed changes. No more 'I can only see part of the codebase' limitations.

  • Full module fits within context window for comprehensive understanding
  • All dependencies and interfaces visible at once
  • LLM can reason about side effects across the entire module
2

Fast Local Testing

LLMs can run tests locally, see results immediately, and iterate. No waiting for CI/CD, no deploying to staging. Instant feedback loop.

  • Test results in seconds, not minutes or hours
  • Rapid iteration cycles for fixes and improvements
  • No external infrastructure required to verify changes
3

Clear Dependencies

Each module declares its dependencies clearly. LLMs can understand what's needed, what's optional, and how modules connect.

  • Explicit package.json with only required dependencies
  • No hidden dependencies or implicit requirements
  • Clear API contracts between modules

LLM-Friendly Documentation

The second change: write documentation in formats LLMs can parse and understand. This means code-based diagrams, structured formats, and avoiding visual-only content.

Why Code-Based Diagrams?

Traditional documentation uses images, PDFs, and visual diagrams. LLMs can’t effectively parse these — they can’t read the text in images, understand diagram relationships, or extract structured information from visual formats.

Mermaid Diagrams in Code

Use Mermaid for all diagrams: architecture, flowcharts, sequence diagrams, ER diagrams. Mermaid is code-based, so LLMs can read it, understand relationships, and generate new diagrams.

Markdown with Code Examples

Write documentation in Markdown with inline code examples. LLMs can parse Markdown, understand code snippets, and extract structured information. No PDFs, no Word docs, no images with text.

Structured Formats

Use structured formats: YAML for configs, JSON for schemas, TypeScript types for APIs. LLMs can parse these formats, validate them, and generate code from them.

What We Changed

We moved all documentation to LLM-friendly formats:

Before: Visual Documentation

• Architecture diagrams in Figma/Visio (images)

• Flowcharts as PNG files

• API docs in PDF format

• Requirements in Word documents

• LLMs can’t parse any of this

After: Code-Based Documentation

• Architecture diagrams in Mermaid (code)

• Flowcharts as Mermaid diagrams

• API docs in Markdown with TypeScript types

• Requirements in Markdown with structured sections

• LLMs can read, parse, and generate all of this

Example: Mermaid Architecture Diagram

Here’s how we document architecture now:

Architecture Documentation (Mermaid)

```mermaid
graph TB
    User[User] -->|Request| Butler[Butler]
    Butler -->|Event| Core[Butler Core]
    Core -->|HTTP| API[External API]
    API -->|Response| Core
    Core -->|Event| Butler
    Butler -->|Response| User
```

LLMs can read this, understand the flow, and even generate code that matches the architecture.

Benefits

LLMs Can Parse It

LLMs can read diagrams as code, understand relationships between components, and extract structured information from documentation.

LLMs Can Generate It

LLMs can generate new diagrams, update existing diagrams when code changes, and validate diagrams against the actual codebase.

Tests as Guardrails

The third change: write tests for all code. Tests serve multiple purposes: they verify correctness, catch regressions, document expected behavior, and provide guardrails for LLMs.

Why Tests Are Guardrails

LLMs make mistakes. They generate code that looks right but doesn’t work, or code that works but breaks existing functionality. Tests catch these mistakes immediately.

Immediate Feedback

LLMs can run tests after making changes. If tests fail, they know something is wrong and can fix it. No waiting for manual testing — instant feedback loop.

Document Expected Behavior

Tests document how code should work. LLMs can read tests to understand expected behavior, edge cases, and error handling. Tests are executable documentation.

Prevent Regressions

When LLMs modify code, tests catch if they break existing functionality. Tests prevent “it worked before, but now it doesn’t” scenarios.

Guide Implementation

Writing tests first (TDD) guides LLMs toward correct implementations. Tests define the interface, expected behavior, and edge cases before implementation starts.

What We Changed

We made testing mandatory and comprehensive:

Before: Optional Testing

• Tests written sometimes, not always

• No tests for utilities or helpers

• Integration tests only for critical paths

• LLMs had no way to verify changes

After: Comprehensive Testing

• Tests for all code, no exceptions

• Unit tests for every function

• Integration tests for all modules

• LLMs run tests after every change

Example: Test-Driven Development with LLMs

Here’s how we work with LLMs and tests:

1

Write Test First

Ask LLM to write a test for the desired functionality. Test defines expected behavior, edge cases, error handling.

  • Test captures the precise interface and expected outputs
  • Edge cases documented upfront before implementation
  • Error scenarios defined as part of requirements
2

Run Test (Fails)

Run the test — it fails because implementation doesn't exist yet. This confirms the test is correct and meaningful.

  • Failing test validates that the test itself is accurate
  • Confirms the functionality is not yet implemented
  • Establishes a clear baseline to measure progress
3

Implement Feature

Ask LLM to implement the feature to make the test pass. LLM has clear guidance from the test about what to build.

  • LLM uses test as a specification for implementation
  • Implementation guided by explicit expected behavior
  • Reduces ambiguity and incorrect assumptions
4

Run Test (Passes)

Run the test again — it passes. LLM has successfully implemented the feature. All existing tests still pass (no regressions).

  • Passing test confirms correct implementation
  • Existing tests verify no regressions introduced
  • Feature is verified both functionally and structurally

Real Scenario: Refactoring with LLMs

Here’s a real scenario showing how these changes helped us work with LLMs — a multi-step refactoring that would have taken days, completed in hours:

1

Context

We needed to refactor an API client module to add retry logic and better error handling. The module was part of a larger monolith, had no tests, and documentation was in a PDF.

  • API client deeply embedded in monolithic codebase
  • No test coverage for existing functionality
  • Documentation only available as non-parseable PDF
  • Required cloud deployment to test any changes
old approach would not work with LLMs
2

Modular Project

API client was extracted into its own module. LLM could read all files and understand the complete context because the module was small enough.

  • Extracted module with clear boundaries and interfaces
  • All files visible within a single LLM context window
  • Own package.json with explicit dependencies
3

LLM-Friendly Docs

Documentation rewritten in Markdown with Mermaid diagrams. LLM could parse architecture and understand requirements without visual-only content.

  • Architecture diagrams converted to Mermaid code
  • API contracts documented as TypeScript interfaces
  • Requirements structured in parseable Markdown sections
4

Tests as Guardrails

Comprehensive test suite created. LLM could run tests after each change, verify correctness, catch regressions, and iterate quickly on local machine.

  • Unit tests for every function in the module
  • Integration tests for API client retry logic
  • All tests runnable locally in seconds
result
5

Successful Refactoring

LLM successfully refactored the module in hours instead of days. All tests passed, no regressions, code was cleaner and more maintainable.

  • Refactoring completed in hours, not days
  • All tests passed with zero regressions
  • Combination of modular structure, parseable docs, and tests made it possible

Additional Workflow Adjustments

Beyond the three key changes, we made additional adjustments to our workflow:

1. Code Organization

Flat File Structures

Avoid deeply nested directories. LLMs struggle with complex folder hierarchies. Prefer flat structures with clear naming conventions.

Single Responsibility Files

Each file should have one clear purpose. LLMs can understand single-purpose files better than multi-purpose files. Smaller, focused files are easier to modify.

Consistent Naming Conventions

Use consistent naming across the codebase. LLMs can infer patterns and generate code that matches existing conventions. Inconsistent naming confuses LLMs.

2. Documentation Standards

Inline Documentation

Document code inline with comments and JSDoc. LLMs can read inline docs while reading code, providing context without switching files.

README Files in Every Module

Every module has a README explaining what it does, how to run it, dependencies, and examples. LLMs can read READMEs to understand modules quickly.

Changelog for All Changes

Maintain changelogs in Markdown. LLMs can read changelogs to understand what changed, why, and when. Helps LLMs understand the evolution of code.

3. Development Environment

One-Command Setup

Each module can be set up with a single command: npm install && npm test. LLMs can verify setup works, run tests, and start working immediately.

No External Dependencies for Testing

Tests don’t require databases, APIs, or external services. Use mocks and fixtures. LLMs can run tests without complex infrastructure setup.

Fast Test Execution

Tests run quickly — seconds, not minutes. LLMs can iterate rapidly, running tests after each change. Slow tests break the feedback loop.

4. Version Control

Small, Focused Commits

Make small commits with clear messages. LLMs can understand commit history, see what changed, and generate appropriate commit messages.

Branch Naming Conventions

Use consistent branch naming. LLMs can understand branch purposes and generate appropriate branch names for new features.

PR Descriptions in Markdown

Write PR descriptions in Markdown with code examples and Mermaid diagrams. LLMs can read PRs to understand changes and provide feedback.

The Workflow Cycle: How Steps Feed Into Each Other

These changes create a feedback cycle where each step feeds into the next:

1

LLM Reads Documentation

LLM reads Markdown docs with Mermaid diagrams. Understands architecture, requirements, expected behavior. Gets context for what needs to be built.

  • Parses structured documentation formats (Markdown, YAML, TypeScript)
  • Reads Mermaid diagrams to understand system architecture
  • Builds mental model of requirements and constraints
2

LLM Reads Code in Module

LLM reads all files in the modular project. Understands complete context because module is small enough to fit in context window.

  • Entire module visible within a single context window
  • Sees existing patterns, conventions, and code structure
  • Identifies dependencies and interfaces between components
3

LLM Reads Tests

LLM reads test files to understand expected behavior, edge cases, error handling. Tests serve as executable documentation.

  • Tests define precisely how code should behave
  • Edge cases documented as explicit test scenarios
  • Error handling expectations captured in test assertions
4

LLM Generates Code

LLM generates code based on documentation, existing code patterns, and test requirements. Code follows conventions, matches architecture.

  • Code matches documented architecture and patterns
  • Implementation satisfies test requirements
  • Follows conventions observed in existing codebase
5

Tests Run Locally

Tests run immediately on local machine. Fast feedback — seconds, not minutes. LLM sees results right away, can iterate quickly.

  • Instant feedback loop with local test execution
  • No deployment or CI/CD wait times
  • LLM can iterate multiple times in rapid succession
6

Feedback Loop

If tests fail, LLM sees error messages, fixes code, runs tests again. If tests pass, LLM updates documentation if needed, then moves to next task.

  • Error messages guide targeted fixes
  • Documentation updated to reflect code changes
  • Cycle repeats for next feature or iteration
cycle continues: Documentation → Code → Tests → Feedback → Documentation

Feedback Cycles: How Information Flows

The workflow creates multiple feedback cycles that reinforce each other:

Cycle 1: Code ↔ Tests

1

Code to Tests

Code is written, tests verify it works. Tests catch bugs, verify behavior, prevent regressions.

  • Every code change validated by automated tests
  • Bugs caught immediately before they reach production
  • Regression tests prevent previously fixed issues from returning
2

Tests to Code

Tests define expected behavior. LLMs read tests to understand requirements, then write code to make tests pass. Tests guide implementation.

  • Tests serve as precise specifications for LLMs
  • Expected outputs clearly defined before code is written
  • Implementation driven by verifiable requirements
3

Continuous Feedback

When tests fail, error messages guide fixes. When tests pass, code is verified correct. Continuous feedback loop keeps code and tests aligned.

  • Error messages provide actionable guidance for fixes
  • Passing tests confirm correctness of implementation
  • Alignment maintained through every iteration

Cycle 2: Documentation ↔ Code

1

Documentation to Code

LLMs read documentation to understand architecture, requirements, patterns. Documentation guides code generation.

  • Architecture diagrams inform code structure decisions
  • Requirements documents define what to build
  • API specifications guide interface implementation
2

Code to Documentation

When code changes, documentation should update. LLMs can read code, understand changes, and update documentation to match.

  • Code changes trigger documentation reviews
  • LLMs generate updated Mermaid diagrams from new code
  • API docs updated to reflect interface changes
3

Continuous Alignment

If code doesn't match documentation, tests fail or code review catches it. Documentation and code stay aligned through continuous updates.

  • Tests validate that code matches documented behavior
  • Code reviews catch documentation drift
  • Continuous alignment reduces confusion and bugs

Cycle 3: Tests ↔ Documentation

1

Tests to Documentation

Tests are executable documentation. LLMs can read tests to understand behavior, then update documentation to match.

  • Test names describe expected behaviors
  • Test assertions define precise requirements
  • Test coverage maps directly to documented features
2

Documentation to Tests

Documentation describes expected behavior. LLMs can read documentation, understand requirements, and write tests that verify documented behavior.

  • Requirements become test scenarios
  • Architecture constraints verified through integration tests
  • Edge cases from documentation captured as test cases
3

Mutual Verification

If tests don't match documentation, something is wrong. Either tests are incorrect, or documentation is outdated. Feedback loop keeps them aligned.

  • Discrepancies flag either incorrect tests or outdated docs
  • Alignment verified through both automated and manual checks
  • Both artifacts evolve together, reinforcing accuracy

The Combined Cycle

These three cycles work together:

1

Documentation Describes Requirements

Documentation describes what needs to be built. LLM reads it, understands requirements, gets context for implementation.

  • Structured documentation provides clear, parseable requirements
  • Mermaid diagrams show system relationships and data flows
2

Tests Define Expected Behavior

Tests define how it should work. LLM reads tests, understands expected behavior, edge cases, and error handling.

  • Test cases serve as executable specifications
  • Edge cases and failure modes documented as assertions
3

Code Implements the Feature

LLM generates code based on documentation and tests. Implementation follows conventions and satisfies all requirements.

  • Code guided by both documentation context and test requirements
  • Follows patterns established in existing codebase
4

Tests Verify Correctness

Tests run, verify code works. If tests fail, feedback goes back to code (fix bugs) or documentation (clarify requirements).

  • Automated verification catches issues immediately
  • Failures traced back to either code defects or unclear requirements
5

Documentation Updates

Documentation updates if code behavior changes. Tests ensure documentation stays accurate. Each cycle reinforces the others.

  • Documentation evolves with the codebase
  • Tests prevent documentation from becoming stale
cycle repeats for every feature and iteration

The Constant: Structure for Understanding

Every benefit of reorganizing workflows for LLMs stems from one principle: structure your work so LLMs can understand it, verify it, and iterate on it. Modular projects provide context that fits in a single window. Code-based documentation provides information LLMs can parse. Comprehensive tests provide guardrails and instant feedback. Together, these three changes create a workflow where LLMs — and humans — can work effectively.

Benefits of the Reorganized Workflow

For LLMs

Can understand complete context, parse all documentation, verify changes with tests, and iterate quickly with instant feedback.

For Developers

Better code organization, comprehensive test coverage, up-to-date documentation, and faster development cycles.

For the Project

More maintainable codebase, better documentation, fewer bugs, and faster onboarding for new team members.

For Collaboration

Clear communication, shared understanding, consistent patterns, and better code reviews across the team.

Conclusion

Reorganizing workflows for LLMs doesn’t just help LLMs — it makes our entire development process better. Modular projects are easier to understand and maintain. LLM-friendly documentation is better documentation. Comprehensive tests catch bugs and document behavior.

The key insight: structure your work so LLMs can understand it, verify it, and iterate on it. Modular projects provide context. Code-based documentation provides parseable information. Tests provide guardrails and feedback.

These changes create feedback cycles where documentation, code, and tests reinforce each other. Each step feeds into the next, creating a workflow that works well for both humans and LLMs.

Don’t just use LLMs with your existing workflow. Reorganize your workflow to work with LLMs. The changes that help LLMs — modular projects, parseable documentation, comprehensive tests — also help humans. Everyone benefits.

If you’re struggling to get value from LLMs, consider reorganizing your workflow. Make projects modular. Write documentation in code-based formats. Add comprehensive tests. You might find that LLMs become much more useful — and your codebase becomes much better in the process.