RUNLOCALAIv38
->Will it run?Best GPUCompareTroubleshootStartLearnPulseModelsHardwareToolsBench
Run check
RUNLOCALAI

Independently operated catalog for local-AI hardware and software. Hand-written verdicts. Source-cited claims. Reproducible commands when we have them.

OP·Eruo Fredoline
DIR
  • Models
  • Hardware
  • Tools
  • Benchmarks
TOOLS
  • Will it run?
  • Compare hardware
  • Cost vs cloud
  • Choose my GPU
  • Prompting kits
  • Quick answers
REF
  • All buyer guides
  • Learn local AI
  • Methodology
  • Glossary
  • Errors KB
  • Trust
EDITOR
  • About
  • Author
  • How we make money
  • Editorial policy
  • Contact
LEGAL
  • Privacy
  • Terms
  • Sitemap
MAIL · MONTHLY DIGEST
Get monthly local AI changes
Monthly recap. No spam.
DISCLOSURE

Some links on this site are affiliate links (Amazon Associates and other first-class retailers). When you buy through them, we earn a small commission at no extra cost to you. Affiliate links do not influence our verdicts — there are cards we rate highly that we don't have affiliate relationships with, and cards that sell well that we refuse to recommend. Read more →

© 2026 runlocalai.coIndependently operated
RUNLOCALAI · v38
  1. >
  2. Home
  3. /Learn
  4. /Courses
  5. /Custom Agent Frameworks
  6. /Ch. 20
Custom Agent Frameworks

20. Documentation

Chapter 20 of 24 · 20 min
KEY INSIGHT

Documentation is a liability, not an asset. Every sentence you write must be maintained. Write less, but write things that can't get out of date—like code with type annotations, or decision records that explain intent.

Documentation is a lie you tell yourself: "I'll document it later." Later never comes. Document as you build, or accept that your knowledge will be lost.

Code-Level Documentation

Every public interface needs docstrings that answer: what, why, and how:

class MessageRouter:
    """
    Routes messages to registered handlers based on message type.
    
    The router maintains a registry of handlers keyed by message type.
    When a message arrives, the router dispatches it to the appropriate
    handler based on exact type matching.
    
    Thread Safety:
        This class is NOT thread-safe. Use with a single event loop
        or wrap dispatch in asyncio.Lock if multithreaded access needed.
    
    Example:
        >>> router = MessageRouter()
        >>> router.register("greeting", handle_greeting)
        >>> await router.route({"type": "greeting", "content": "hi"})
    """
    
    def __init__(self):
        self._handlers: dict[str, Callable] = {}

API Documentation

Generate API docs from code, don't maintain them separately:

## AgentRegistry.find_by_capability(capability)

**Parameters:**
- `capability` (str): The capability to search for (e.g., "text-generation")

**Returns:**
- `list[AgentRegistration]`: All agents that have the requested capability and have sent a heartbeat within the TTL window.

**Raises:**
- Nothing. Returns empty list if no matching agents found.

**Note:**
This method filters out agents that have missed heartbeats, ensuring
you don't route to agents that have crashed or become unreachable.

Architecture Decision Records

Document why decisions were made, not just what was built:

# ADR-012: Message Serialization Format

## Status
Accepted

## Context
We need a serialization format for agent messages that survives process 
restarts and can be read by monitoring tools.

## Decision
We will use JSON for message serialization, not pickle or protocol buffers.

## Consequences

### Positive
- Human-readable for debugging
- Compatible across Python versions
- No compilation step needed

### Negative
- Larger message sizes than binary formats
- No schema enforcement (runtime validation needed)
- Slower serialization than msgpack
EXERCISE

Document an existing agent's interfaces using the patterns above. Identify places where the code contradicts the documentation or where documentation would become stale quickly.

← Chapter 19
Benchmarking
Chapter 21 →
Package Distribution