Pseudocode Spec for AI Agents

Disclaimer: I write this myself without any AI/LLM, except the part that I explicitly mention that AI/LLM was used for codegen

When we ask AI agents to write an implementation, we typically give one of three things: prose, code example, or a combination of both.

Prose is ambiguous. “Normalize the phone number to Indonesian format” leaves a thousand implementation questions unanswered. Existing source code is precise, but it’s also verbose, language-specific, and front-loads irrelevant detail (error handling boilerplate, type declarations, import statements) before the agent ever reaches the logic that actually matters.

I figured that there’s an alternative kind of documentation that’s more optimized for the context of software development with AI. This acts as a precise specification that’s language agnostic and compressed, optimal for token consumption and you can store it on your personal documentation. This is even more beneficial for experienced engineers that curates their own documentation in order to achieve high code quality despite not having to write as much code.

I compressed this code from 116 lines to 17 lines. This is an implementation of WAHA

Example (This code is LLM generated using a specification that I explained below):

CONFIG baseURL, apiKey, session # Check from environment values or other previously set variable

PIPE SendOTP(phone, code)
  phone
  -> digitsOnly
  -> if startsWith "0" replacePrefix "0" -> "62"
  -> else if startsWith "8" prefix "62"
  -> else keep
  -> append "@c.us"
  -> POST {baseURL}/api/sendText
       headers {Content-Type:json, Accept:json, X-Api-Key:apiKey}
       body {
         chatId: $
         text: "*<APP_NAME>*\n\nKode OTP Anda adalah: *{code}*\n\nKode ini berlaku selama 5 menit.\nJangan bagikan kode ini kepada siapapun."
         session: session
       }
  -> success if status in {200,201} else error

CONFIG means external dependencies (values, function, environment variables, etc). PIPE means the data pipeline, how data is transformed through certain steps. The CONFIG, PIPE term does not matter. The symbol ‘ is result of previous pipeline (in this example case, a normalized phone number. This also can be a variable name, for example ‘normalizedPhoneWithAtCDotUs’, no need to overthink this. The agent knows whatever you write.

original code of pkg/waha/client.go (LLM generated)

package waha

import (
    "bytes"
    "context"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "strings"
    "time"
)

type Client struct {
    baseURL    string
    apiKey     string
    session    string
    httpClient *http.Client
}

type SendTextRequest struct {
    ChatID  string `json:"chatId"`
    Text    string `json:"text"`
    Session string `json:"session"`
}

type SendTextResponse struct {
    ID        string `json:"id"`
    Timestamp int64  `json:"timestamp"`
}

func NewClient(baseURL, apiKey, session string) *Client {
    return &Client{
        baseURL: strings.TrimSuffix(baseURL, "/"),
        apiKey:  apiKey,
        session: session,
        httpClient: &http.Client{
            Timeout: 30 * time.Second,
        },
    }
}

// NormalizePhone normalizes a phone number to a consistent format (e.g. 6285281812202).
// Handles: "085281812202", "8528181202", "+62 85281812202", "6285281812202"
// All produce: "6285281812202"
func NormalizePhone(phone string) string {
    // Remove all non-digit characters
    cleaned := ""
    for _, ch := range phone {
        if ch >= '0' && ch <= '9' {
            cleaned += string(ch)
        }
    }

    // Handle Indonesian numbers
    if strings.HasPrefix(cleaned, "0") {
        cleaned = "62" + cleaned[1:]
    } else if strings.HasPrefix(cleaned, "62") {
        // Already has country code
    } else if strings.HasPrefix(cleaned, "8") {
        cleaned = "62" + cleaned
    }

    return cleaned
}

// FormatPhoneNumber converts a phone number to WhatsApp chat ID format
// Input: +62 085281812202 or 085281812202 or 62085281812202
// Output: 6285281812202@c.us
func FormatPhoneNumber(phone string) string {
    return NormalizePhone(phone) + "@c.us"
}

// SendOTP sends an OTP code via WhatsApp
func (c *Client) SendOTP(ctx context.Context, phone string, code string) error {
    chatID := FormatPhoneNumber(phone)
    message := fmt.Sprintf("*Washaholic*\n\nKode OTP Anda adalah: *%s*\n\nKode ini berlaku selama 5 menit.\nJangan bagikan kode ini kepada siapapun.", code)

    return c.SendText(ctx, chatID, message)
}

// SendText sends a text message via WhatsApp
func (c *Client) SendText(ctx context.Context, chatID, text string) error {
    reqBody := SendTextRequest{
        ChatID:  chatID,
        Text:    text,
        Session: c.session,
    }

    jsonBody, err := json.Marshal(reqBody)
    if err != nil {
        return fmt.Errorf("failed to marshal request: %w", err)
    }

    req, err := http.NewRequestWithContext(ctx, "POST", c.baseURL+"/api/sendText", bytes.NewBuffer(jsonBody))
    if err != nil {
        return fmt.Errorf("failed to create request: %w", err)
    }

    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("Accept", "application/json")
    req.Header.Set("X-Api-Key", c.apiKey)

    resp, err := c.httpClient.Do(req)
    if err != nil {
        return fmt.Errorf("failed to send request: %w", err)
    }
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
        body, _ := io.ReadAll(resp.Body)
        return fmt.Errorf("WAHA API error: status=%d body=%s", resp.StatusCode, string(body))
    }

    return nil
}

LLM already knows how to code using go, typescript, etc. No need to fully feed the LLM with verbose language. Now a simple snippet can direct your LLM faster and just as precise.