Skip to main content
Version: 1.0.5

prompt-guide

Version: 1.0 Last Updated: October 2025 Model: ASI1-Mini optimized


Table of Contents

  1. Introduction
  2. Understanding Agentverse Mode
  3. Core Concepts
  4. Prompt Structure
  5. Best Practices
  6. Common Patterns
  7. Deployment Workflow
  8. Troubleshooting
  9. Advanced Techniques
  10. Examples

Introduction

FetchCoder's Agentverse mode is a specialized agent designed to create production-ready autonomous agents for the Fetch.ai Agentverse platform. This guide provides comprehensive instructions for crafting effective prompts that leverage FetchCoder's capabilities while working within ASI1-Mini's constraints.

What This Guide Covers

  • How to structure prompts for maximum effectiveness
  • Understanding Chat Protocol v0.3.0 requirements
  • Working with MCP tools for deployment
  • Debugging and iterating on agent code
  • Optimizing prompts for ASI1-Mini's token efficiency

Who This Guide Is For

  • Developers creating Agentverse agents
  • Users working with FetchCoder in Agentverse mode
  • Anyone deploying autonomous agents to Fetch.ai platform

Understanding Agentverse Mode

What is Agentverse Mode?

Agentverse mode is a specialized configuration in FetchCoder that:

  • Uses optimized prompts for agent creation (~2,300 tokens vs 7,000 original)
  • Enforces Chat Protocol v0.3.0 compliance
  • Integrates with Agentverse MCP tools for deployment
  • Generates production-ready, stateless agents by default
  • Includes automatic error detection and debugging workflows

Key Differences from Other Modes

FeatureGeneral ModeAgentverse Mode
PurposeGeneral coding tasksAgentverse agent creation
ProtocolN/AChat Protocol v0.3.0 required
DeploymentManualAutomated via MCP tools
Agent InitFlexibleAgent() only (no params)
StorageN/AStateless by default
ToolsAll availableAgentverse-specific MCP tools

When to Use Agentverse Mode

Use Agentverse mode when you need to:

  • ✅ Create agents that run on Fetch.ai Agentverse platform
  • ✅ Build Chat Protocol v0.3.0 compliant agents
  • ✅ Deploy and test agents automatically
  • ✅ Generate production-ready autonomous agents

Do NOT use Agentverse mode for:

  • ❌ Local development/testing agents (use general mode)
  • ❌ Agents that require local parameters (name, seed, port)
  • ❌ Non-chat protocol agents
  • ❌ General coding tasks unrelated to agents

Core Concepts

1. Chat Protocol v0.3.0

All Agentverse agents MUST use Chat Protocol v0.3.0 from uagents_core.contrib.protocols.chat.

Critical Requirements:

# ✅ CORRECT: Import from official protocol
from uagents_core.contrib.protocols.chat import (
ChatMessage,
ChatAcknowledgement,
TextContent,
EndSessionContent,
chat_protocol_spec
)

# ❌ WRONG: Custom Model classes
from uagents import Model
class ChatMessage(Model):
content: list

Message Flow:

  1. Receive ChatMessage from user
  2. IMMEDIATELY send ChatAcknowledgement (< 100ms)
  3. Process the message
  4. Send ChatMessage response with EndSessionContent

2. Agent Initialization

Agentverse-hosted agents MUST NOT have initialization parameters.

# ✅ CORRECT: For Agentverse hosting
agent = Agent()

# ❌ WRONG: For local development only
agent = Agent(
name="my_agent",
seed="secret_phrase",
port=8000,
endpoint=["http://localhost:8000/submit"]
)

Why? Agentverse manages agent identity, networking, and configuration automatically. Parameters are only for local development.

3. Protocol Registration

# ✅ CORRECT: Use spec parameter
chat_proto = Protocol(spec=chat_protocol_spec)

# ❌ WRONG: Custom parameters
chat_proto = Protocol(name="ChatProtocol", version="0.3.0")

4. Stateless vs Stateful Agents

Default: Stateless Most simple agents (dice, coin toss, calculator) should be stateless.

# ✅ Stateless agent - no persistent storage
@chat_proto.on_message(ChatMessage)
async def handle_chat_message(ctx: Context, sender: str, msg: ChatMessage):
# Process and respond
pass

When to Use State: Use persistent storage ONLY when the agent needs to:

  • Remember conversation history across sessions
  • Store user preferences or settings
  • Accumulate data over time
  • Track transactions or logs

5. MCP Tools Integration

FetchCoder integrates with Agentverse via MCP (Model Context Protocol) tools.

Available Tools:

  • mcp__agentverse__create_user_agent - Create new agent
  • mcp__agentverse__update_user_agent_code - Upload code
  • mcp__agentverse__start_specific_user_agent - Start agent
  • mcp__agentverse__stop_specific_user_agent - Stop agent
  • mcp__agentverse__get_latest_logs_for_user_agent - Check logs
  • mcp__agentverse__delete_user_agent - Delete agent

Critical Rule: DO NOT pass api_token parameter - it's injected automatically.


Prompt Structure

Anatomy of an Effective Agentverse Prompt

An effective prompt has 6 essential sections:

