documentation/docs/tutorials/subagents.md
This tutorial walks you through how to spin up a team of AI subagents and guide them through building a fully functional app.
You'll build AI BriefMe, an app that generates a structured executive style briefing based on any topic.
You'll use goose to orchestrate a full software team of subagents:
By the end of the session, you'll have a working prototype and a clear understanding of how to use AI agents for realistic workflows.
Create apps in html, javascript, and css when possible.
NEVER run blocking server commands (node server.js, npm start, etc.) - provide commands for user to run separately.
You'll be building an AI-powered briefing app by spinning up a team of subagents to help you. Each agent has a clear role. Your job is to figure out how to prompt goose to delegate the work.
π If you get stuck, you can peek to the prompts for examples.
Have the Planner define the product vision and scope. The Planner should decide:
This output should be a clear product definition, not code.
<details> <summary>Planner Agent Prompt</summary>You're the Planner agent for a hands-on AI app building session using goose and subagents. We are building the MVP *right now*.
The app is called **AI BriefMe**. It generates a daily briefing on any given topic. A user inputs a topic like βApple earningsβ or βAI in DevOps,β and the app returns:
- A title
- Today's date
- 2β3 bullet-point takeaways
- (Optional) a code snippet or chart, if the topic is technical
You're working with a team of subagents β PM, Architect, Frontend Dev, Backend Dev, QA, and Tech Writer β who will immediately begin executing your plan.
Write a short, focused **Markdown file (`plan.md`)** that outlines:
- The goals of the MVP
- Only the features that can be built in a 40 minute session
- Any helpful design considerations
β
DO: Keep it lean and actionable
β DON'T: Include long-term features like email delivery, user accounts, dashboards, analytics, personalization, mobile optimization, or 8-week timelines
Ask the Project Manager to break the product down into development tasks. The output should:
You're the PM agent. A Planner has just created `plan.md` for a 1-hour build session of an app called "AI BriefMe."
Your job is to:
- Break the work into tasks for each subagent: Architect, Backend Dev, Frontend Dev, QA, Tech Writer
- Group tasks by agent
- Decide what work can be done in parallel vs what must be sequential
- Output the task breakdown in Markdown and save it as `project_board.md`
Be realistic and concise β this is a sprint, not a roadmap.
Have the Architect plan the technical setup. They should:
You are the Architect. Based on the project plan and `project_board.md`, set up the project scaffolding.
Do the following:
- Create the folder structure and all placeholder files (e.g. `index.html`, `server.js`, `style.css`, etc.)
- Generate a `package.json` file that includes `express`, `cors`, and `child_process` as dependencies
- Add a `.gitignore` that excludes `node_modules` and any temporary files
- Define the API contract for the `/api/briefing` endpoint in Markdown
β
Do NOT include or reference any API keys
β
Do NOT install packages β just scaffold the structure
β
DO list the output files and folders at the end
Spin up two developer subagents in parallel to build the core app. One will handle the Express server and backend logic, the other will build the UI and wire up the form. goose should execute both agents at the same time, not one after the other.
Use **parallel execution** to run two subagents:
- A π οΈ Backend Developer
- A π» Frontend Developer
Both should work simultaneously β not sequentially β to build the AI BriefMe MVP.
π οΈ **Backend Developer** should:
- Implement `server.js` with Express
- Add POST `/api/briefing` endpoint accepting `{ "topic": "string" }`
- Use **Headless goose** to generate the summary:
- `goose run -t "YOUR_PROMPT_HERE" --quiet --no-session --max-turns 1`
- Use `child_process.spawn()` instead of `exec()`
- Clean response: remove ANSI codes, markdown blocks, and extract JSON
- Handle timeouts (max 60s) and errors
- Serve frontend files from `express.static`
- Add CORS
- Do not require any API keys
π» **Frontend Developer** should:
- Create `index.html`, `style.css`, and `script.js`
- Build a form for entering a topic
- Call the `/api/briefing` endpoint and display the result
- Handle loading states and errors
- Include a copy-to-clipboard button
- Make it mobile-friendly
- Do not interfere with backend files
β οΈ Important: These agents must not write to the same files. Keep their work isolated.
Now that development is done, spin up two final subagents: a QA Engineer and a Tech Writer. They'll work together to assess the app's quality and document how to use it. Your job is to prompt goose in a way that gets both agents to collaborate without overlapping or duplicating work.
/api/briefing endpoint using a framework like JestQA_NOTES.md file:
README.md file with:
β οΈ Important:
The development phase is complete. Now it's time for quality assurance and documentation.
Use **parallel execution** to run two subagents simultaneously:
- π§ͺ A **QA Agent** who will:
- Write a unit test for the `/api/briefing` endpoint in `tests/briefing.test.js` using Jest
- **Mock the child_process module** using `jest.mock('child_process')` at the top of the test file
- Create a simple mock that returns fake data instead of calling the real goose CLI
- Assert that the response includes: `title`, `date`, and 2β3 `takeaways`
- Include tests for:
- Valid topic input
- Missing or invalid input
- goose CLI timeout or error
- **Do not start or run the server manually.** Only write test files.
- **Do not execute `npm test` or run any tests.** Only create the test file.
- Save a full QA analysis report in `QA_NOTES.md` with:
- Critical issues
- Security or performance gaps
- Recommendations for production readiness
- **When all files are created, immediately state: "QA Agent Sign-off: β
COMPLETE" and finish.**
- π A **Tech Writer Agent** who will:
- Create a `README.md` that includes:
- Project overview
- How to run the app locally
- API endpoint documentation
- Example request/response
- Troubleshooting section
- **When documentation is complete, immediately state: "Tech Writer Sign-off: β
COMPLETE" and finish.**
Both agents should work in parallel, not sequentially.
Once all agents complete their work, you should have a working prototype. Here's how to see it in action:
cd your-project-folder
npm install
Important: Run this in a separate terminal window (not in goose):
npm start
You should see:
AI BriefMe server running on port 3000
Health check: http://localhost:3000/health
Briefing endpoint: http://localhost:3000/api/briefing
Open your browser and go to:
http://localhost:3000/
Note: Use the root URL (/), not /ai-briefme/
You should see:
:::tip Keep the Server Running
Ctrl+C in the server terminalCongratulations! You've built a full-stack AI app using goose subagents! π
:::warning Don't expect your app to be production ready. This workshop shows how vibe coding with goose can accelerate prototyping, but the human still owns the judgment and polish. :::
Cause: Route not registered or server not restarted Solutions:
node server.jscurl -X POST http://localhost:3000/api/briefing -H "Content-Type: application/json" -d '{"topic":"test"}'
Cause: Frontend receiving HTML instead of JSON (usually a 404 page) Solutions:
curl -X POST http://localhost:3000/api/briefing -H "Content-Type: application/json" -d '{"topic":"test"}'
http://localhost:3000/ not /ai-briefme/Cause: goose taking too long or hanging Solutions:
['run', '-t', prompt, '--quiet', '--no-session', '--max-turns', '1']
goose run -t "Return JSON: {\"test\": \"value\"}" --quiet --no-session --max-turns 1
Cause: goose returns formatted output with color codes Solutions:
// Remove ANSI color codes
jsonString = jsonString.replace(/\x1b\[[0-9;]*m/g, '');
// Remove markdown formatting
jsonString = jsonString.replace(/```json\s*/, '').replace(/```\s*$/, '');
jsonString = jsonString.replace(/```\s*/, '');
console.log('Raw goose response:', aiResponse);
console.log('Cleaned JSON string:', jsonString);
Solutions:
lsof -ti:3000
lsof -ti:3000 | xargs kill -9
const PORT = process.env.PORT || 3001;
Solutions:
http://localhost:3000/ (not /ai-briefme/)app.use(express.static(__dirname));
http://localhost:3000/index.htmlhttp://localhost:3000/style.csshttp://localhost:3000/script.js