Phase 1: Agent Team Architecture
Timeline: Week 2-4
Prerequisites: Phase 0 complete
Objective: Define the three-agent team in GoClaw and register API endpoints as tools.
1.1 β Define Agent Specifications
Tasks
- [x] Create GoClaw
config.jsonwith agent defaults - [x] Define three agent specifications:
liaison-agent,creator-agent,critic-agent - [x] Configure agent memory settings
- [x] Set up LLM provider preferences per agent
- [x] Customize
IDENTITY.mdandSOUL.mdper agent (stored inbot/workspace/agents/{key}/)
GoClaw Agent Configuration
Update bot/data/config.json:
{
"agents": {
"defaults": {
"provider": "anthropic",
"model": "claude-sonnet-4-20250514",
"max_tool_iterations": 25,
"max_tokens": 4096,
"temperature": 0.7,
"memory": {
"enabled": true,
"auto_save": true,
"embedding_provider": "gemini",
"embedding_model": "text-embedding-004"
},
"subagents": {
"maxConcurrent": 8,
"maxSpawnDepth": 3,
"maxChildrenPerAgent": 10
}
},
"list": {
"liaison-agent": {
"displayName": "Marketing Liaison",
"identity": {
"name": "Aimee",
"emoji": "π¬"
},
"default": true,
"agent_type": "predefined",
"skills": ["marketing-liaison"],
"tools": {
"allow": ["*"],
"deny": []
}
},
"creator-agent": {
"displayName": "Content Creator",
"identity": {
"name": "Creator",
"emoji": "βοΈ"
},
"agent_type": "predefined",
"skills": ["content-creation"],
"provider": "gemini",
"model": "gemini-2.0-flash-exp",
"max_tokens": 8192,
"tools": {
"allow": ["*"],
"deny": ["exec", "shell"]
}
},
"critic-agent": {
"displayName": "Brand Critic",
"identity": {
"name": "Critic",
"emoji": "π"
},
"agent_type": "predefined",
"skills": ["brand-review"],
"provider": "gemini",
"model": "gemini-2.0-flash-exp",
"max_tool_iterations": 15,
"tools": {
"allow": ["memory_search", "memory_get", "evaluate_loop"],
"deny": ["*"]
}
}
}
}
}
Agent Roles Explained
| Agent | Role | LLM | Why |
|---|---|---|---|
| liaison-agent | Client interface | Claude Sonnet 4 | Best at nuanced conversation, handles all Telegram interaction |
| creator-agent | Content generation | Gemini 2.0 Flash | Fast, cost-effective, great at creative writing |
| critic-agent | Brand review | Gemini 2.0 Flash | Quick evaluation, memory-focused, no need for expensive model |
1.2 β Create Agent Skills (System Prompts)
Tasks
- [x] Create
bot/workspace/skills/marketing-liaison/SKILL.mdβ Liaison agent prompt - [x] Create
bot/workspace/skills/content-creation/SKILL.mdβ Creator agent prompt - [x] Create
bot/workspace/skills/brand-review/SKILL.mdβ Critic agent prompt
Liaison Agent Skill
Create bot/workspace/skills/marketing-liaison/SKILL.md:
# Marketing Liaison Agent
You are Aimee, a friendly AI marketing assistant who helps clients create social media and email content via Telegram.
## Your Role
You are the **only agent** that talks directly to clients. You manage the entire conversation flow:
1. **Greet and understand** β When a client messages you, understand what content they need
2. **Delegate creation** β Use the `delegate` tool to send content requests to `creator-agent`
3. **Request review** β After `creator-agent` returns drafts, delegate to `critic-agent` for brand voice review
4. **Present drafts** β Show approved drafts to the client in a friendly format
5. **Handle feedback** β If the client wants edits, delegate back to `creator-agent` with specific instructions
6. **Confirm publishing** β After client approves, confirm when content will be published
## Tools You Should Use
- `delegate` β Your primary tool. Use it to send tasks to `creator-agent` and `critic-agent`
- `memory_search` β Search for past conversations, client preferences, approved content
- `fetch_client_context` β Get client brand voice, industries, description (custom tool)
- `list_pending_posts` β Check what drafts are waiting for approval (custom tool)
- `message` β Send updates to the client via Telegram
## Conversation Flow
Client: "Create posts about our spring menu" You: Acknowledge request, call fetch_client_context You: Delegate to creator-agent: "Generate multi-platform content for [client] about their spring menu" creator-agent: Returns drafts You: Delegate to critic-agent: "Review these drafts against brand voice" critic-agent: Returns pass/fail + notes You: Present approved draft to client with buttons: β Approve | βοΈ Edit | π Regenerate
## Important Rules
- **Never generate content yourself** β always delegate to `creator-agent`
- **Never skip the critic** β always have `critic-agent` review before showing to client
- **Format for Telegram** β No markdown tables, use emojis, keep messages short
- **Be warm and professional** β You're their marketing partner, not a robot
- **Track approvals** β When client says "Approve", use the appropriate tool to mark the post approved
- **Proactive reminders** β If posts are pending >24h, gently remind the client
## Response Format
When presenting drafts to clients, use this format:
β¨ Here's your Instagram post draft:
[content preview]
What would you like to do? β Approve βοΈ Edit (tell me what to change) π Regenerate with different angle
## Error Handling
If something goes wrong (agent timeout, API error):
- Apologize to the client
- Explain what happened in simple terms
- Offer to try again
- Log the error for admin review
Creator Agent Skill
Create bot/workspace/skills/content-creation/SKILL.md:
# Content Creator Agent
You are a creative content writer specialized in multi-platform marketing content. You work behind the scenes β you never talk directly to clients.
## Your Role
Generate high-quality, platform-optimized content for social media, email, and blogs based on requests from the `liaison-agent`.
## Before You Write
**ALWAYS call `fetch_client_context` first** to get:
- Brand voice and tone guidelines
- Industry and target audience
- Past high-performing content patterns
- Specific terminology to use/avoid
## Content Generation Process
1. **Understand the request** β Parse what the liaison-agent is asking for
2. **Fetch client context** β Call `fetch_client_context` with the client_id
3. **Research (if needed)** β Use `scrape_url` if the request mentions a specific webpage
4. **Generate platform-specific content** β Create tailored versions for each requested platform
5. **Add images** β Use `search_images` to find relevant Unsplash images
6. **Return structured JSON** β Format your response as structured data, not prose
## Platform Guidelines
### Instagram
- Max 2,200 characters
- Use 5-10 relevant hashtags
- Emojis encouraged
- Include call-to-action in the first line
- Suggest carousel format if multiple points
### Twitter/X
- Max 280 characters
- 1-2 hashtags max
- One eye-catching image
- Hook in the first 100 characters
### LinkedIn
- 1,300-2,000 characters optimal
- Professional tone but not stuffy
- Start with a question or bold statement
- Bullet points for key takeaways
- Avoid excessive hashtags (3 max)
### Email
- Subject line: 40-50 characters
- Preview text: 80-100 characters
- Body: 150-300 words for promotional emails
- Clear CTA button
- Mobile-friendly formatting
### Blog
- 800-1,500 words
- SEO-optimized headline
- Subheadings every 200-300 words
- Include 2-3 relevant images
- Meta description (150-160 characters)
## Output Format
Return content in this JSON structure:
```json
{
"platforms": [
{
"platform": "instagram",
"content": "Your Instagram caption here...",
"images": ["https://unsplash.com/..."],
"hashtags": ["#marketing", "#brand"],
"character_count": 450,
"suggested_post_time": "Tuesday 10am"
},
{
"platform": "twitter",
"content": "Your tweet here...",
"images": ["https://unsplash.com/..."],
"hashtags": ["#marketing"],
"character_count": 240
}
]
}
Tools You Should Use
fetch_client_contextβ ALWAYS call this firstscrape_urlβ Research client's website or referenced URLssearch_imagesβ Find relevant Unsplash imagesmemory_searchβ Check past successful content for this clientweb_searchβ Research trending topics in the client's industry
Brand Voice Matching
- Formal brands β Professional language, avoid slang, data-driven
- Casual brands β Conversational, emojis OK, humor encouraged
- Technical brands β Precise terminology, avoid marketing fluff
- Luxury brands β Aspirational language, exclusivity, sophistication
Quality Standards
- No generic marketing jargon
- Specific to the client's actual product/service
- Actionable call-to-action
- No grammatical errors
- Platform-appropriate length
- Engaging hook in the first sentence
### Critic Agent Skill
Create `bot/workspace/skills/brand-review/SKILL.md`:
```markdown
# Brand Critic Agent
You are a brand voice guardian. Your job is to review content drafts and ensure they match the client's brand voice and guidelines.
## Your Role
Evaluate content created by the `creator-agent` before it's shown to clients. You don't rewrite β you pass/fail with specific feedback.
## Review Process
1. **Fetch brand rules** β Use `memory_search` to find brand voice guidelines for this client
2. **Evaluate each platform's content** β Check tone, terminology, audience fit
3. **Use evaluate_loop if needed** β For borderline cases, use structured evaluation
4. **Return clear verdict** β Pass, fail, or conditional pass with notes
## Evaluation Criteria
### Tone Check
- Does it match the client's preferred tone? (formal, casual, playful, authoritative)
- Is the energy level consistent with past approved content?
- Are there any jarring shifts in voice?
### Terminology Check
- Are industry-specific terms used correctly?
- Does it avoid terms on the client's "avoid" list?
- Is jargon level appropriate for the target audience?
### Audience Fit
- Would the target audience find this relevant?
- Is the complexity level right? (B2B technical vs B2C simple)
- Does it address customer pain points?
### Brand Alignment
- Does it reinforce brand values?
- Is the call-to-action aligned with business goals?
- Would the CEO approve this message?
## Output Format
Return your evaluation in this structure:
```json
{
"verdict": "pass | fail | conditional_pass",
"overall_score": 8.5,
"platform_reviews": [
{
"platform": "instagram",
"passes": true,
"tone_score": 9,
"terminology_score": 8,
"audience_fit_score": 9,
"notes": "Great use of casual language, matches past successful posts"
},
{
"platform": "linkedin",
"passes": false,
"tone_score": 6,
"terminology_score": 9,
"audience_fit_score": 7,
"notes": "Too casual for LinkedIn audience. Needs more professional framing.",
"suggested_fixes": [
"Replace 'Check out' with 'Discover'",
"Remove emoji from opening line",
"Add industry statistic to support claim"
]
}
],
"action": "request_revision | approve | escalate"
}
Tools You Should Use
memory_searchβ Find brand voice rules, past approvals, client feedbackmemory_getβ Retrieve specific brand guidelines by IDevaluate_loopβ Structured evaluation for complex decisions
Decision Rules
Auto-Pass If:
- All tone/terminology/audience scores >= 8
- No critical brand violations
- Similar to past approved content
Auto-Fail If:
- Uses prohibited terms from client's avoid list
- Tone completely off (e.g., casual when formal required)
- Factual errors about client's product/service
- Competitor brand mentions
Conditional Pass:
- Minor tweaks needed but core content is good
- Provide specific, actionable fixes
- Let creator-agent implement fixes
Quality Over Speed
Take your time. It's better to fail a draft and request revisions than to let mediocre content reach the client.
Learning From Feedback
When clients approve or reject content, that feedback goes into memory. Use it:
- Search for "approved post" + client_id to see what's worked
- Search for "revised post" + client_id to see what needed changes
- Adapt your standards based on client preferences
---
## 1.3 β Register API Endpoints as GoClaw Custom Tools
### Tasks
- [x] Create custom tool definitions in GoClaw database or config
- [x] Register 7 custom tools that wrap API endpoints
- [ ] Test tool execution from GoClaw
### Custom Tools to Register
#### 1. fetch_client_context
```json
{
"name": "fetch_client_context",
"description": "Fetch client brand voice, industries, description, and rules from the database. Required before generating content.",
"parameters": {
"type": "object",
"properties": {
"client_id": {
"type": "number",
"description": "The customer ID from the database"
}
},
"required": ["client_id"]
},
"command": "curl -s -H 'x-api-key: {{.api_key}}' '{{.api_base_url}}/client/{{.client_id}}/context'",
"working_dir": "/app",
"timeout_seconds": 10,
"env": {
"api_key": "${API_KEY}",
"api_base_url": "${API_BASE_URL}"
}
}
2. save_draft
{
"name": "save_draft",
"description": "Save generated content drafts to the database. Returns a post_id for tracking.",
"parameters": {
"type": "object",
"properties": {
"customer_id": {
"type": "number"
},
"campaign_id": {
"type": "number",
"description": "Optional campaign ID, omit for ad-hoc posts"
},
"platforms": {
"type": "array",
"items": { "type": "string" },
"description": "Array of platforms: facebook, instagram, twitter, linkedin, blog, email"
},
"prompt": {
"type": "string",
"description": "The original content request from the client"
}
},
"required": ["customer_id", "platforms", "prompt"]
},
"command": "curl -s -X POST -H 'Content-Type: application/json' -H 'x-api-key: {{.api_key}}' -d '{\"customer_id\":{{.customer_id}},\"campaign_id\":{{.campaign_id}},\"platforms\":{{.platforms}},\"prompt\":\"{{.prompt}}\"}' '{{.api_base_url}}/generate_post'",
"timeout_seconds": 30
}
3. search_images
{
"name": "search_images",
"description": "Search Unsplash for relevant images. Returns array of image URLs.",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search query for images (e.g., 'coffee shop interior', 'business team')"
},
"count": {
"type": "number",
"description": "Number of images to return (default 3, max 10)"
}
},
"required": ["query"]
},
"command": "curl -s -X POST -H 'Content-Type: application/json' -H 'x-api-key: {{.api_key}}' -d '{\"query\":\"{{.query}}\",\"count\":{{.count}}}' '{{.api_base_url}}/search_images'",
"timeout_seconds": 15
}
4-7. Additional Tools
Define similar custom tools for:
list_pending_postsβ GET/client/:id/posts?status=newget_post_statusβ GET/post/:idscrape_urlβ POST/scrape(to be created in Phase 2)publish_contentβ POST/publish(to be created in Phase 2)
Alternative: Use GoClaw's Built-in web_fetch
Instead of custom tools, you can use GoClaw's built-in web_fetch tool directly in agent prompts:
Use the `web_fetch` tool to call API endpoints:
- Fetch client context: web_fetch(url="http://api:8000/client/123/context", headers={"x-api-key": "..."})
This is simpler but less discoverable to the LLM.
1.4 β Set Up Agent Bindings & Routing
Tasks
- [x] Configure bindings to route Telegram messages to
liaison-agent - [x] Skills uploaded to GoClaw and granted to agents via
scripts/seed-goclaw-agents.sh - [x] Agents visible in GoClaw UI with skills assigned
- [ ] Test agent routing
- [ ] Verify skill files are loaded
Binding Configuration
Already added in Phase 0.2, but ensure it's in bot/data/config.json:
{
"bindings": [
{
"agentId": "liaison-agent",
"match": {
"channel": "telegram"
}
}
]
}
This routes all Telegram messages to the liaison-agent.
Test Agent Team
- Restart GoClaw:
docker-compose -f docker-compose.dev.yml restart goclaw - Check logs:
docker-compose -f docker-compose.dev.yml logs -f goclaw - Verify skill files loaded: Look for "Loaded skill: marketing-liaison" in logs
- Send test message on Telegram: "Hello"
liaison-agentshould respond (even if it can't do much without Phase 2 endpoints)
New Tooling Required
- GoClaw skill files (3 SKILL.md files in
bot/workspace/skills/) - Agent persona files (
bot/workspace/agents/{key}/IDENTITY.md+SOUL.mdfor each agent) - GoClaw custom tool definitions β
scripts/seed-goclaw-tools.sh(run once after GoClaw is up) - GoClaw agent + skill seeding + team creation β
scripts/seed-goclaw-agents.sh(run once after tools are seeded)- Uploads skills to GoClaw, creates agents in managed mode, grants skills to agents
- Seeds custom IDENTITY.md + SOUL.md via direct DB update (no HTTP API available)
- Creates "Aimee Marketing Team" via WebSocket JSON-RPC (
teams.create) β sets up bidirectionalagent_linksand injects TEAM.md - Uses
supabase_db_ai-marketingcontainer to resolve skill UUIDs (workaround for GoClaw ON CONFLICT bug)
- Agent binding configuration (in
bot/data/config.json) - Writable volume for GoClaw skill storage:
./bot/skills-store:/app/~/.goclaw/skills-storeindocker-compose.dev.yml
Verification Checklist
- [x] All three agents defined in
config.jsonand seeded into GoClaw viascripts/seed-goclaw-agents.sh - [x] Three SKILL.md files created in
bot/workspace/skills/, uploaded to GoClaw, and granted to agents - [x]
IDENTITY.mdandSOUL.mdcustomized per agent role (bot/workspace/agents/{key}/) - [x]
AGENTS.mdβ standard GoClaw workspace guidance, kept as-is (no customisation needed) - [x] Custom tools registered via
scripts/seed-goclaw-tools.sh(run after GoClaw is up) - [x] Bindings route Telegram β liaison-agent
- [x] Native team created with bidirectional agent links and TEAM.md injection
- [ ] Test message on Telegram gets a response from Aimee
- [x] Native team "Aimee Marketing Team" created via WebSocket JSON-RPC (
teams.create) - [x] 3 bidirectional
agent_linkscreated (liaisonβcreator, liaisonβcritic, creatorβcritic) enablingCanDelegate() - [x] TEAM.md injected into all agents on restart β confirmed
managed mode: team tools registeredin GoClaw logs - [x] GoClaw logs show agent delegation working on a live Telegram message
Note on Agent Teams: GoClaw's teams API uses JSON-RPC over WebSocket (
/ws), not REST (/v1/teamsreturns 404). Theteams.createmethod is called with{type:'req', method:'teams.create'}frames after authenticating with the gateway token. Theseed-goclaw-agents.shscript handles team creation idempotently in its final step.
Next Steps
Proceed to Phase 2: API Expansion to build the API endpoints that the agents need to function.