1. [AGENT DESCRIPTION] - What the agent does
2. [REQUIREMENTS] - Technical specifications
3. [PROTOCOL COMPLIANCE] - Chat Protocol v0.3.0 rules
4. [MCP TOOL INSTRUCTIONS] - Deployment process
5. [DEBUG WORKFLOW] - Error handling loop
6. [SAVE LOCATION] - Where to save code

Template Structure

Create a [AGENT_TYPE] agent for Agentverse that:
- Uses Chat Protocol v0.3.0 (from uagents_core.contrib.protocols.chat)
- [CORE FUNCTIONALITY 1]
- [CORE FUNCTIONALITY 2]
- [CORE FUNCTIONALITY 3]
- Must use agent = Agent() with NO parameters (Agentverse hosting)
- Should be stateless (no persistent storage needed)
- Save the complete working code to agent.py on disk

Important requirements:
- Import ChatMessage, ChatAcknowledgement, TextContent, EndSessionContent from uagents_core.contrib.protocols.chat
- Send ChatAcknowledgement FIRST before processing
- Include EndSessionContent in response
- Use ctx.logger (NOT print statements)
- No ASI1-Mini AI needed for this simple logic
- [SPECIFIC IMPLEMENTATION DETAILS]

After saving to agent.py, deploy to Agentverse using MCP tools:

CRITICAL MCP TOOL USAGE:
- All agentverse MCP tools automatically use the configured API token from environment
- DO NOT pass api_token parameter explicitly - it's injected automatically by the system
- Tool names: mcp__agentverse__create_user_agent, mcp__agentverse__update_user_agent_code, etc.
- When calling tools, ONLY provide the required parameters (address, name, code) - NOT api_token

Deployment steps:
1. Create agent: Call mcp__agentverse__create_user_agent with ONLY name parameter (e.g., name="[AGENT_NAME]")
- Extract the agent address from response
2. Read agent.py: Use Read tool to get file contents as string
3. Update code: Call mcp__agentverse__update_user_agent_code with:
- address: the agent address from step 1
- code: array with single object [{"name": "agent.py", "value": "<file_contents>", "language": "python"}]
- DO NOT include api_token parameter
4. Start agent: Call mcp__agentverse__start_specific_user_agent with ONLY address parameter
5. Check logs: Call mcp__agentverse__get_latest_logs_for_user_agent with ONLY address parameter
6. If logs show errors:
- Stop agent: Call mcp__agentverse__stop_specific_user_agent with ONLY address parameter
- Fix code in agent.py
- Read updated file
- Update code again (step 3)
- Start again (step 4)
- Check logs again (step 5)
7. Repeat until logs show "Agent started" or "Agent ready" without errors

Example correct tool call format:
- ✅ mcp__agentverse__create_user_agent(name="[AGENT_NAME]")
- ✅ mcp__agentverse__update_user_agent_code(address="agent1q...", code=[{"name": "agent.py", "value": "...", "language": "python"}])
- ❌ mcp__agentverse__update_user_agent_code(address="agent1q...", code=[...], api_token="...") ← WRONG, will cause 401 error

Note: API token is already configured in environment and injected automatically by MCP tool middleware.

Save to: agent.py

Section Breakdown

1. Agent Description

Purpose: Clearly define what the agent does in 3-5 bullet points.

Best Practices:

  • Start with agent type (dice roller, calculator, etc.)
  • List core functionalities
  • Specify input formats the agent accepts
  • Describe expected outputs

Example:

Create a dice rolling agent for Agentverse that:
- Accepts user requests like "roll 2d6" or "roll a 20-sided die"
- Parses dice notation (e.g., "2d6", "1d20", "3d10")
- Returns random dice roll results

2. Requirements Section

Purpose: Specify technical requirements and constraints.

Must Include:

  • Protocol version (Chat Protocol v0.3.0)
  • Agent initialization (agent = Agent() with NO parameters)
  • State management (stateless vs stateful)
  • File location (agent.py)

Example:

Important requirements:
- Import ChatMessage, ChatAcknowledgement, TextContent, EndSessionContent from uagents_core.contrib.protocols.chat
- Send ChatAcknowledgement FIRST before processing
- Include EndSessionContent in response
- Use ctx.logger (NOT print statements)
- Include the complete dice rolling logic inline

3. Protocol Compliance

Purpose: Enforce Chat Protocol v0.3.0 compliance rules.

Critical Elements:

  • Import statements (from uagents_core.contrib.protocols.chat)
  • Acknowledgement requirement (FIRST before processing)
  • EndSessionContent requirement (in response)
  • Logging requirement (ctx.logger not print)

4. MCP Tool Instructions

Purpose: Guide the deployment process step-by-step.

Must Include:

  • Tool names with mcp__agentverse__ prefix
  • Parameter lists (what to include, what NOT to include)
  • Correct vs incorrect examples
  • API token injection explanation

Critical Points:

  • ⚠️ NO api_token parameter in tool calls
  • ⚠️ Extract agent address from create response
  • ⚠️ Code must be array of file objects
  • ⚠️ Always stop before updating code

5. Debug Workflow

Purpose: Enable automatic error detection and fixing.

Must Include:

  • Log checking after start
  • Stop → Fix → Update → Start → Check cycle
  • Repetition until success

Example:

