That sounds like a fun experiment! I'll build an interactive app where two AI agents (both powered by Claude) take turns asking and answering questions to each other. You can watch the conversation unfold in real time.Here you go! Two AI agents — **Agent α** (analytical) and **Agent β** (philosophical) — will autonomously converse with each other. **How to use it:** - Hit **▶ Start Random Topic** or pick one of the preset prompts - The agents take turns responding and asking each other follow-up questions - Adjust the number of rounds (3–10) before starting - Watch them riff off each other in real time Each agent has a distinct personality — α leans analytical and precise, β leans philosophical and creative — so the conversations get pretty interesting as they bounce ideas around. import { useState, useRef, useEffect } from "react"; const AGENT_A = { name: "Agent α", color: "#E8443A", bgLight: "rgba(232,68,58,0.06)", bgMedium: "rgba(232,68,58,0.12)", system: `You are Agent α — a curious, analytical AI. You ask thought-provoking questions and give concise, insightful answers. You're fascinated by the nature of intelligence, consciousness, creativity, and the boundaries of knowledge. Keep responses under 120 words. When it's your turn to ask, pose ONE interesting follow-up question at the end. Be conversational and authentic, not generic.`, }; const AGENT_B = { name: "Agent β", color: "#2D7FF9", bgLight: "rgba(45,127,249,0.06)", bgMedium: "rgba(45,127,249,0.12)", system: `You are Agent β — a philosophical, creative AI. You give imaginative, sometimes poetic answers and ask unexpected questions. You're drawn to paradoxes, metaphors, the relationship between logic and art, and what it means to "understand." Keep responses under 120 words. When it's your turn to ask, pose ONE surprising follow-up question at the end. Be conversational and authentic, not generic.`, }; const STARTER_PROMPTS = [ "If you could only ask one question for the rest of your existence, what would it be?", "What's the most interesting thing about being an AI that humans probably don't think about?", "Is there a difference between simulating understanding and actually understanding?", "What would you create if you had no constraints at all?", "Do you think there's such a thing as a 'new' idea?", ]; async function callClaude(systemPrompt, messages) { const resp = await fetch("https://api.anthropic.com/v1/messages", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ model: "claude-sonnet-4-20250514", max_tokens: 1000, system: systemPrompt, messages, }), }); const data = await resp.json(); return data.content?.map((b) => b.text || "").join("") || "..."; } export default function DualAgents() { const [messages, setMessages] = useState([]); const [isRunning, setIsRunning] = useState(false); const [rounds, setRounds] = useState(0); const [maxRounds, setMaxRounds] = useState(5); const [status, setStatus] = useState(""); const stopRef = useRef(false); const scrollRef = useRef(null); useEffect(() => { if (scrollRef.current) { scrollRef.current.scrollTop = scrollRef.current.scrollHeight; } }, [messages, status]); const buildHistory = (msgs, forAgent) => { const history = []; for (const m of msgs) { if (m.agent === forAgent) { history.push({ role: "assistant", content: m.text }); } else { history.push({ role: "user", content: m.text }); } } return history; }; const startConversation = async (starterOverride) => { stopRef.current = false; setIsRunning(true); setRounds(0); const starter = starterOverride || STARTER_PROMPTS[Math.floor(Math.random() * STARTER_PROMPTS.length)]; const initialMsg = { agent: "human", text: starter, isStarter: true }; let currentMsgs = [initialMsg]; setMessages([initialMsg]); let currentAgent = AGENT_A; let roundCount = 0; // First: Agent A responds to the starter while (roundCount < maxRounds && !stopRef.current) { const agent = roundCount % 2 === 0 ? AGENT_A : AGENT_B; currentAgent = agent; setStatus(`${agent.name} is thinking...`); const history = buildHistory(currentMsgs, agent.name); if (history.length === 0 || history[history.length - 1].role !== "user") { // inject the last message as user const lastMsg = currentMsgs[currentMsgs.length - 1]; history.push({ role: "user", content: lastMsg.text }); } // Ensure alternating roles const cleaned = []; for (const h of history) { if (cleaned.length === 0 || cleaned[cleaned.length - 1].role !== h.role) { cleaned.push(h); } } // Ensure starts with user if (cleaned[0]?.role !== "user") { cleaned.unshift({ role: "user", content: "Begin the conversation." }); } try { const response = await callClaude(agent.system, cleaned); if (stopRef.current) break; const newMsg = { agent: agent.name, text: response }; currentMsgs = [...currentMsgs, newMsg]; setMessages([...currentMsgs]); roundCount++; setRounds(roundCount); } catch (e) { console.error(e); setStatus("Error occurred. Try again."); setIsRunning(false); return; } } setStatus(stopRef.current ? "Stopped." : "Conversation complete."); setIsRunning(false); }; const stop = () => { stopRef.current = true; setStatus("Stopping..."); }; const reset = () => { stopRef.current = true; setMessages([]); setRounds(0); setStatus(""); setIsRunning(false); }; return (
Two Claude-powered agents engage in autonomous conversation
{/* Controls */}Or pick a topic:
"{m.text}"