Dos frameworks dominan extremos distintos del stack moderno y comparten más principios de diseño de lo que podrías esperar. Astro entrega HTML estático por defecto y solo carga JavaScript cuando se lo pides explícitamente. Agno crea agentes de IA en Python puro, sin grafos, sin cadenas y sin complicaciones: solo un agente que hace aquello para lo que lo configuras. Ambos son extremadamente minimalistas respecto a lo que envían al runtime, y ambos están diseñados para que tú, o un generador de código con IA, puedan obtener un resultado funcional en menos de veinte líneas.
Este artículo explica qué hace excepcional a cada framework y después parte de una página de Astro con un solo componente y un agente de Agno de cinco líneas para llegar a un dashboard de investigación multiagente servido a través de una API de producción.
TL;DR
- Astro es un framework que prioriza el contenido estático y no envía JavaScript por defecto. Islands Architecture significa que solo hidratas los componentes interactivos que realmente necesitas, lo que se traduce en puntuaciones de Lighthouse de 95–100 y costos de hosting cercanos a cero.
- Astro 5 incorporó la Content Layer API y Server Islands. Astro 6 (enero de 2026) reconstruyó el servidor de desarrollo sobre el runtime
workerdde Cloudflare después de que Cloudflare adquiriera Astro, logrando verdadera paridad entre desarrollo y producción. - Agno es un framework de Python para crear agentes de IA y sistemas multiagente. Es independiente del modelo, instancia agentes 529× más rápido que LangGraph y permite crear agentes listos para producción en ~20 líneas.
- La primitiva central de Agno es un objeto
Agent: asígnale un modelo, una lista de herramientas, memoria opcional e instrucciones. Para trabajos más grandes, combina agentes en unTeamy encapsúlalos en unWorkflow. - Los dos frameworks se complementan de forma natural: Astro renderiza el frontend de forma estática, mientras Agno impulsa los agentes del backend que le proporcionan contenido, responden preguntas o automatizan workflows.
Parte 1 — Astro: el framework que no confía en JavaScript
La idea central
La mayoría de los frameworks web envían un bundle de JavaScript al navegador y luego hidratan toda la página desde cero. Astro invierte este comportamiento por defecto. Cada componente .astro se renderiza como HTML puro en el servidor durante el build. El JavaScript solo llega al navegador si marcas explícitamente un componente con una directiva client:*.
Esto no es solo una opción de configuración. Es la arquitectura. No puedes enviar accidentalmente un bundle de React a una página que no lo necesita.
---
// src/pages/index.astro
// This file produces plain HTML. No JS bundle.
import ArticleCard from '../components/ArticleCard.astro';
import { getCollection } from 'astro:content';
const articles = await getCollection('articles');
---
<html>
<body>
{articles.map(a => <ArticleCard article={a} />)}
</body>
</html>
Islands Architecture
Cuando sí necesitas interactividad —un widget de búsqueda, un control para activar el modo oscuro o un botón para compartir—, escribes un componente de React (o Vue, Svelte, Solid, Preact) y lo montas como una isla. Cada isla se hidrata de manera independiente. El resto de la página permanece como HTML estático.
---
// A page that is mostly static, with one interactive island
import SearchBar from '../components/SearchBar.tsx';
import StaticHeader from '../components/StaticHeader.astro';
---
<html>
<body>
<!-- Static — zero JS cost -->
<StaticHeader />
<!-- Interactive island — hydrates only this component -->
<SearchBar client:visible />
</body>
</html>
La directiva client:visible significa que Astro ni siquiera descargará el bundle de JavaScript hasta que el componente entre en el viewport al hacer scroll. Otras directivas te dan un control más preciso:
| Directiva | Cuándo se carga JS |
|---|---|
client:load | Inmediatamente al cargar la página |
client:idle | Cuando el navegador está inactivo |
client:visible | Cuando el elemento entra en el viewport |
client:media="(max-width: 768px)" | Cuando se cumple una media query |
client:only="react" | Solo en el cliente, sin SSR |
Content Collections
Content Collections es el sistema de Astro con seguridad de tipos para administrar archivos markdown, MDX, YAML y JSON. Define un esquema con Zod y Astro valida cada entrada durante el build.
// src/content.config.ts
import { defineCollection, z } from 'astro:content';
const articles = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
excerpt: z.string(),
tags: z.array(z.string()),
date: z.string(),
}),
});
export const collections = { articles };
Consulta y renderiza el contenido en cualquier página sin tocar una base de datos:
---
import { getCollection, getEntry } from 'astro:content';
// All articles, sorted by date
const articles = await getCollection('articles');
const sorted = articles.sort((a, b) =>
new Date(b.data.date).getTime() - new Date(a.data.date).getTime()
);
---
View Transitions
La API View Transitions de Astro convierte un sitio estático de varias páginas en algo que se siente como una aplicación de una sola página —con animaciones fluidas entre rutas, transformación de elementos y estado persistente de la interfaz— con dos líneas de código.
---
// src/layouts/BaseLayout.astro
import { ViewTransitions } from 'astro:transitions';
---
<head>
<ViewTransitions />
</head>
Marca los elementos con transition:name para transformarlos entre páginas:
<!-- Article card on index page -->
<img src={article.cover} transition:name={`cover-${article.slug}`} />
<!-- Same image on the article detail page — Astro morphs it smoothly -->
<img src={article.cover} transition:name={`cover-${article.slug}`} />
Para marzo de 2026, la API View Transitions cuenta con soporte nativo en >85% de los navegadores, y Astro recurre a cambios instantáneos de página en los navegadores que no la soportan.
Server Islands (Astro 5+)
Server Islands te permite diferir el renderizado de componentes individuales al servidor mientras el resto de la página se entrega como HTML estático. Es la herramienta adecuada para contenido personalizado o que depende del momento dentro de una página por lo demás estática.
---
import UserGreeting from '../components/UserGreeting.astro';
import StaticHero from '../components/StaticHero.astro';
---
<html>
<body>
<!-- Pre-rendered at build time -->
<StaticHero />
<!-- Rendered on-demand per request, injected after the static shell loads -->
<UserGreeting server:defer>
<span slot="fallback">Loading your profile…</span>
</UserGreeting>
</body>
</html>
Astro 6 y la adquisición por Cloudflare
En enero de 2026, Cloudflare adquirió The Astro Technology Company. El framework sigue siendo de código abierto y tiene licencia MIT. Tres semanas después de la adquisición, llegó la beta de Astro 6 con el servidor de desarrollo reconstruido sobre workerd, el runtime de código abierto de Cloudflare Workers. Esto significa que tu npm run dev local y tu despliegue de producción en Cloudflare Pages ahora se ejecutan en el mismo runtime exacto. Se acabaron las sorpresas de «funciona en mi máquina» en el edge.
Benchmarks de rendimiento
Las migraciones reales reportan de forma consistente:
- Puntuaciones de rendimiento en Lighthouse: 95–100 (frente a 85–95 para sitios comparables de Next.js)
- Time to First Byte: más rápido en páginas estáticas porque no hay renderizado en el servidor al momento de la solicitud
- Costo de hosting: $0/mes en el plan gratuito de Cloudflare Pages para la mayoría de los sitios de contenido
- Total Blocking Time: cercano a cero cuando las islas se cargan de forma diferida
Parte 2 — Agno: agentes de IA sin complicaciones
Qué es Agno
Agno es un framework de Python de código abierto para crear agentes de IA y sistemas multiagente. Su filosofía de diseño es una respuesta directa a la complejidad de LangChain y LangGraph: sin grafos, sin cadenas, sin decoradores, sin LCEL: solo Python.
Un agente en Agno es un objeto. Le asignas un modelo, una lista de herramientas, memoria opcional e instrucciones. Llamas a agent.run() o agent.print_response(). Esa es toda la API para el 90% de los casos de uso.
Las cifras de rendimiento son notables: los agentes de Agno se instancian 529× más rápido que LangGraph y 57× más rápido que PydanticAI en un Apple M4, según mediciones de octubre de 2025. La razón es arquitectónica: Agno no construye un grafo al momento de la instanciación. Resuelve la ruta de ejecución en tiempo de ejecución.
Por qué los generadores de código con IA adoran Agno
Los generadores de código funcionan mejor cuando la correspondencia entre la intención y el código es directa. La API de Agno se acerca a una relación 1:1:
- «Necesito un agente que busque en la web» →
Agent(tools=[DuckDuckGoTools()]) - «Necesito un agente con memoria» →
Agent(memory=AgentMemory(db=SqliteMemoryDb(...))) - «Necesito dos agentes que trabajen juntos» →
Agent(team=[agent1, agent2])
No hay clases base abstractas de las que heredar, sistemas de callbacks con los que integrarse ni estados de grafos que definir. Un asistente de IA que genera código de Agno puede concentrarse en la tarea en lugar de navegar por los patrones internos de un framework.
Parte 3 — Código: de Hello World a un dashboard de producción
Nivel 0 — Agente Hello World
El agente mínimo viable de Agno: un modelo y un prompt.
from agno.agent import Agent
from agno.models.anthropic import Claude
agent = Agent(
model=Claude(id="claude-sonnet-4-6"),
description="You are a friendly assistant.",
)
agent.print_response("What is the capital of France?")
Paris is the capital of France.
Ese es todo el programa. Sin archivos de configuración inicial, sin clases de configuración y sin inicialización del framework.
Nivel 1 — Agente con herramientas
Agrega herramientas para que el agente pueda realizar acciones reales. Agno incluye 80+ toolkits integrados.
from agno.agent import Agent
from agno.models.anthropic import Claude
from agno.tools.duckduckgo import DuckDuckGoTools
from agno.tools.yfinance import YFinanceTools
research_agent = Agent(
model=Claude(id="claude-sonnet-4-6"),
tools=[
DuckDuckGoTools(),
YFinanceTools(stock_price=True, company_news=True),
],
instructions=[
"Always cite your sources.",
"Use tables to display financial data.",
],
markdown=True,
)
research_agent.print_response(
"What is the current stock price of NVDA and what's the latest news about it?",
stream=True,
)
El agente decidirá qué herramienta llamar, la ejecutará, inspeccionará el resultado y sintetizará una respuesta final en markdown con citas, todo de forma autónoma.
Nivel 2 — Agente con memoria y almacenamiento
Dale memoria persistente al agente para que pueda recordar datos entre sesiones.
from agno.agent import Agent
from agno.models.anthropic import Claude
from agno.memory.v2.db.sqlite import SqliteMemoryDb
from agno.memory.v2.memory import Memory
from agno.storage.sqlite import SqliteStorage
# Persistent memory backed by SQLite
memory = Memory(
db=SqliteMemoryDb(table_name="user_memories", db_file="agent.db"),
delete_memories=True,
clear_memories=True,
)
agent = Agent(
model=Claude(id="claude-sonnet-4-6"),
memory=memory,
# Persist conversation sessions across restarts
storage=SqliteStorage(table_name="sessions", db_file="agent.db"),
add_history_to_messages=True,
num_history_runs=5,
enable_user_memories=True,
)
# First session
agent.print_response(
"My name is Luis and I prefer Python over TypeScript.",
user_id="luis",
session_id="session-001",
)
# A later session — the agent remembers the preference
agent.print_response(
"What language should I use for my next backend project?",
user_id="luis",
session_id="session-002",
)
# → "Based on your preference for Python, I'd recommend FastAPI or Django..."
Nivel 3 — Equipo multiagente
Combina agentes especializados en un equipo. El coordinador del equipo delega subtareas y sintetiza los resultados.
from agno.agent import Agent
from agno.models.anthropic import Claude
from agno.models.openai import OpenAIChat
from agno.tools.duckduckgo import DuckDuckGoTools
from agno.tools.yfinance import YFinanceTools
from agno.tools.newspaper4k import Newspaper4kTools
# Specialist 1: web researcher
web_agent = Agent(
name="Web Researcher",
role="Search the web for current information and news.",
model=OpenAIChat(id="gpt-4o-mini"),
tools=[DuckDuckGoTools(), Newspaper4kTools()],
instructions=["Always include the source URL.", "Summarize key points concisely."],
markdown=True,
)
# Specialist 2: financial analyst
finance_agent = Agent(
name="Finance Analyst",
role="Retrieve and analyze financial data.",
model=OpenAIChat(id="gpt-4o-mini"),
tools=[YFinanceTools(
stock_price=True,
analyst_recommendations=True,
company_info=True,
company_news=True,
)],
instructions=["Use tables to display stock data.", "Include analyst consensus."],
markdown=True,
)
# Team coordinator: delegates and synthesizes
team_lead = Agent(
name="Research Lead",
team=[web_agent, finance_agent],
model=Claude(id="claude-sonnet-4-6"),
instructions=[
"Delegate web research to the Web Researcher.",
"Delegate financial analysis to the Finance Analyst.",
"Synthesize a comprehensive final report with clear sections.",
"Always include sources.",
],
markdown=True,
)
team_lead.print_response(
"Write a comprehensive investment analysis for NVDA including recent news, "
"current financials, and analyst recommendations.",
stream=True,
)
Nivel 4 — Dashboard completo de workflow
Un workflow de producción que orquesta agentes a través de pasos definidos: investigación → borrador → revisión → publicación. Este es el patrón detrás de los pipelines de contenido autónomos, los reportes automatizados y los dashboards basados en datos.
from agno.agent import Agent
from agno.workflow import Workflow, RunResponse
from agno.models.anthropic import Claude
from agno.models.openai import OpenAIChat
from agno.tools.duckduckgo import DuckDuckGoTools
from agno.tools.newspaper4k import Newspaper4kTools
from agno.storage.sqlite import SqliteStorage
from pydantic import BaseModel
from typing import Iterator
import json
# --- Schemas ---
class ResearchBrief(BaseModel):
topic: str
key_findings: list[str]
sources: list[str]
class DraftArticle(BaseModel):
title: str
body: str
summary: str
# --- Agents ---
researcher = Agent(
name="Researcher",
model=OpenAIChat(id="gpt-4o-mini"),
tools=[DuckDuckGoTools(), Newspaper4kTools()],
instructions=["Find authoritative sources.", "Extract key facts and statistics."],
response_model=ResearchBrief,
)
writer = Agent(
name="Writer",
model=Claude(id="claude-sonnet-4-6"),
instructions=[
"Write in a clear, technical but accessible style.",
"Structure articles with Introduction, Body sections, and Conclusion.",
"Cite sources inline.",
],
response_model=DraftArticle,
)
editor = Agent(
name="Editor",
model=Claude(id="claude-opus-4-6"),
instructions=[
"Check for factual accuracy and logical consistency.",
"Improve clarity and flow.",
"Flag any claims that need stronger sourcing.",
],
)
# --- Workflow ---
class ContentPipeline(Workflow):
description: str = "Research → Draft → Edit → Publish pipeline"
def run(self, topic: str) -> Iterator[RunResponse]:
# Step 1: Research
yield RunResponse(content=f"Researching: {topic}…")
research_result = researcher.run(
f"Research this topic thoroughly: {topic}"
)
brief: ResearchBrief = research_result.content
# Step 2: Write draft
yield RunResponse(content="Writing first draft…")
draft_result = writer.run(
f"Write an article based on this research:\n{brief.model_dump_json(indent=2)}"
)
draft: DraftArticle = draft_result.content
# Step 3: Editorial review
yield RunResponse(content="Reviewing draft…")
review = editor.run(
f"Review and improve this article:\n\nTitle: {draft.title}\n\n{draft.body}"
)
# Step 4: Final output
yield RunResponse(
content=json.dumps({
"title": draft.title,
"summary": draft.summary,
"sources": brief.sources,
"body": review.content,
}),
event="workflow_completed",
)
# --- Run it ---
pipeline = ContentPipeline(
storage=SqliteStorage(table_name="pipeline_sessions", db_file="pipeline.db"),
)
for response in pipeline.run("The impact of Cloudflare's acquisition of Astro"):
print(response.content)
Para servirlo como una API REST con gestión de sesiones, encapsúlalo en AgentOS:
from agno.app.agentOS import AgentOS
from agno.agent import Agent
# Expose agents + workflows as a single API
agent_os = AgentOS(
description="Content Intelligence Platform",
agents=[researcher, writer, editor],
workflows=[pipeline],
)
# Serves at http://localhost:8000
# POST /v1/agents/researcher/runs
# POST /v1/workflows/content-pipeline/runs
agent_os.serve(app="main:agent_os", reload=True)
Parte 4 — Combinar Astro y Agno
La división natural: Astro se encarga del frontend y Agno de la capa de inteligencia.
Browser
└─ Astro (static HTML + React islands for interactivity)
└─ Calls AgentOS API for dynamic content
└─ Agno agents handle research, Q&A, and workflows
Un ejemplo concreto: un sitio de Astro con una isla de preguntas y respuestas en vivo respaldada por un agente de Agno.
// src/components/AskAgent.tsx — React island
import { useState } from 'react';
export default function AskAgent() {
const [question, setQuestion] = useState('');
const [answer, setAnswer] = useState('');
const [loading, setLoading] = useState(false);
async function ask() {
setLoading(true);
const res = await fetch('https://your-agentOS-api.example.com/v1/agents/assistant/runs', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: question }),
});
const data = await res.json();
setAnswer(data.content);
setLoading(false);
}
return (
<div className="ask-agent">
<input
value={question}
onChange={e => setQuestion(e.target.value)}
placeholder="Ask anything…"
/>
<button onClick={ask} disabled={loading}>
{loading ? 'Thinking…' : 'Ask'}
</button>
{answer && <div className="answer">{answer}</div>}
</div>
);
}
---
// src/pages/index.astro
import AskAgent from '../components/AskAgent.tsx';
---
<html>
<body>
<h1>My Astro + Agno Site</h1>
<!-- Static content — zero cost -->
<p>This page is pre-rendered HTML.</p>
<!-- Interactive AI island — loads only when visible -->
<AskAgent client:visible />
</body>
</html>
Por qué combinar estos dos frameworks
Tanto Astro como Agno son respuestas al mismo problema de fondo: frameworks que hacen demasiado por defecto.
Astro cuestiona la idea de que cada página web necesita un runtime de JavaScript en el navegador. El resultado son páginas más rápidas, mejor SEO, menores costos de hosting y despliegues más sencillos.
Agno cuestiona la idea de que los agentes de IA necesitan abstracciones complejas de grafos, sistemas de callbacks y configuraciones extensas. El resultado son agentes más rápidos de escribir, más fáciles de leer y más sencillos de depurar.
Al combinarlos, obtienes un stack con configuraciones predeterminadas de rendimiento siempre correctas en ambos extremos —HTML estático hasta que necesites interactividad, agentes ligeros de Python hasta que necesites coordinación— y en el que la distancia entre una idea y el código funcional se mide en líneas, no en días.
Fuentes
- Astro Framework — Sitio oficial
- Documentación de Astro
- Análisis en profundidad de Islands Architecture de Astro — Leapcell
- Astro en 2026: por qué supera a Next.js para sitios de contenido — DEV Community
- Novedades de Astro — enero de 2026
- Novedades de Astro — febrero de 2026
- Guía del framework Astro: rendimiento, islas y SSR (2026) — Alex Bobes
- Guía de View Transitions de Astro — EastonDev
- Next.js vs Astro: ¿qué framework deberías elegir en 2026? — Cipher Projects
- Astro vs Next.js: sitios de contenido vs aplicaciones full-stack en 2026 — Out Plane
- Agno — Sitio oficial
- Documentación de Agno
- Repositorio de Agno en GitHub
- Paquete de Agno en PyPI
- Agno: el framework de agentes para equipos de Python — Blog de WorkOS
- Entender Agno: un framework multiagente rápido y escalable — DigitalOcean
- Agno + Groq: crea agentes multimodales rápidos — Documentación de Groq
- Análisis en profundidad de frameworks agénticos (parte 2): Agno — Medium
- Crear una aplicación de trading multiagente con Agno — Medium
- Los 10 principales frameworks de agentes de IA en 2026 — Genta.dev
- Strapi: explicación de Islands Architecture de Astro