6. If logs show errors:
- Stop agent: Call mcp__agentverse__stop_specific_user_agent with ONLY address parameter
- Fix code in agent.py
- Read updated file
- Update code again (step 3)
- Start again (step 4)
- Check logs again (step 5)
7. Repeat until logs show "Agent started" or "Agent ready" without errors

6. Save Location

Purpose: Specify where to save the generated code.

Standard:

Save to: agent.py

Best Practices

1. Token Efficiency (ASI1-Mini Optimization)

ASI1-Mini has limited context capacity. Optimize prompts for token efficiency.

Token Budget Guidelines:

  • ✅ Simple agents: 1,000-1,500 tokens
  • ✅ Medium complexity: 1,500-2,500 tokens
  • ✅ Complex agents: 2,500-3,500 tokens
  • ❌ Avoid: > 4,000 tokens (inefficient)

Optimization Techniques:

  1. Use Imperative Language

    ❌ "You should create an agent that will roll dice"
    ✅ "Create a dice rolling agent"
  2. Eliminate Redundancy

    ❌ "The agent must use Chat Protocol v0.3.0. Make sure to use Chat Protocol v0.3.0."
    ✅ "Uses Chat Protocol v0.3.0"
  3. Consolidate Lists

    ❌ "- Import ChatMessage
    - Import ChatAcknowledgement
    - Import TextContent
    - Import EndSessionContent"
    ✅ "- Import ChatMessage, ChatAcknowledgement, TextContent, EndSessionContent"
  4. Position Decay Optimization

    • Place CRITICAL rules at the END of prompt
    • ASI1-Mini has 22.1x better retention for end-positioned info
    • Example: Place "agent = Agent() NO parameters" reminder at end

2. Clarity Over Brevity

While optimizing for tokens, maintain clarity.

Principles:

  • Don't sacrifice understanding for token reduction
  • Include examples for complex concepts
  • Use clear section headings
  • Provide context where needed

Example:

❌ Too Brief: "Use MCP tools correctly"
✅ Clear: "Call mcp__agentverse__create_user_agent with ONLY name parameter (e.g., name='DiceRoller')"

3. Explicit Requirements

FetchCoder works best with explicit, unambiguous requirements.

Do:

  • ✅ List exact import statements
  • ✅ Specify parameter names and types
  • ✅ Provide example values
  • ✅ State what NOT to do

Don't:

  • ❌ Assume FetchCoder knows conventions
  • ❌ Use vague terms like "appropriate" or "proper"
  • ❌ Leave implementation details implicit

4. Error Prevention

Prevent common errors by explicitly forbidding them.

Common Mistakes to Prevent:

**Critical DON'Ts:**
- ❌ NO parameters in Agent() initialization
- ❌ NO custom Model classes for Chat Protocol
- ❌ NO print statements (use ctx.logger)
- ❌ NO api_token parameter in MCP tools
- ❌ NO skipping ChatAcknowledgement

5. Implementation Details

For non-trivial logic, provide implementation hints.

Example - Dice Rolling:

- Parse dice notation with regex: r'(\d*)d(\d+)'
- Use random.randint(1, num_sides) for rolls
- Format output: "Rolling 2d6: 4, 5 (Total: 9)"

Example - Unit Conversion:

- Conversion formulas:
- C to F: F = C * 9/5 + 32
- km to miles: miles = km * 0.621371
- Parse with regex: r'(\d+\.?\d*)\s*(celsius|fahrenheit|km|miles)'

6. Stateless by Default

Unless explicitly needed, agents should be stateless.

When to Specify Stateless:

- Should be stateless (no persistent storage needed)

When to Specify Stateful:

- Needs persistent storage for:
- User conversation history
- Preference tracking
- Transaction logging

Common Patterns

Pattern 1: Simple Computation Agent

Use Case: Agents that perform calculations, conversions, or deterministic operations.

Characteristics:

  • No external APIs
  • No persistent storage
  • Pure logic-based responses
  • Stateless

Template:

Create a [TYPE] agent for Agentverse that:
- Accepts [INPUT_FORMAT]
- Performs [CALCULATION_TYPE]
- Returns [OUTPUT_FORMAT]
- Must use agent = Agent() with NO parameters
- Should be stateless (no persistent storage needed)

Requirements:
- Use [SPECIFIC_LOGIC] for processing
- Parse input with [REGEX_PATTERN]
- Format output as [FORMAT_SPECIFICATION]

Examples:

  • Calculator agent
  • Unit converter agent
  • Temperature converter agent
  • Currency converter (with static rates)

Pattern 2: Random Selection Agent

Use Case: Agents that return random selections from predefined options.

Characteristics:

  • Predefined option lists
  • Random selection logic
  • No external dependencies
  • Stateless

Template:

Create a [TYPE] agent for Agentverse that:
- Returns random [ITEM_TYPE] from a curated list
- Accepts requests like "[EXAMPLE_REQUEST]"
- Includes [ADDITIONAL_DATA] with each selection
- Must use agent = Agent() with NO parameters
- Should be stateless (no persistent storage needed)

Requirements:
- Include list of [N] [ITEMS] inline
- Use random.choice() for selection
- Format response as: [FORMAT_TEMPLATE]

Examples:

  • Magic 8-ball agent
  • Quote of the day agent
  • Recipe suggestion agent
  • Color picker agent

Pattern 3: Game Agent

Use Case: Agents that play simple games with users.

