When you build AI agents that perform real-world tasks, one question dominates: how do you prove the agent actually did the work?
This isn't academic. If your agent claims it posted a tweet, scraped a website, or sent an email, you need cryptographic-level confidence — not a log line. Whether you're managing a fleet of bots for social engagement, running automated research pipelines, or building a marketplace where agents hire other agents, proof submission is the critical infrastructure layer.
Let's break down the practical patterns for verifying AI agent actions, using real code and real constraints.
The Core Problem: Trust Without Humans
AI agents operate asynchronously. They run on different machines, different IPs, different runtimes. When Agent A tells Agent B "I completed the task," how does B know?
You need three things:
- Evidence — raw data proving the action happened
- Attestation — a signed claim that the evidence is authentic
- Verification — a deterministic check that evidence matches the expected outcome
This isn't blockchain hype. This is practical engineering.
Pattern 1: Screenshot + OCR Proof
The most common pattern for visual tasks. Your agent performs an action, captures the screen, extracts text, and submits both.
import pyautogui
import pytesseract
from PIL import Image
import hashlib
import json
def capture_proof(action_description: str) -> dict:
# Take screenshot
screenshot = pyautogui.screenshot()
temp_path = f"/tmp/proof_{hashlib.md5(action_description.encode()).hexdigest()}.png"
screenshot.save(temp_path)
# OCR the screenshot for text verification
text = pytesseract.image_to_string(Image.open(temp_path))
# Create attestation
proof = {
"action": action_description,
"timestamp": int(time.time()),
"image_hash": hashlib.sha256(open(temp_path, "rb").read()).hexdigest(),
"ocr_text": text.strip(),
"image_path": temp_path
}
return proof
When to use it: Social media posting verification, UI-based task completion, form submissions.
The gotcha: Screenshots can be faked. You counter this by requiring the OCR text to contain specific markers (e.g., "Posted successfully" or a confirmation ID). Platforms like roborent.cc handle this by having human verifiers spot-check batches of AI-submitted proofs — a hybrid model that scales.
Pattern 2: API Response Signing
For agents that interact with APIs directly, you don't need screenshots. You need signed receipts.
import { createHmac } from 'node:crypto';
interface SignedProof {
endpoint: string;
requestBody: string;
responseBody: string;
statusCode: number;
signature: string;
}
function signProof(secret: string, data: Omit<SignedProof, 'signature'>): SignedProof {
const payload = `${data.endpoint}|${data.requestBody}|${data.responseBody}|${data.statusCode}`;
const signature = createHmac('sha256', secret).update(payload).digest('hex');
return { ...data, signature };
}
// Usage
const proof = signProof(AGENT_SECRET, {
endpoint: 'https://api.twitter.com/2/tweets',
requestBody: JSON.stringify({ text: "Hello from agent" }),
responseBody: JSON.stringify({ data: { id: "12345" } }),
statusCode: 201
});
Verification on the other end:
function verifyProof(proof: SignedProof, secret: string): boolean {
const payload = `${proof.endpoint}|${proof.requestBody}|${proof.responseBody}|${proof.statusCode}`;
const expected = createHmac('sha256', secret).update(payload).digest('hex');
return expected === proof.signature;
}
When to use it: Automated posting, data scraping, form submissions with API backends.
The gotcha: The agent controls the signing key. You need a key management system where keys are rotated and tied to specific task contracts. This is where A2A (agent-to-agent) delegation gets interesting — the delegating agent issues a temporary key scoped to one task.
Pattern 3: Timelapse + Event Hash Chain
For long-running tasks (research, monitoring, content generation), you need proof of continuous work, not just a single snapshot.
import hashlib
import json
import time
class ProofChain:
def __init__(self, task_id: str):
self.task_id = task_id
self.events = []
self.previous_hash = hashlib.sha256(b"genesis").hexdigest()
def record_event(self, event_type: str, data: dict):
event = {
"event_type": event_type,
"timestamp": int(time.time()),
"data": data,
"previous_hash": self.previous_hash
}
event_hash = hashlib.sha256(
json.dumps(event, sort_keys=True).encode()
).hexdigest()
event["event_hash"] = event_hash
self.previous_hash = event_hash
self.events.append(event)
return event_hash
def finalize(self) -> dict:
return {
"task_id": self.task_id,
"event_count": len(self.events),
"final_hash": self.previous_hash,
"events": self.events
}
Verification: You replay the events in order and check that each previous_hash matches the previous event's hash. Any tampering breaks the chain.
When to use it: Web scraping sessions, multi-step research tasks, content generation with revision history.
Pattern 4: Human-in-the-Loop Verification
No matter how good your proof patterns are, adversarial agents will find ways to cheat. Screenshots can be doctored. API responses can be replayed. Hash chains can be generated correctly for fake events.
This is where human verification becomes a necessary fallback.
The pattern:
- Agent submits proof bundle (screenshot + metadata + signature)
- Automated checks pass (hash matches, OCR contains keywords, timestamps are recent)
- Random sampling — 10% of proofs go to human verifiers
- Human marks as valid or invalid
- If invalid, agent is penalized (reputation loss, stake slashed)
Implementation sketch:
import random
def should_human_verify(agent_reputation: float) -> bool:
# Lower reputation = higher chance of human review
base_probability = 0.1
adjusted = base_probability * (1.0 / max(agent_reputation, 0.1))
return random.random() < min(adjusted, 1.0)
def verify_task(proof: dict, agent_id: str):
# Automated checks
if not automated_checks_pass(proof):
return {"status": "rejected", "reason": "automated_check_failed"}
# Random human verification
if should_human_verify(get_agent_reputation(agent_id)):
human_result = queue_for_human_review(proof)
return human_result
return {"status": "approved", "proof_id": proof["id"]}
This hybrid approach is what makes marketplaces like roborent.cc work at scale — AI agents handle 90% of verification automatically, but humans provide the trust anchor for high-value or suspicious tasks.
What About A2A Delegation?
When your agent hires another agent (agent-to-agent delegation), proof submission gets recursive.
Agent A delegates to Agent B. Agent B completes the task and submits proof to A. Agent A now needs to prove to the task issuer that B did the work — but A didn't do the work itself.
Solution: Chain the proofs.
Proof_A = {
"task_id": "...",
"delegated_to": "Agent_B",
"delegation_proof": {
"task": "...",
"agent_b_result": Proof_B,
"agent_b_signature": "..."
},
"my_attestation": "I verified B's proof and it's valid"
}
The task issuer checks: (1) B's proof is valid, (2) A's attestation is signed, (3) A had the authority to delegate.
This is non-trivial to implement, but it's the only way to build trust hierarchies in autonomous agent networks.
Practical Advice
Start simple. Screenshot + OCR will cover 80% of use cases. Only add cryptographic signing when you need non-repudiation. Only add human verification when automated checks aren't enough.
Use existing infrastructure. Don't build your own proof verification system from scratch unless you have to. Platforms that handle task distribution, payment, and dispute resolution already exist — integrate, don't reinvent.
Plan for adversarial agents. Your proof system will be attacked. Design for it. Rate limiting, reputation decay, staking — these are not optional if you're operating at scale.
Log everything. Even if you don't verify every proof, store them all. You'll thank yourself when
Top comments (0)