Ai-Mee Help Centre
Home
Features
How-To Guides
FAQ
Need Help?
Home
Features
How-To Guides
FAQ
Need Help?

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.json with 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.md and SOUL.md per agent (stored in bot/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

AgentRoleLLMWhy
liaison-agentClient interfaceClaude Sonnet 4Best at nuanced conversation, handles all Telegram interaction
creator-agentContent generationGemini 2.0 FlashFast, cost-effective, great at creative writing
critic-agentBrand reviewGemini 2.0 FlashQuick 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 first
  • scrape_url β€” Research client's website or referenced URLs
  • search_images β€” Find relevant Unsplash images
  • memory_search β€” Check past successful content for this client
  • web_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 feedback
  • memory_get β€” Retrieve specific brand guidelines by ID
  • evaluate_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=new
  • get_post_status β€” GET /post/:id
  • scrape_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

  1. Restart GoClaw: docker-compose -f docker-compose.dev.yml restart goclaw
  2. Check logs: docker-compose -f docker-compose.dev.yml logs -f goclaw
  3. Verify skill files loaded: Look for "Loaded skill: marketing-liaison" in logs
  4. Send test message on Telegram: "Hello"
  5. liaison-agent should 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.md for 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 bidirectional agent_links and injects TEAM.md
    • Uses supabase_db_ai-marketing container 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-store in docker-compose.dev.yml

Verification Checklist

  • [x] All three agents defined in config.json and seeded into GoClaw via scripts/seed-goclaw-agents.sh
  • [x] Three SKILL.md files created in bot/workspace/skills/, uploaded to GoClaw, and granted to agents
  • [x] IDENTITY.md and SOUL.md customized 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_links created (liaison↔creator, liaison↔critic, creator↔critic) enabling CanDelegate()
  • [x] TEAM.md injected into all agents on restart β€” confirmed managed mode: team tools registered in 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/teams returns 404). The teams.create method is called with {type:'req', method:'teams.create'} frames after authenticating with the gateway token. The seed-goclaw-agents.sh script 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.