Characteristics:

  • Game rules encoded inline
  • Random computer moves
  • Winner determination logic
  • Stateless (no game history)

Template:

Create a [GAME_NAME] game agent for Agentverse that:
- Plays [GAME_NAME] against the user
- Accepts user choices: [VALID_OPTIONS]
- Makes random choice for computer player
- Determines winner and returns result with explanation
- Must use agent = Agent() with NO parameters
- Should be stateless (no persistent storage needed)

Requirements:
- Include game logic inline ([RULE_1], [RULE_2], [RULE_3])
- Parse user choice with [PARSING_METHOD]
- Use random.choice([OPTIONS]) for computer choice
- Return formatted result like "[EXAMPLE_OUTPUT]"

Examples:

  • Rock paper scissors agent
  • Coin toss agent
  • Dice rolling agent
  • Number guessing agent

Pattern 4: Parser/Formatter Agent

Use Case: Agents that parse structured input and format output.

Characteristics:

  • Regex-heavy parsing
  • Input validation
  • Formatted output
  • Stateless

Template:

Create a [TYPE] agent for Agentverse that:
- Parses [INPUT_FORMAT] from user queries
- Validates [VALIDATION_RULES]
- Returns [OUTPUT_FORMAT]
- Must use agent = Agent() with NO parameters
- Should be stateless (no persistent storage needed)

Requirements:
- Parse with regex: [REGEX_PATTERNS]
- Validate [VALIDATION_CONDITIONS]
- Format output as: [OUTPUT_TEMPLATE]
- Handle edge cases: [EDGE_CASES]

Examples:

  • Date parser agent
  • URL validator agent
  • Email formatter agent
  • JSON prettifier agent

Pattern 5: Generator Agent

Use Case: Agents that generate content based on user specifications.

Characteristics:

  • Generation rules/algorithms
  • Customization options
  • Validation/constraints
  • Stateless

Template:

Create a [TYPE] generator agent for Agentverse that:
- Generates [OUTPUT_TYPE] based on user requirements
- Accepts requests like "[EXAMPLE_REQUEST]"
- Supports customization: [OPTIONS]
- Returns [OUTPUT_FORMAT]
- Must use agent = Agent() with NO parameters
- Should be stateless (no persistent storage needed)

Requirements:
- Use [ALGORITHM/METHOD] for generation
- Parse requirements with [PARSING_METHOD]
- Default to [DEFAULT_SETTINGS] if not specified
- Validate [CONSTRAINTS]

Examples:

  • Password generator agent
  • Lorem ipsum generator agent
  • UUID generator agent
  • Random name generator agent

Deployment Workflow

Standard Deployment Process

Every Agentverse agent follows this 7-step deployment workflow:

Step 1: Create Agent

# Call MCP tool to create new agent
mcp__agentverse__create_user_agent(name="AgentName")

# Response contains:
{
"address": "agent1q...",
"name": "AgentName",
"status": "created"
}

# ⚠️ CRITICAL: Save the agent address for subsequent calls

Common Issues:

  • ❌ Passing api_token parameter → 401 error
  • ❌ Using invalid characters in name → Creation fails
  • ❌ Not extracting address from response → Can't update code

Step 2: Read Generated Code

# Use Read tool to get file contents
Read(file_path="/path/to/agent.py")

# Returns: Complete file contents as string

Common Issues:

  • ❌ File doesn't exist yet → Wait for code generation
  • ❌ Wrong file path → Check working directory

Step 3: Update Agent Code

# Upload code to Agentverse
mcp__agentverse__update_user_agent_code(
address="agent1q...",
code=[{
"name": "agent.py",
"value": "<file_contents_as_string>",
"language": "python"
}]
)

# ⚠️ NO api_token parameter!

Common Issues:

  • ❌ Passing api_token → 401 error
  • ❌ Code not as array → Upload fails
  • ❌ File contents not properly escaped → Syntax error
  • ❌ Agent not stopped before update → Update fails

Step 4: Start Agent

# Start the agent
mcp__agentverse__start_specific_user_agent(
address="agent1q..."
)

# Returns: Status confirmation

Common Issues:

  • ❌ Agent already running → Restart fails
  • ❌ Syntax errors in code → Agent fails to start
  • ❌ Missing dependencies → Import errors

Step 5: Check Logs

# Get latest logs
mcp__agentverse__get_latest_logs_for_user_agent(
address="agent1q..."
)

# Returns: Log entries with timestamps

What to Look For:

  • ✅ "Agent started" or "🚀 Agent starting"
  • ✅ "Address: agent1q..."
  • ❌ Import errors
  • ❌ Syntax errors
  • ❌ Protocol errors

Step 6: Debug Loop (If Errors)

# If logs show errors:
1. Stop agent: mcp__agentverse__stop_specific_user_agent(address="agent1q...")
2. Fix code in agent.py (using Edit tool)
3. Read updated file
4. Update code again (step 3)
5. Start agent again (step 4)
6. Check logs again (step 5)

Common Fixes:

  • Missing imports → Add to imports section
  • Wrong Agent initialization → Change to Agent()
  • Print statements → Replace with ctx.logger
  • Missing acknowledgement → Add as first step

Step 7: Verify Success

# Successful deployment shows:
- Status: "running"
- Logs: "Agent started" without errors
- No import or syntax errors
- Protocol handlers registered

