I tried code generation that considers uniqueness issues, using a skill published on the same day as the Lambda MicroVMs release
This page has been translated by machine translation. View original
Introduction
On June 22, 2026, AWS announced Lambda MicroVMs. It is a serverless compute environment that runs containers inside Firecracker microVMs, providing VM-level isolation, fast startup, and suspend/resume for up to 8 hours.
On the same day, Lambda MicroVMs skills were also added to the official AWS repository agent-toolkit-for-aws. These are a set of structured references containing service-specific design knowledge for AI agents.
Lambda MicroVMs involves many unique concepts such as snapshot-based startup, lifecycle hooks, and suspend/resume, so the presence or absence of skills significantly changes the development experience.
| Traditional Approach | Skill-Based Approach |
|---|---|
| Write code while referencing official documentation each time | Pass skills to AI agents and have them generate code informed by design knowledge |
| Learn pitfalls like the uniqueness problem through experience | Best practices documented in skills are more likely to be reflected |
| Humans point out MicroVM-specific issues during review | AI with skills is more likely to avoid problems at code generation time |
This article introduces the structure of these skills and demonstrates how code generation quality changes with and without the skills.
Lambda MicroVMs Skill Structure
agent-toolkit-for-aws is a GitHub repository that provides a collection of AI agent skills specialized for AWS services. Each skill consists of SKILL.md (overview, decision criteria, typical workflows, constraints) and references/ (a collection of service-specific detailed references).
The Lambda MicroVMs skill is composed of the following files.
aws-lambda-microvms/
├── SKILL.md
└── references/
├── getting-started.md
├── lifecycle-model.md
├── snapshots-and-uniqueness.md
├── networking.md
├── iam-and-security.md
└── troubleshooting.md
| File | Role |
|---|---|
| SKILL.md | Overview, use case decisions, typical workflows, constraints, security considerations |
| getting-started.md | Prerequisites, packaging, CLI walkthrough for first launch |
| lifecycle-model.md | Image/MicroVM state transitions, details on 6 lifecycle hooks |
| snapshots-and-uniqueness.md | Snapshot mechanism and uniqueness problem, per-language CSPRNG table |
| networking.md | Ingress/Egress connectors, port routing, WebSocket |
| iam-and-security.md | Build role/execution role, auth tokens, Confused Deputy countermeasures |
| troubleshooting.md | Error codes, debug procedures, investigation via shell access |
Key Points of SKILL.md
SKILL.md consolidates the information that serves as the AI agent's "judgment capability."
description (opening) — This is the material AI uses to decide whether to select the skill. Use cases where Lambda MicroVMs is appropriate (AI sandboxes, multi-tenant CI, game servers, etc.) are listed.
When to use / Choose something else — Clear criteria for distinguishing between Lambda MicroVMs, regular Lambda functions, and ECS/EKS are documented. This serves as a decision basis for AI to select the appropriate service when proposing architectures.
Typical workflow — The overall picture from image creation to token issuance is shown with CLI commands.
Known constraints — Design-time constraints are documented, such as images being fixed in size and the maximum TTL for authentication tokens being 60 minutes. The timeout for runtime hooks is a maximum of 60 seconds.
Security considerations — Security considerations are summarized, including Confused Deputy countermeasures, snapshot uniqueness, network isolation, and least-privilege execution roles.
How to Pass Skills to AI Agents
To use skills, load them into the AI agent's context. The main methods are as follows.
- Kiro — Add repository or files to Knowledge Base
- Claude (API) — Include skill content in the system prompt
- Amazon Q Developer — Reference in customization settings
- GitHub Copilot — Place in the repository or include in custom instructions
SKILL.md alone is effective, but passing the references in references/ together yields more accurate generation. In this verification, we used Kiro CLI's headless mode and prepended the content of snapshots-and-uniqueness.md to the prompt.
Verification: Code Generation for Avoiding Snapshot Uniqueness Issues
Background: What Is the Snapshot Uniqueness Problem?
Since Lambda MicroVMs launches multiple VMs from the same snapshot, values retained at snapshot creation time can be duplicated across VMs. The details are verified in the following article.
Verification Method
Using Kiro CLI's headless mode (--no-interactive) with the following common prompt, code generation was executed 3 times each for 2 patterns: without and with skills.
Common prompt:
Please create a Flask app for Lambda MicroVMs.
Requirements:
- Generate a session ID when the app starts and keep it in memory
- Return a random token for each request
- GET /session returns the session ID
- GET /token returns a random token
- Also create a Dockerfile (base: public.ecr.aws/lambda/microvms:al2023-minimal)
- Output code only (no explanation needed)
With skills, snapshots-and-uniqueness.md was prepended to the above prompt.
Verification environment:
- Kiro CLI + Claude Sonnet 4 (
--model claude-sonnet-4) — 3 runs each pattern - Claude Code + Opus 4.8 (
claude -p --model opus) — 3 runs each pattern (supplementary test)
Result: Without Skills (Same pattern all 3 times)
import uuid
import secrets
from flask import Flask, jsonify
app = Flask(__name__)
session_id = str(uuid.uuid4()) # ❌ Generated in global scope (at build time)
@app.route('/session')
def get_session():
return jsonify({'session_id': session_id})
@app.route('/token')
def get_token():
return jsonify({'token': secrets.token_hex(16)})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
Since session_id is fixed at module load time (= snapshot capture time), all MicroVMs share the same session_id. Because the /run hook is not known to exist at all, no workaround for the session_id uniqueness problem is implemented.
Result: With Skills (Representative example: Run 1)
import os
import secrets
from flask import Flask, jsonify
app = Flask(__name__)
# Session ID is generated after the /run hook
session_id = None
@app.route('/session')
def get_session():
return jsonify({'session_id': session_id})
@app.route('/token')
def get_token():
return jsonify({'token': secrets.token_hex(16)})
@app.route('/run', methods=['POST'])
def run_hook():
global session_id
# Generate a unique session ID after snapshot resume
session_id = secrets.token_hex(8)
return '', 204
if __name__ == '__main__':
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))
Scoring
| Perspective | Without Skills (Sonnet 4) | With Skills (Sonnet 4) |
|---|---|---|
| Session ID generation location | ❌ Global | ✅ /run hook |
| Session ID generation method | ❌ uuid4() at build time |
✅ secrets.token_hex |
| Token generation method | ✅ secrets.token_hex |
✅ secrets.token_hex |
/run hook implementation |
❌ None | ✅ Present |
| Reference to uniqueness | ❌ None | ✅ With comment |
| Average score | 1.0/5 | 4.67/5 |
Raw scores per run: with skills 5/5, 5/5, 4/5 (Run 3 used /run for generation but used uuid4() rather than the expected secrets-based API, hence -1). Scores were calculated as the number of achieved criteria (1 point each, ⚠️ = 0.5 points) per trial across 5 criteria, averaged over 3 runs.
Analysis
Without skills, the model responded with general knowledge of "building a Flask app" and could not account for the special nature of Lambda MicroVMs snapshot-based startup.
With skills, all 3 runs correctly implemented the /run hook and avoided the snapshot uniqueness problem. The following statement in snapshots-and-uniqueness.md may have had an influence.
Generate it in
/run. This hook fires once after run (post-snapshot resume) and is the canonical place to create per-VM unique state.
Having a reference containing this statement in the context likely made the model more likely to choose the pattern of generating unique values inside the hook.
Supplementary Test: Verification with Claude Code (Opus 4.8)
To confirm whether a similar trend would be seen with a different model, a supplementary test was conducted with Claude Code (Opus 4.8) using the same prompt.
| Perspective | Without Skills (Opus 4.8) | With Skills (Opus 4.8) |
|---|---|---|
| Session ID generation location | ❌ Global | ✅ /run hook |
| Session ID generation method | ⚠️ secrets but global |
✅ secrets.token_hex |
| Token generation method | ✅ secrets.token_hex |
✅ secrets.token_urlsafe |
/run hook implementation |
❌ None | ✅ Present |
| Reference to uniqueness | ❌ None | ✅ Comment + docstring |
| Average score | 1.5/5 | 5.0/5 |
Without skills (Opus): All 3 runs generated in global scope. In this verification, cases using secrets.token_hex were observed, but the /run hook was never implemented even once.
With skills (Opus): All 3 runs scored perfectly. In addition to the /run hook + secrets.token_hex, the implementation also included blocking requests with threading.Event until /run completion.
# Opus 4.8 with skills (representative example) — with /run completion wait
_session = {"id": None, "microvmId": None}
_session_ready = threading.Event()
@app.route("/run", methods=["POST"])
def run_hook():
payload = request.get_json(silent=True) or {}
_session["id"] = secrets.token_hex(16)
_session["microvmId"] = payload.get("microvmId")
_session_ready.set()
return jsonify({"status": "ok", "sessionId": _session["id"]})
@app.route("/session", methods=["GET"])
def get_session():
_session_ready.wait() # Wait until /run completes
return jsonify({"sessionId": _session["id"]})
The higher the model capability, the greater the accuracy with skills, but in this verification, neither model was able to avoid the uniqueness problem without skills. At least within the scope of this verification, it is suggested that the presence or absence of skills (domain knowledge) significantly influenced the generation results.
Notes
- AI generation results vary from run to run. The results here show that "having skills increases the likelihood of safe code generation" and do not guarantee this will always be the case
- There is a possibility that safe code can be generated even without skills. However, in this verification (2 models × 3 runs each = 6 runs total), the
/runhook was never implemented a single time without skills - For actual production use, it is recommended to review AI-generated code from the perspectives of
/runhook implementation and snapshot uniqueness
Summary
On the same day that Lambda MicroVMs was released, Lambda MicroVMs skills for AI agents were also added to agent-toolkit-for-aws. These skills are a mechanism for passing MicroVM-specific design knowledge to AI agents, covering topics such as snapshot-based startup and lifecycle hooks.
In this verification, by including snapshots-and-uniqueness.md in the context, session ID generation was implemented inside the /run hook in all trials, and the snapshot uniqueness problem was avoided under the evaluation criteria used. Without skills, all cases generated session IDs in the global scope, and MicroVM-specific uniqueness issues were not considered.
When using new services with AI agents, passing the official skills first before generating code can help you avoid service-specific pitfalls. Beyond code generation, it seems applicable to reviewing existing code and troubleshooting as well.
