{
"path": "/posts/2025/goose-as-a-task-runner",
"site": "at://did:plc:mracrip6qu3vw46nbewg44sm/site.standard.publication/self",
"tags": [
"goose",
"language_models"
],
"$type": "site.standard.document",
"title": "Goose as a Task Runner",
"updatedAt": "2025-07-19T02:41:27.000Z",
"publishedAt": "2025-03-01T02:41:27.000Z",
"textContent": "Goose is a CLI language model-based agent.\nGoose exposes a chat interface and uses tool calling (mostly to invoke shell commands) to accomplish the objective prompted by the user.\nThese tasks can include everything from writing code to running tests to converting a folder full of mov files to mp4s.\nMost things you can do with your computer, Goose can do with your computer.\n\nGoose runs most commands by default.\nSome other tools call this \"YOLO mode\".\nIf this approach concerns you, you may want to prompt Goose to let you know before it runs commands (this approach does not substitute for running the tool in an isolated/containerized environment).\nYou ultimately never know what an LLM-based tool will actually run when given access to your system.\n\nGoose hints\n\nWhen you start Goose, it will check for a .goosehints file in the current directory (docs).\nIf it finds one, it will use the hints in that file to guide its behavior.\nThe instructions will be appended to the system prompt that Goose is provided.\n\nHere's an example file:\n\nNow, when can start Goose and say \"hi\", it will read the file and respond to my prompt.\n\nGoose as a task runner\n\nBecause a .goosehints file can contain any natural language instructions, we can also use it to define useful tasks that might benefit from a language model-based agent execution flow, like idea generation, summarization, or structured data extraction.\n\nHere's an example of a .goosehints file that uses Goose to generate summaries of content from my blog.\nIt provides the description of a _hypothetical_ summary command and a few _hypothetical_ options for creating summaries across my post types and over different time periods.\nIt also prompts for citations from the original content from which the summaries are derived.\n\nI'm emphasizing the _hypothetical_ part because we're not actually going to implement this /summary command with code.\nWe're going to have Goose use this specification as instructions which it will carry out, allowing the language model to run commands to do it.\n\nHere's the file:\n\n/summary logs 2020-02\n\n/summary all -3m\n\n/summary all -3w\n/summary all -1y\nmd\n... 2025-02-28 ...\nmd\nI learned more about Astro and build a new website ...\n\nNow, I can run Goose and generate a summary of my logs posts in February 2025 like this:\n\nGoose first reads the .goosehints file and then plans and executes a series of shell commands to find the appropriate files, load them into context, generate the summary, and write it to a file in the location and with the naming convention specified.\n\nAfter running the command above, Goose wrote a file out to content/summary/logs/2025-02.md with a pretty reasonable summary.\n\nThat's a lot of tokens\n\nWhile the above command works well in my experience, it can use a lot more tokens than is really necessary as Goose navigates the filesystem, builds a context window, generates the summary, and writes it to a file.\nMost of these steps don't _need_ to be executed by Goose.\nWe can write a deterministic script that builds the context from the types of posts and window of time we specify, then _just_ prompt an LLM to summarize.\n\nI had the LLM write a script for this.\nCompared to the ~50 lines in my sparse .goosehints file, the script is almost 300 lines of Python.\n\nThis is obviously not an apples-to-apples comparison.\nThe script is deterministic (except for the LLM summary), far more efficient, and less prone to random failures of the LLM agent.\nHowever, the .goosehints file is more flexible, easier to understand, and easier to read.\n\nI believe there is room and value in both approaches.\n\nLanguage vs Code\n\nThe ability to write a quick instruction set and have an agent execute it in steps is powerful and distinctly its own thing compared to what long-time engineers are used to.\nOnce an idea has been translated into code, edges need to be dealt with, compilers and interpreters satisfied.\nCode necessarily imposes limiting constraints on the developer.\nWe want and need our programs to be correct.\nTo accomplish this, we need to handle failure modes and edge cases.\n\nNatural language is more flexible and squishy compared to code.\nThere is more room for interpretation at inference time.\nAny validation (like does the program compile/run) is done at runtime.\nNatural language allows for faster iteration but, in practice, can produce unpredictable results.\n\nWhile (orders of magnitude more) inefficient compared to the typical way you'd perform this task, I was still impressed with the results of the /summary command from my .goosehints file.\nThe execution became an implementation detail dealt with by the model once the spec was written.\nThe prose and documentation are clearer than the Python and shell equivalents I wrote, especially for a non-technical reader.\nIt's also trivial to extend - I just write the document of the new feature and Goose and the model do the rest.\n\nGoose and other LLM-based tools make it easy and fast to extend a script version of the summary command, but the way you do that is by writing the spec or description of what you want.\nThis is all you do when creating a \"command\" in a .goosehints` file.\n\nYou could argue that natural language instructions, executed by an agent, are like an interpreted language whereas an already-written script is closer to a compiled language because the language tools and runtime impose constraints and invariants on the behavior of the program.\nIt's possible to reason about what the behavior of the latter will be at runtime, but the former can still be useful.",
"canonicalUrl": "https://www.danielcorin.com/posts/2025/goose-as-a-task-runner"
}