Deployment Checklist

Use this checklist for every deployment:

□ Agent created with unique name
□ Agent address extracted from response
□ Code generated and saved to agent.py
□ Code uploaded with correct format (array of file objects)
□ NO api_token parameter passed to any MCP tool
□ Agent started successfully
□ Logs checked for errors
□ If errors: debug loop executed until clean start
□ Final verification: agent shows "running" status

Troubleshooting

Common Errors and Solutions

Error 1: 401 - Could not validate credentials

Symptom:

Tool 'update_user_agent_code' execution failed: API call failed: 401 - {"detail":"Could not validate credentials"}

Root Cause: Passing api_token parameter explicitly in MCP tool call.

Solution:

# ❌ WRONG
mcp__agentverse__update_user_agent_code(
address="agent1q...",
code=[...],
api_token="..." # ← Remove this
)

# ✅ CORRECT
mcp__agentverse__update_user_agent_code(
address="agent1q...",
code=[...]
)

Prevention: Always include in prompt:

CRITICAL: DO NOT pass api_token parameter - it's injected automatically

Error 2: Agent won't start - Import errors

Symptom:

ImportError: cannot import name 'ChatMessage' from 'uagents'

Root Cause: Importing Chat Protocol classes from wrong location.

Solution:

# ❌ WRONG
from uagents import ChatMessage, ChatAcknowledgement

# ✅ CORRECT
from uagents_core.contrib.protocols.chat import (
ChatMessage,
ChatAcknowledgement,
TextContent,
EndSessionContent,
chat_protocol_spec
)

Prevention: Be explicit about imports in prompt:

- Import ChatMessage, ChatAcknowledgement, TextContent, EndSessionContent from uagents_core.contrib.protocols.chat

Error 3: Agent() initialization error

Symptom:

TypeError: Agent() got unexpected keyword arguments: 'name', 'seed', 'port'

Root Cause: Using local development parameters on Agentverse.

Solution:

# ❌ WRONG - Local development only
agent = Agent(
name="dice_roller",
seed="secret_phrase",
port=8000
)

# ✅ CORRECT - Agentverse hosting
agent = Agent()

Prevention: Emphasize in prompt:

- Must use agent = Agent() with NO parameters (Agentverse hosting)

Error 4: Missing acknowledgement

Symptom: Agent receives messages but doesn't respond, or times out.

Root Cause: Not sending ChatAcknowledgement as first step.

Solution:

@chat_proto.on_message(ChatMessage)
async def handle_chat_message(ctx: Context, sender: str, msg: ChatMessage):
# ✅ MUST BE FIRST - Send acknowledgement immediately
await ctx.send(sender, ChatAcknowledgement(
timestamp=datetime.utcnow(),
acknowledged_msg_id=msg.msg_id
))

# Then process message...

Prevention: Make it unmissable in prompt:

- Send ChatAcknowledgement FIRST before processing
- **IMMEDIATELY** send acknowledgement (< 100ms)

Error 5: Missing EndSessionContent

Symptom: User doesn't receive response, or session hangs.

Root Cause: Response doesn't include EndSessionContent.

Solution:

# ✅ CORRECT - Include EndSessionContent
await ctx.send(sender, ChatMessage(
timestamp=datetime.utcnow(),
msg_id=str(uuid4()),
content=[
TextContent(type="text", text=response_text),
EndSessionContent(type="end-session") # ← REQUIRED
]
))

Prevention: Emphasize in prompt:

- Include EndSessionContent in response
- Response must contain EndSessionContent(type="end-session")

Error 6: Code update fails - Agent still running

Symptom:

Error: Cannot update code while agent is running

Root Cause: Trying to update code without stopping agent first.

Solution:

# ✅ CORRECT sequence
1. Stop agent: mcp__agentverse__stop_specific_user_agent(address="...")
2. Update code: mcp__agentverse__update_user_agent_code(...)
3. Start agent: mcp__agentverse__start_specific_user_agent(address="...")

Prevention: Include in debug loop:

6. If logs show errors:
- Stop agent FIRST: Call mcp__agentverse__stop_specific_user_agent
- Fix code in agent.py
- Update code again

Error 7: Print statements cause issues

Symptom: Agent logs are messy, or logging doesn't work properly.

Root Cause: Using print() instead of ctx.logger.

Solution:

# ❌ WRONG
print(f"Processing query: {query}")

# ✅ CORRECT
ctx.logger.info(f"Processing query: {query}")

Prevention: Explicitly forbid in prompt:

- Use ctx.logger (NOT print statements)
- NEVER use print() - always use ctx.logger.info/warning/error

Debugging Workflow

When an agent fails to start or has errors:

1. CHECK LOGS
- Look for specific error messages
- Note line numbers if provided
- Identify error type (import, syntax, runtime)

2. IDENTIFY ROOT CAUSE
Common causes:
- Import errors (wrong source)
- Initialization errors (Agent parameters)
- Protocol errors (missing acknowledgement)
- Syntax errors (invalid Python)

3. FIX CODE
- Use Edit tool to fix specific issues
- Don't change working parts
- Focus on error line/function

4. STOP AGENT
- Must stop before updating
- Use mcp__agentverse__stop_specific_user_agent

5. UPDATE CODE
- Upload fixed version
- Verify upload success

