Advent of AI - Day 10: Understanding Arguments in Goose Recipes

Advent of AI - Day 10: Understanding Arguments in Goose Recipes

7 minute read

I've edited this post, but AI helped. These are meant to be quick posts related to the Advent of AI. I don't have time if I'm doing one of these each day to spend a couple hours on a post.

The advent of AI series leverages Goose, an open source AI agent. If you've never heard of it, check it out!

The https://github.com/block/goose repository on GitHubOpenGraph image for https://github.com/block/goose

For Advent of AI Day 10, I built a festival poster generator using Goose recipes. Here’s my submission. But this post isn't really about making posters. It's about understanding how recipe arguments and conditional logic turn static prompts into reusable AI workflows.

Up until now in the Advent of AI challenges, I'd been using recipes pretty simply. Pass in some parameters, get output.

But Day 10 made me dig deeper into what's actually happening under the hood with arguments and I discovered you can leverage Jinja templating with recipe arguments (args).

The Problem I Was Solving permalink

The Day 10 challenge asks you to generate festival posters. Not just one poster, but posters for different event types. Food events need warm, cozy vibes. Kids events need bright, playful energy. Performance events need elegant styling.

Without parameters, you're writing separate prompts for each type. That's tedious and doesn't scale. With parameters and conditional logic, you write one recipe that handles all of them.

How Recipe Parameters Work permalink

Goose recipes let you define inputs just like function parameters. You specify what can change, and users provide those values when they run the recipe.

Here's the basic setup:


version: 1.0.0
title: Festival Poster Generator
description: Generate themed HTML posters with conditional styling

parameters:
  - key: event_name
    input_type: string
    requirement: required
    description: Name of the festival event

  - key: event_type
    input_type: select
    requirement: required
    description: Type of event - determines theme and styling
    options:
      - food
      - kids
      - performance
      - competition
      - workshop

  - key: tagline
    input_type: string
    requirement: optional
    description: Optional tagline or subtitle
    default: ""

Required vs Optional permalink

Required parameters are non-negotiable. You can't generate a poster without knowing the event name, date, location, and type. The recipe won't run if these are missing.

Optional parameters add flexibility. A tagline is nice to have, but if you don't provide one, the recipe still works. Setting default: "" means optional parameters become empty strings when not provided, which is perfect for conditional logic later.

Conditional Logic with Jinja permalink

This is where it gets really good. The instructions section of a recipe supports Jinja2 templating. That means you can write logic that changes what the AI actually sees based on the parameters you pass in.

For the poster generator, the entire styling instructions change based on event_type:


instructions: |
  You are a festival poster generator.
  
  **Event Details:**
  - Event Name: {{ event_name }}
  - Date & Time: {{ event_datetime }}
  - Location: {{ location }}
  - Event Type: {{ event_type }}
  {% if "tagline" %}- Tagline: {{ tagline }}{%  "endif" %}
  {% if "description" %}- Description: {{ description }}{%  "endif" %}
  
  {% if event_type == "food" %}
  ## Food Event Theme
  - Use warm, inviting colors (burgundy, warm orange, cream)
  - Typography: Friendly, rounded fonts
  - Mood: Cozy, appetizing, welcoming
  {%  "endif" %}
  
  {% if event_type == "kids" %}
  ## Kids Event Theme
  - Use bright, playful colors (rainbow palette, pastels)
  - Typography: Playful, bold, easy-to-read fonts
  - Mood: Fun, energetic, joyful
  {%  "endif" %}

Hot Cocoa Tasting poster

Same recipe, completely different instructions sent to the AI depending on what event_type you provide. That's the power of this approach.

Kids Storytelling poster

What This Actually Does permalink

When you run the recipe with event_type: food, the AI gets instructions about warm colors and cozy vibes. Run it with event_type: kids, and it gets instructions about bright colors and playful energy.

The AI doesn't see both sets of instructions. It only sees the one that matches your event type. That's way better than trying to cram all the logic into a single prompt and hoping the AI picks the right path.

Useful Jinja Patterns permalink

Variable Interpolation permalink

The basic `` syntax injects parameter values:


instructions: |
  Create a poster for {{ event_name }} on {{ event_datetime }}.

Conditional Blocks permalink

{% if "condition" %} lets you include or skip entire sections:


{% if "tagline" %}
Make the tagline prominent: {{ tagline }}
{%  "endif" %}

{% if not description %}
Since no description was provided, create a brief one.
{%  "endif" %}

I used this a lot for optional parameters. If someone provides a tagline, include it. If not, skip that section entirely.

String Manipulation permalink

Jinja filters let you transform values on the fly:


Save to: poster_{{ event_type }}_{{ event_name | lower | replace(" ", "_") }}.html

This converts "Hot Cocoa Tasting" to "hot_cocoa_tasting" automatically. Super useful for file names.

Combining Conditions permalink

You can get fancy with multiple conditions:


{% if event_type == "performance" and ticket_info %}
Display ticket info with elegant styling: {{ ticket_info }}
{% elif event_type == "kids" and not ticket_info %}
Add "Free admission - all families welcome!"
{%  "endif" %}

Why This Matters permalink

With parameters and conditional logic, you write once and reuse forever.

For the Day 10 challenge, I can generate posters for all the different festival events just by changing the parameters:


# CLI
goose run festival-poster-generator \
  --event_name "Hot Cocoa Tasting" \
  --event_datetime "December 15, 2pm–4pm" \
  --location "Main Plaza" \
  --event_type food

Want a kids event? Same recipe, different parameters:


goose run festival-poster-generator \
  --event_name "Storytelling Hour" \
  --event_datetime "December 17, 3pm–4pm" \
  --location "Story Tent" \
  --event_type kids

In Goose Desktop, you get a form UI with dropdowns for the event type and text inputs for everything else. Way nicer than typing command-line args.

The real win is consistency. All the posters follow the same structure and quality standards because they're coming from the same recipe. The only thing that changes is the data and the conditional styling.

Beyond Posters permalink

The Day 10 challenge is about posters, but these patterns work for any repetitive AI task.

I've been using Goose recipes for all sorts of stuff during Advent of AI:

  • Data transformation (Day 8: messy vendor data to structured JSON)
  • GitHub automation (Day 6: issue triage and labeling)
  • UI generation (Day 4: festival website with theme switching)

Each one follows the same pattern. Define what varies (parameters), write conditional logic for different paths (Jinja), run it as many times as you need.

For work at Pomerium, I could see this being useful for generating security policies or MCP server configurations with different auth providers and policy levels. Same recipe, different security postures based on parameters.

Things I Learned permalink

Start Simple permalink

Don't try to make everything configurable on day one. Figure out the 3-5 things that actually need to vary, make those parameters, and ship it. You can always add more later.

Use Select Types When You Can permalink

For the event type, I used input_type: select instead of a freeform string. This prevents typos and makes the conditional logic reliable. If someone can only pick from "food", "kids", "performance", etc., you don't have to worry about handling "Food" vs "food" vs "FOOD".

Provide Defaults for Optional Stuff permalink

For optional parameters, think about what makes sense when nothing is provided:


- key: output_format
  input_type: select
  requirement: optional
  default: html
  options:
    - html
    - markdown

Most people probably want HTML, so default to that.

Test All the Paths permalink

With conditional logic, you're creating multiple execution paths. I made sure to test:

  • All five event types to confirm each conditional branch works
  • Optional parameters both provided and omitted
  • Edge cases like really long event names

Check the Docs permalink

The Recipe Parameters docs list all the input types and validation options. Reference these when you're setting up parameters instead of guessing.

Reference Docs permalink

Everything here is documented officially:

I referenced these docs a lot while building the poster recipe.

Wrapping Up permalink

Parameters and conditional logic turn recipes from one-off tools into reusable workflows.

Instead of "make me a poster", it becomes "here's a poster recipe that adapts based on what you need". Run it once, run it a hundred times, same quality every time.

The Advent of AI Day 10 challenge is a good intro to these concepts. You get to see how the same recipe generates five completely different poster themes just by changing one parameter. But the real learning is recognizing when you could apply this pattern to your own work.

What repetitive tasks are you doing with AI right now? Recipes are probably a good candidate for those kinds of tasks/workflows.

Check out the Day 10 challenge if you want to try building one yourself.

If you want to stay in touch, all my socials are on nickyt.online.

Until the next one!


Resources:

Photo by Sven Mieke on Unsplash