prompt-guide
Version: 1.0 Last Updated: October 2025 Model: ASI1-Mini optimized
Table of Contents
- Introduction
- Understanding Agentverse Mode
- Core Concepts
- Prompt Structure
- Best Practices
- Common Patterns
- Deployment Workflow
- Troubleshooting
- Advanced Techniques
- 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
Feature | General Mode | Agentverse Mode |
---|---|---|
Purpose | General coding tasks | Agentverse agent creation |
Protocol | N/A | Chat Protocol v0.3.0 required |
Deployment | Manual | Automated via MCP tools |
Agent Init | Flexible | Agent() only (no params) |
Storage | N/A | Stateless by default |
Tools | All available | Agentverse-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:
- Receive
ChatMessage
from user - IMMEDIATELY send
ChatAcknowledgement
(< 100ms) - Process the message
- Send
ChatMessage
response withEndSessionContent
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 agentmcp__agentverse__update_user_agent_code
- Upload codemcp__agentverse__start_specific_user_agent
- Start agentmcp__agentverse__stop_specific_user_agent
- Stop agentmcp__agentverse__get_latest_logs_for_user_agent
- Check logsmcp__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
notprint
)
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:
-
Use Imperative Language
❌ "You should create an agent that will roll dice"
✅ "Create a dice rolling agent" -
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" -
Consolidate Lists
❌ "- Import ChatMessage
- Import ChatAcknowledgement
- Import TextContent
- Import EndSessionContent"
✅ "- Import ChatMessage, ChatAcknowledgement, TextContent, EndSessionContent" -
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:
- Deploy to test environment
- Send test messages
- Check response format
- Verify acknowledgements
- Monitor logs for warnings
- 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 Code | Meaning | Solution |
---|---|---|
401 | Authentication failed | Remove api_token parameter |
404 | Agent not found | Check agent address |
409 | Agent already running | Stop before updating |
422 | Invalid parameters | Check parameter format |
500 | Server error | Check 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:
- Structure is Critical - Follow the 6-section prompt structure
- Be Explicit - Don't assume FetchCoder knows conventions
- Prevent Errors - List common mistakes to avoid
- Optimize Tokens - Keep prompts under 2,500 tokens when possible
- Test Thoroughly - Use the debug loop until clean deployment
- Follow Protocol - Chat Protocol v0.3.0 compliance is mandatory