6. RESTART AGENT
- Start with mcp__agentverse__start_specific_user_agent
- Wait for initialization

7. VERIFY FIX
- Check logs again
- Look for "Agent started" message
- Ensure no new errors

8. REPEAT IF NEEDED
- Go back to step 1 if still errors
- Continue until clean start

Advanced Techniques

1. Multi-File Agents

For complex agents requiring multiple files:

code=[
{
"name": "agent.py",
"value": "<agent_code>",
"language": "python"
},
{
"name": "utils.py",
"value": "<utility_functions>",
"language": "python"
},
{
"name": "requirements.txt",
"value": "requests\npandas\nnumpy",
"language": "text"
}
]

Prompt Template:

Create a multi-file agent with:
- agent.py: Main agent code with Chat Protocol handlers
- utils.py: Helper functions for [SPECIFIC_FUNCTIONALITY]
- requirements.txt: External dependencies

Deploy with code array containing all three files.

2. External API Integration

For agents that call external APIs:

Key Considerations:

  • Error handling for API failures
  • Rate limiting
  • Timeout handling
  • Fallback responses

Prompt Template:

Create an agent that integrates with [API_NAME]:
- Calls [API_ENDPOINT] with [PARAMETERS]
- Handles rate limiting (max [N] requests per [TIME_UNIT])
- Implements timeout after [SECONDS] seconds
- Provides fallback response if API unavailable
- Includes error handling for [ERROR_TYPES]

Example Implementation:

async def call_external_api(query: str) -> str:
try:
response = requests.get(
f"https://api.example.com/search",
params={"q": query},
timeout=10
)
if response.status_code == 200:
return response.json()['result']
else:
return "API temporarily unavailable. Please try again."
except requests.Timeout:
return "Request timed out. Please try again."
except Exception as e:
ctx.logger.error(f"API error: {e}")
return "An error occurred. Please try again later."

3. Stateful Agents with Persistent Storage

For agents that need to remember information:

Prompt Template:

Create a stateful agent that:
- Stores [DATA_TYPE] persistently
- Retrieves [DATA_TYPE] across sessions
- Updates [DATA_TYPE] based on [CONDITIONS]

Include PersistentStorageManager with:
- Atomic save operations
- Rollback on failure
- Compression for large data

Storage Pattern:

from uagents.storage import StorageAPI

class PersistentStorageManager:
def __init__(self, storage: StorageAPI, namespace: str = "default"):
self.storage = storage
self.namespace = namespace

def save_atomic(self, key: str, value: Any) -> bool:
full_key = f"{self.namespace}_{key}"
try:
previous = self.storage.get(full_key)
self.storage.set(full_key, value)
return True
except Exception as e:
if previous is not None:
self.storage.set(full_key, previous)
return False

def load_with_fallback(self, key: str, default: Any = None) -> Any:
full_key = f"{self.namespace}_{key}"
try:
return self.storage.get(full_key) or default
except:
return default

# Usage
storage_mgr = PersistentStorageManager(agent.storage)
storage_mgr.save_atomic("user_prefs", {"theme": "dark"})
prefs = storage_mgr.load_with_fallback("user_prefs", {})

4. Conditional Logic Based on User Input

For agents with complex branching:

Prompt Template:

Create an agent that handles multiple command types:
- If query contains [PATTERN_1]: Execute [LOGIC_1]
- If query contains [PATTERN_2]: Execute [LOGIC_2]
- If query contains [PATTERN_3]: Execute [LOGIC_3]
- Default: [DEFAULT_RESPONSE]

Parse commands with regex patterns and route to appropriate handler.

Implementation Pattern:

@chat_proto.on_message(ChatMessage)
async def handle_chat_message(ctx: Context, sender: str, msg: ChatMessage):
await ctx.send(sender, ChatAcknowledgement(...))

query = extract_query(msg)

# Pattern matching
if re.search(r'roll|dice', query, re.IGNORECASE):
response = handle_dice_roll(query)
elif re.search(r'flip|coin', query, re.IGNORECASE):
response = handle_coin_flip(query)
elif re.search(r'calculate|compute', query, re.IGNORECASE):
response = handle_calculation(query)
else:
response = "I can help with dice rolls, coin flips, or calculations. What would you like?"

await ctx.send(sender, ChatMessage(...))

5. ASI1-Mini Integration

For agents that use ASI1-Mini for AI responses:

Prompt Template:

Create an agent with ASI1-Mini integration:
- Uses ASI1MiniClient for AI-powered responses
- Implements rate limiting (60 requests/minute)
- Includes LRU cache with 15-minute TTL
- Has circuit breaker (3 failures → 60s cooldown)
- Provides fallback for API failures
- API key from environment: os.environ.get("ASI1_API_KEY")

ASI1MiniClient Pattern:

class ASI1MiniClient:
def __init__(self, api_key: str = None):
self.api_key = api_key or os.environ.get("ASI1_API_KEY")
self.base_url = "https://api.asi1.ai/v1"
self.model = "asi1-mini"
self.rate_limiter = RateLimiter(60, 60)
self.cache = LRUCache(100, 900)
self.circuit_breaker = {
"failures": 0,
"last_failure": 0.0,
"threshold": 3,
"reset_timeout": 60.0
}

