
Weekend Challenge: Haiku
One Python file. Amazon Bedrock. A small model. No web app, no background processes, and absolutely no follow-up questions.
Most AI tools are built to keep you engaged. They offer suggestions, generate alternatives, remember context, and invite you to keep going. Every interaction opens the door to another.
I wanted to build something that did the opposite.
An agent that takes a single word, writes a haiku, and stops.
No second verse. No menu of alternatives. No “Would you like another?” Just three lines of poetry, followed by silence.
I call it a small experiment in restraint: a tool for people who want less software between themselves and a moment of thought.
What I built
The idea is deliberately simple. You give the agent a topic, and it returns a haiku inspired by that word.
For example:
1
python haiku.py the sea
The output:
1
2
3
Grey waves fold and fall
a gull writes one line of foam
then the tide erases
That is the entire interaction.
The agent does not explain its choices, suggest related topics, or offer to generate another poem. It completes the task and exits.
I imagined using it in the pause between two tasks, before writing a difficult email, or whenever a noisy day could use a small, quiet interruption. It is not designed to appeal to everyone. It is designed for the person who appreciates a tool that knows when to stop.
How I built it
The entire application lives in one file:
haiku.py.It uses Python and Amazon Bedrock, with Amazon Nova Lite as the language model. The AWS integration uses
boto3, which handles communication with Bedrock using the user's existing AWS credentials.There is no web framework, frontend, server, deployment pipeline, or infrastructure stack to maintain. Nothing runs in the background between requests.
The workflow is straightforward:
- Accept a topic from the command line.
- Send the topic to Amazon Bedrock with instructions to produce a three-line haiku following the traditional 5–7–5 syllable pattern.
- Extract the generated text.
- Print the three lines to the terminal.
- Exit.
The implementation is intentionally small. There is no elaborate agent orchestration, tool-calling loop, or multi-step reasoning pipeline. For a task this narrow, those abstractions would add complexity without adding much value.
Nova Lite was a deliberate choice. A short poem does not require the largest available model. I wanted a model that was lightweight, responsive, and economical for a single-turn interaction.
The goal was not to demonstrate how much infrastructure I could assemble. It was to find the smallest setup that could do the job.
The entire AWS footprint
The application depends on two things:
- Amazon Bedrock: One model-conversation call per poem.
- boto3 and AWS credentials: The Python SDK and the user's existing authentication setup.
On the first run, the script asks for an AWS region and remembers that choice locally. Subsequent runs reuse it instead of asking again.
To forget the saved region, delete the configuration directory:
1
rm -rf ~/.haiku-null
That is the only local configuration the application needs to retain. The generated poems are not saved by the application.
The cost model is equally simple. Each poem requires a model invocation, so the variable cost depends on the model's pricing and the tokens processed. For short requests and responses, the expected cost is small, though the exact amount depends on usage and current AWS pricing.
When the script is not running, it makes no model calls. There is no continuously running application to pay for.
That last point matters to me. A command-line tool that runs only when invoked can have a much smaller operational footprint than a web application that needs hosting and ongoing maintenance.
The delightful detail is restraint
The most important feature is not the model or the AWS integration. It is the decision to stop.
The agent could explain the sea. It could produce five variations. It could ask whether I preferred something melancholy, playful, or meditative.
It does none of those things.
You ask for the sea. It gives you a haiku about the sea. Then the terminal returns to its ordinary state.
That restraint shapes the entire design. The application does not need conversation history because it is not having a conversation. It does not need persistent storage because the poem is meant to be temporary. It does not need a web interface because the terminal is already enough.
Even error handling follows the same principle. Missing credentials should produce a concise message explaining what needs to be configured. Missing model access should identify the relevant permission or access issue. The aim is to avoid dumping an unnecessarily intimidating traceback on the user for an expected configuration problem.
A quiet tool should fail clearly, too.
How I knew it worked
My test was not a dashboard or an engagement metric.
I asked for “rain.” The agent returned three lines. I read them twice.
Then I wanted another.
I asked for “winter.” Again, three lines. Again, silence.
I tried a third topic.
That small impulse to return to the terminal was the most interesting part of the experiment. The application had done its job without trying to manufacture a longer session.
This is a subjective test, not a formal evaluation of poetry quality or syllable accuracy. A language model can miscount syllables, and a three-line output does not automatically make a poem a valid 5–7–5 haiku. Those constraints need to be checked if strict adherence is important.
But as a test of the interaction itself, the experience worked for me. I wanted to use the tool again because of what it gave me, not because it prompted me to continue.
What I learned
Building something small is not necessarily easier than building something large.
Large applications can hide questionable decisions behind additional features. A tiny application puts every decision in plain sight. Every dependency, configuration option, and extra line of output has to justify its existence.
I kept encountering tempting additions:
- A save option for poems.
- A choice of poetic styles.
- A web interface.
- A history of previous generations.
- A follow-up prompt to encourage another request.
Each feature was plausible. None was necessary for the original idea.
Saying no became the central engineering task.
I also came away with a useful reminder about managed AI services: not every application needs a complex architecture to make a model useful. Sometimes a short prompt, one API call, and a well-defined stopping point are enough.
There is an important distinction here, too. The model generates the poem; the Python script controls the interaction. The decision to stop is enforced by the application rather than left to the model's discretion. That makes the behavior simple, predictable, and easy to maintain.
Finally, I liked the economics of the design. Usage-based inference means the application makes no model requests when nobody is using it. With no always-on server or background worker, there is also no application compute running between invocations. Actual AWS costs still depend on the account, model pricing, and any other configured services, but the architecture keeps the recurring footprint small.
Why these choices matter
Every technical decision supports the same principle.
Nova Lite instead of a larger model: The task is narrow, and a smaller model is a reasonable starting point for balancing latency and cost against output quality.
A CLI instead of a web app: The terminal is enough to accept one word and display three lines. A frontend would introduce additional work without improving the core interaction.
No poem history: The experience is intentionally temporary. The application does not need to turn every output into a record.
One model call: There is no need for an agent loop when the task has a clear input, a clear output, and a clear stopping condition.
Minimal configuration: Remembering the AWS region removes one repeated question without creating a larger settings system.
Individually, these are ordinary engineering choices. Together, they create a product with a distinct character.
The restraint is not just a description of the interface. It is an architectural constraint.
Try it yourself
The repository link and a terminal screenshot will be added here when available.

Repository: https://github.com/sus19mondal/haiku
The basic setup is:
1
2
pip install -r requirements.txt
python haiku.py the sea
You will need Python, valid AWS credentials, access to Amazon Bedrock, and permission to invoke the selected model in your chosen region.
There is no application deployment step. Clone the repository, configure your AWS access, run the script, and give it a word.
One practical caveat: the exact setup commands and configuration behavior depend on the implementation in
haiku.py and requirements.txt. The commands above reflect the intended usage and should be verified against the published repository before release.A small thing that knows when it is done
I built this agent because I wanted to explore a different idea of usefulness.
Not every tool needs to become a platform. Not every interaction needs a second step. Not every blank space needs to be filled.
Sometimes, a tool can be useful precisely because it does one thing and gets out of the way.
One word in. Three lines out.
Then silence.
And, for this particular little agent, that is enough.
Enjoyed reading this content? Let the author know!
Your likes, comments, shares, and saves help creators reach more builders.
Loading recommendations
Loading article