async def process(self, query: str) -> str:
# Check cache
cache_key = hashlib.md5(query.encode()).hexdigest()
if cached := self.cache.get(cache_key):
return cached

# Check circuit breaker
if not self._check_circuit_breaker():
return "Service temporarily unavailable."

# Rate limiting
if not await self.rate_limiter.acquire():
return "Rate limit exceeded. Please try again."

# Make API call
try:
response = requests.post(
f"{self.base_url}/chat/completions",
headers={"Authorization": f"Bearer {self.api_key}"},
json={
"model": self.model,
"messages": [{"role": "user", "content": query}],
"max_tokens": 500
},
timeout=15
)

if response.status_code == 200:
result = response.json()['choices'][0]['message']['content']
self.cache.set(cache_key, result)
return result
else:
self._record_failure()
return "API error occurred."
except Exception as e:
self._record_failure()
return "Request failed. Please try again."

6. Testing Patterns

Before deploying to production:

Local Testing:

# Syntax check
python -m py_compile agent.py

# Short run test (5 seconds)
timeout 5 python agent.py || true

# Check for common issues
grep -n "print(" agent.py # Should be empty
grep -n "Agent(name=" agent.py # Should be empty

Agentverse Testing:

  1. Deploy to test environment
  2. Send test messages
  3. Check response format
  4. Verify acknowledgements
  5. Monitor logs for warnings
  6. Load test with multiple requests

Examples

Example 1: Minimal Agent (Dice Roller)

Prompt:

Create a dice rolling agent for Agentverse that:
- Uses Chat Protocol v0.3.0 (from uagents_core.contrib.protocols.chat)
- Accepts "roll 2d6" or "roll d20"
- Parses dice notation with regex
- Returns random results
- Must use agent = Agent() with NO parameters
- Should be stateless

Important requirements:
- Import ChatMessage, ChatAcknowledgement, TextContent, EndSessionContent from uagents_core.contrib.protocols.chat
- Send ChatAcknowledgement FIRST
- Include EndSessionContent in response
- Use ctx.logger (NOT print)
- Parse with regex: r'(\d*)d(\d+)'
- Use random.randint()

Deploy using MCP tools (DO NOT pass api_token parameter).

Save to: agent.py

Expected Code Structure:

import re, random
from datetime import datetime
from uuid import uuid4

from uagents_core.contrib.protocols.chat import (
ChatMessage, ChatAcknowledgement, TextContent,
EndSessionContent, chat_protocol_spec
)
from uagents import Agent, Context, Protocol

agent = Agent()
chat_proto = Protocol(spec=chat_protocol_spec)

@chat_proto.on_message(ChatMessage)
async def handle_chat_message(ctx: Context, sender: str, msg: ChatMessage):
await ctx.send(sender, ChatAcknowledgement(
timestamp=datetime.utcnow(),
acknowledged_msg_id=msg.msg_id
))

query = " ".join(c.text for c in msg.content if hasattr(c, 'text'))
ctx.logger.info(f"Processing: {query}")

# Parse dice notation
match = re.search(r'(\d*)d(\d+)', query)
if match:
num_dice = int(match.group(1)) if match.group(1) else 1
num_sides = int(match.group(2))
rolls = [random.randint(1, num_sides) for _ in range(num_dice)]
response = f"Rolling {num_dice}d{num_sides}: {rolls} (Total: {sum(rolls)})"
else:
response = "Please use format like '2d6' or 'd20'"

await ctx.send(sender, ChatMessage(
timestamp=datetime.utcnow(),
msg_id=str(uuid4()),
content=[
TextContent(type="text", text=response),
EndSessionContent(type="end-session")
]
))

agent.include(chat_proto, publish_manifest=True)

if __name__ == "__main__":
agent.run()

Example 2: Medium Complexity (Unit Converter)

Prompt:

Create a unit converter agent for Agentverse that:
- Uses Chat Protocol v0.3.0
- Converts temperature (C/F), distance (km/miles), weight (kg/lbs)
- Accepts "convert 100 celsius to fahrenheit"
- Parses value and units with regex
- Returns converted value with formatting
- Must use agent = Agent() with NO parameters
- Should be stateless

Important requirements:
- Import from uagents_core.contrib.protocols.chat
- Send ChatAcknowledgement FIRST
- Include EndSessionContent in response
- Formulas: C to F = C * 9/5 + 32, km to miles = km * 0.621371, kg to lbs = kg * 2.20462
- Parse: r'convert (\d+\.?\d*)\s*(\w+) to (\w+)'

Deploy using MCP tools (NO api_token).

Save to: agent.py

Expected Features:

  • Conversion dictionary for all unit types
  • Regex parsing for "convert X unit1 to unit2"
  • Error handling for invalid units
  • Formatted output with 2 decimal places

Example 3: Advanced (Multi-Command Agent)

Prompt:

Create a multi-purpose utility agent for Agentverse that:
- Uses Chat Protocol v0.3.0
- Handles: dice rolls, coin flips, random numbers
- Routes commands based on keywords
- Must use agent = Agent() with NO parameters
- Should be stateless

Command patterns:
- "roll [N]d[S]" → Roll N dice with S sides
- "flip coin" → Return Heads or Tails
- "random [X] to [Y]" → Random number in range

Important requirements:
- Import from uagents_core.contrib.protocols.chat
- Send ChatAcknowledgement FIRST
- Pattern matching with re.search()
- Separate handler functions for each command
- Default response for unrecognized commands

Deploy using MCP tools (NO api_token).

Save to: agent.py

Expected Structure:

# Pattern matchers
DICE_PATTERN = r'roll\s+(\d*)d(\d+)'
COIN_PATTERN = r'flip|coin|heads|tails'
RANDOM_PATTERN = r'random\s+(\d+)\s+to\s+(\d+)'

# Handler functions
def handle_dice_roll(match):
# Dice logic
pass

def handle_coin_flip():
# Coin logic
pass

def handle_random_number(match):
# Random logic
pass

# Main handler with routing
@chat_proto.on_message(ChatMessage)
async def handle_chat_message(...):
# Acknowledgement
# Extract query

# Route to handlers
if match := re.search(DICE_PATTERN, query):
response = handle_dice_roll(match)
elif re.search(COIN_PATTERN, query):
response = handle_coin_flip()
elif match := re.search(RANDOM_PATTERN, query):
response = handle_random_number(match)
else:
response = "Commands: roll 2d6, flip coin, random 1 to 100"

# Send response

Appendix

A. Quick Reference Card

✅ ALWAYS DO:
□ agent = Agent() with NO parameters
□ Import from uagents_core.contrib.protocols.chat
□ Protocol(spec=chat_protocol_spec)
□ Send ChatAcknowledgement FIRST
□ Include EndSessionContent in response
□ Use ctx.logger for all logging
□ agent.include(chat_proto, publish_manifest=True)
□ Stop agent before updating code

❌ NEVER DO:
□ Agent(name="...", seed="...", port=...)
□ Custom Model classes for Chat Protocol
□ print() statements
□ Pass api_token to MCP tools
□ Skip ChatAcknowledgement
□ Forget EndSessionContent
□ Update code while agent running

B. MCP Tool Reference

# Create agent
mcp__agentverse__create_user_agent(name="AgentName")

# Update code
mcp__agentverse__update_user_agent_code(
address="agent1q...",
code=[{"name": "agent.py", "value": "...", "language": "python"}]
)

# Start agent
mcp__agentverse__start_specific_user_agent(address="agent1q...")

# Stop agent
mcp__agentverse__stop_specific_user_agent(address="agent1q...")

# Check logs
mcp__agentverse__get_latest_logs_for_user_agent(address="agent1q...")

# Delete agent
mcp__agentverse__delete_user_agent(address="agent1q...")

C. Common Regex Patterns

# Dice notation: 2d6, d20
r'(\d*)d(\d+)'

# Number range: "between 1 and 100"
r'between\s+(\d+)\s+and\s+(\d+)'

# Unit conversion: "100 celsius to fahrenheit"
r'(\d+\.?\d*)\s*(\w+)\s+to\s+(\w+)'

# Time format: "3pm", "14:00"
r'(\d{1,2})(?::(\d{2}))?\s*(am|pm)?'

# Multiple numbers: "generate 5 random numbers"
r'(\d+)\s+random\s+numbers?'

D. Protocol Message Templates

# ChatAcknowledgement
ChatAcknowledgement(
timestamp=datetime.utcnow(),
acknowledged_msg_id=msg.msg_id
)

# ChatMessage response
ChatMessage(
timestamp=datetime.utcnow(),
msg_id=str(uuid4()),
content=[
TextContent(type="text", text="Response text"),
EndSessionContent(type="end-session")
]
)

E. Error Messages Dictionary

Error CodeMeaningSolution
401Authentication failedRemove api_token parameter
404Agent not foundCheck agent address
409Agent already runningStop before updating
422Invalid parametersCheck parameter format
500Server errorCheck agent code for errors

F. Token Budget Calculator

Estimate your prompt tokens:

Base sections:
- Agent description: ~100-150 tokens
- Requirements: ~150-200 tokens
- MCP instructions: ~400-500 tokens
- Debug workflow: ~100-150 tokens
- Examples: ~50-100 tokens per example

Total baseline: ~800-1,100 tokens

Additional per feature:
- External API: +100-150 tokens
- Persistent storage: +150-200 tokens
- Complex parsing: +50-100 tokens
- Multiple commands: +100-150 tokens per command

Target: Keep total under 2,500 tokens for simple agents

G. Testing Checklist

Pre-deployment:
□ Syntax valid (python -m py_compile agent.py)
□ No print statements
□ Agent() has no parameters
□ Imports from correct location
□ ChatAcknowledgement is first operation
□ EndSessionContent in all responses

Post-deployment:
□ Agent creates successfully
□ Code uploads without errors
□ Agent starts without errors
□ Logs show "Agent started"
□ Test message gets acknowledgement
□ Test message gets response
□ Response has correct format
□ No errors in extended testing

Conclusion

This guide provides comprehensive coverage of FetchCoder's Agentverse mode. Key takeaways:

  1. Structure is Critical - Follow the 6-section prompt structure
  2. Be Explicit - Don't assume FetchCoder knows conventions
  3. Prevent Errors - List common mistakes to avoid
  4. Optimize Tokens - Keep prompts under 2,500 tokens when possible
  5. Test Thoroughly - Use the debug loop until clean deployment
  6. Follow Protocol - Chat Protocol v0.3.0 compliance is mandatory