Skip to content
Search

AI TALKS

We track technology and show you what to build with it

We watch 24 tools across 4 beats. When one moves we explain it in plain text, write up what you can build with it, and what's worth a full project ends up on video.

  1. 01

    We watch

    Releases, changelogs and announcements from 24 sources, checked automatically every hour.

  2. 02

    We explain

    What actually changed and what breaks, in plain text, always linking the original announcement.

  3. 03

    We apply

    And above all: what you can build with it. Concrete projects, with the code in plain sight.

Latest on video
Agente que consulta inventario en Postgres

NovaTool use con la API de ClaudeIntermediate8:11

What we're watching right now

  • Google Research
  • Qiskit
  • Quanta Magazine
  • The Quantum Insider
  • Activepieces
  • n8n
  • n8n
  • Zapier
  • Claude Platform
  • Browser Use
  • Claude Code
  • CrewAI
  • Google DeepMind
  • Google ADK
  • LangGraph
  • MCP TypeScript SDK
  • OpenAI Agents SDK
  • OpenAI
  • SDK de OpenAI
  • Vercel AI SDK
  • Google
  • Hugging Face
  • MIT Technology Review
  • NVIDIA
4classes31min of class56chaptersnext: Supabase Edge Functions, 8 rendering

02HOW IT WORKS

From a changelog to something you can build

  1. 01WE WATCH

    Several beats, not one feed

    Every beat has its own sources and its own presenter: data, frontend, cloud, LLMs, languages, mobile, testing, automation, ML and product. The watcher polls them by itself, with nobody reading them by hand.

    24 active sources

  2. 02WE EXPLAIN

    What changed, without the changelog noise

    Each release turns into a short text saying what moved, who should care and what breaks on upgrade. Always linked to the original announcement: what was not there is not here.

    80 releases logged

  3. 03WE APPLY

    And what's worth building, gets built

    Articles with the practical cases for each technology, and a video when the topic is worth a full project: code on the page, timestamped chapters and notes in text. No slides.

    4 classes published

The beats we cover

See the full radar

03WHAT YOU CAN BUILD

Practical uses for what we track

One article per beat, written from the official docs. Each ends with three concrete projects you can finish in an afternoon.

See every article →
Tool use con la API de Claude8:11
Frame from Agente que consulta inventario en Postgres

No slides. A project.

Agente que consulta inventario en Postgres

NovaTool use con la API de ClaudeIntermediate8:11

Chapters

You leave with

  • Tool 'query_inventory' que ejecuta SQL parametrizado
  • Loop de tool_use hasta respuesta final del modelo
  • Manejo de errores de conexión y de datos vacíos
  • Endpoint HTTP /api/chat para consumir el agente
  • UI mínima en HTML para probar en el navegador

You needNode.js 18+ · PostgreSQL corriendo localmente (o Docker) · psql CLI instalado · Cuenta y API key de Anthropic

05WHAT YOU'LL BUILD

6 steps, one project that runs

Frame from Agente que consulta inventario en Postgres

8:11204 lines

Watch the class
  1. 01

    Crear la tabla y datos de prueba

    Tener una tabla real de productos con stock y precio para que el agente consulte datos verdaderos

    schema.sql

    schema.sql
    1CREATE TABLE IF NOT EXISTS products (
    2 id SERIAL PRIMARY KEY,
    3 name TEXT NOT NULL,
    4 category TEXT NOT NULL,
    5 stock INTEGER NOT NULL DEFAULT 0,
    6 price NUMERIC(10,2) NOT NULL
    7);
    8​
    9INSERT INTO products
    10 (name, category, stock, price)
    11VALUES
    12 ('Teclado mecanico', 'Perifericos',
    13 34, 89.90),
    14 ('Monitor 27 pulgadas 4K', 'Monitores',
    15 12, 349.00),
    16 ('Mouse inalambrico', 'Perifericos',
    17 58, 29.50),
    18 ('Silla ergonomica', 'Muebles',
    19 7, 219.00)
    20ON CONFLICT DO NOTHING;
    psql -U postgres -d inventory -f schema.sql

    psql -U postgres -d inventory -f schema.sql

    output

    CREATE TABLE

    INSERT 0 4

  2. 02

    Conectar Node a Postgres

    Crear un pool de conexiones reutilizable con manejo de errores de conexión

    src/db.ts

    src/db.ts
    1import { Pool } from 'pg';
    2import 'dotenv/config';
    3​
    4export const pool = new Pool({
    5 connectionString:
    6 process.env.DATABASE_URL,
    7});
    8​
    9pool.on('error', (err) => {
    10 console.error(
    11 'Error en el pool de PG:',
    12 err
    13 );
    14});
  3. 03

    Definir el tool y su ejecutor

    Declarar el schema del tool que Claude puede llamar y la función que corre el SQL real con try/catch

    src/tools.ts

    src/tools.ts
    1import { pool } from './db';
    2​
    3export const inventoryTool = {
    4 name: 'query_inventory',
    5 description:
    6 'Consulta el inventario. Recibe una ' +
    7 'categoria opcional y devuelve nombre, ' +
    8 'stock y precio de los productos.',
    9 input_schema: {
    10 type: 'object' as const,
    11 properties: {
    12 category: {
    13 type: 'string',
    14 description:
    15 'Categoria a filtrar',
    16 },
    17 },
    18 },
    19};
    20​
    21type Input = { category?: string };
    22​
    23export async function runInventoryQuery(
    24 input: Input
    25) {
    26 try {
    27 const { category } = input;
    28 const base =
    29 'SELECT name, stock, price ' +
    30 'FROM products';
    31 const sql = category
    32 ? `${base} WHERE category ILIKE $1`
    33 : base;
    34 const values = category
    35 ? [category]
    36 : [];
    37​
    38 const { rows } = await pool.query(
    39 sql,
    40 values
    41 );
    42​
    43 if (rows.length === 0) {
    44 return {
    45 ok: false,
    46 error:
    47 'No hay productos en esa ' +
    48 'categoria.',
    49 };
    50 }
    51 return { ok: true, data: rows };
    52 } catch (err) {
    53 console.error('Error en PG:', err);
    54 return {
    55 ok: false,
    56 error: 'La base de datos no respondio.',
    57 };
    58 }
    59}
  4. 04

    Armar el loop de tool use

    Entender cómo Claude pide ejecutar el tool, cómo se le devuelve el resultado y cómo se sigue el loop hasta la respuesta final

    src/agent.ts

    src/agent.ts
    1import Anthropic from '@anthropic-ai/sdk';
    2import {
    3 inventoryTool,
    4 runInventoryQuery,
    5} from './tools';
    6​
    7const anthropic = new Anthropic({
    8 apiKey: process.env.ANTHROPIC_API_KEY,
    9});
    10​
    11export async function askAgent(
    12 question: string
    13) {
    14 const messages: any[] = [
    15 { role: 'user', content: question },
    16 ];
    17​
    18 let response = await anthropic.messages.create({
    19 model: 'claude-sonnet-4-5',
    20 max_tokens: 1024,
    21 tools: [inventoryTool],
    22 messages,
    23 });
    24​
    25 while (response.stop_reason === 'tool_use') {
    26 const toolUse = response.content.find(
    27 (b: any) => b.type === 'tool_use'
    28 );
    29 if (!toolUse) break;
    30​
    31 const result = await runInventoryQuery(
    32 toolUse.input as { category?: string }
    33 );
    34​
    35 messages.push({
    36 role: 'assistant',
    37 content: response.content,
    38 });
    39 messages.push({
    40 role: 'user',
    41 content: [
    42 {
    43 type: 'tool_result',
    44 tool_use_id: toolUse.id,
    45 content: JSON.stringify(result),
    46 },
    47 ],
    48 });
    49​
    50 response = await anthropic.messages.create({
    51 model: 'claude-sonnet-4-5',
    52 max_tokens: 1024,
    53 tools: [inventoryTool],
    54 messages,
    55 });
    56 }
    57​
    58 const finalText = response.content.find(
    59 (b: any) => b.type === 'text'
    60 );
    61 return finalText ? finalText.text : '';
    62}
  5. 05

    Exponer el agente por HTTP

    Crear un endpoint Express que recibe la pregunta, llama al agente y devuelve un error controlado si algo falla

    src/server.ts

    src/server.ts
    1import express from 'express';
    2import 'dotenv/config';
    3import { askAgent } from './agent';
    4​
    5const app = express();
    6app.use(express.json());
    7app.use(express.static('public'));
    8​
    9app.post('/api/chat', async (req, res) => {
    10 const { question } = req.body;
    11 if (!question) {
    12 return res.status(400).json({
    13 error: 'Falta la pregunta',
    14 });
    15 }
    16 try {
    17 const answer = await askAgent(question);
    18 res.json({ answer });
    19 } catch (err) {
    20 console.error('Error del agente:', err);
    21 res.status(500).json({
    22 error: 'El agente no pudo responder.',
    23 });
    24 }
    25});
    26​
    27const PORT = process.env.PORT || 3000;
    28app.listen(PORT, () => {
    29 console.log(`Server en puerto ${PORT}`);
    30});
    npx ts-node src/server.ts

    npx ts-node src/server.ts

    output

    Server en puerto 3000

  6. 06

    Probar el agente en el navegador

    Ver el agente respondiendo con datos reales y comprobar que un caso sin resultados o con error de conexión se explica en lenguaje natural en vez de romper la app

    public/index.html

    public/index.html
    1<!DOCTYPE html>
    2<html lang="es">
    3<head>
    4 <meta charset="UTF-8" />
    5 <title>Agente de Inventario</title>
    6</head>
    7<body>
    8 <h1>Agente de Inventario</h1>
    9 <input
    10 id="q"
    11 placeholder="Pregunta por el stock..."
    12 />
    13 <button id="send">Enviar</button>
    14 <p id="answer"></p>
    15​
    16 <script>
    17 const send =
    18 document.getElementById('send');
    19 send.onclick = async () => {
    20 const q =
    21 document.getElementById('q').value;
    22 const res = await fetch('/api/chat', {
    23 method: 'POST',
    24 headers: {
    25 'Content-Type':
    26 'application/json',
    27 },
    28 body: JSON.stringify({
    29 question: q,
    30 }),
    31 });
    32 const data = await res.json();
    33 document.getElementById(
    34 'answer'
    35 ).innerText = data.answer || data.error;
    36 };
    37 </script>
    38</body>
    39</html>
    npx ts-node src/server.ts

    npx ts-node src/server.ts

    output

    Server en puerto 3000

    Agente de Inventario

    Pregunta por el stock...

    Enviar

    Monitor 27 pulgadas 4K: 12 unidades a $349.00

    No hay productos en esa categoria.

06THE BENCH

Already on video

Frame from Registro con validación en vivo

Registro con validación en vivo

14 chapters375 lines

Intermediate
Next.js 15

07MOMENTS

Jump in at the minute you need

08WHERE TO START

Three ways in

09WHO TEACHES

4 presenters, 4 specialties

Agentes de IA: MCP, computer use y sistemas multi-agente

Nova

Del prompt suelto al agente que hace el trabajo

1 class

Watch their latest class
Frame from Agente que consulta inventario en Postgres

Agente que consulta inventario en Postgres

AI Talks generated presenter

10CLASS NOTES

Class notes

In 4 lines

  • El tool_use no es magia: es un loop explícito donde tú ejecutas la función y devuelves el resultado como 'tool_result'
  • El error de la base de datos hay que atraparlo en el ejecutor del tool, no dejar que reviente el server
  • El input_schema del tool es lo único que Claude 've' de tu base: si está mal descrito, va a pedir parámetros que no existen
  • Separar db.ts, tools.ts y agent.ts hace que el mismo tool se pueda testear sin llamar a la API de Claude

What breaks

¿Qué problema resuelve Agente que consulta inventario en Postgres?
Los chatbots que solo 'alucinan' respuestas no sirven para soporte real: hace falta que el modelo consulte datos verdaderos y sepa explicar cuando algo no existe o la base falla. Un agente mínimo en Node.js que usa tool use de Claude para consultar una tabla real de productos en Postgres y responder en lenguaje natural, incluso cuando la consulta falla.
¿Qué necesito saber antes de seguir esta clase?
Necesitas Node.js 18+, PostgreSQL corriendo localmente (o Docker), psql CLI instalado, Cuenta y API key de Anthropic, Conocimientos básicos de SQL y Express. La clase es de nivel intermedio y dura 8 minutos.
¿Qué stack se usa para Tool use con la API de Claude?
El proyecto usa Node.js, TypeScript, Express, PostgreSQL, @anthropic-ai/sdk, pg. Todo el código se escribe en pantalla durante la clase.
¿Por qué falla al olvidar el while(stop_reason === 'tool_use') y devolver solo la primera respuesta, que suele venir vacía o…?
Olvidar el while(stop_reason === 'tool_use') y devolver solo la primera respuesta, que suele venir vacía o incompleta
¿Por qué falla al dejar que una excepción de pg tumbe el proceso en vez de capturarla y devolver un objeto { ok: false, error }?
Dejar que una excepción de pg tumbe el proceso en vez de capturarla y devolver un objeto { ok: false, error }
¿Por qué falla al usar SELECT * en el tool, exponiendo columnas sensibles que no querías que el modelo viera ni repitiera?
Usar SELECT * en el tool, exponiendo columnas sensibles que no querías que el modelo viera ni repitiera

The trick

Serializa SIEMPRE el resultado del tool con JSON.stringify, incluso cuando es un error ({ ok: false, error: '...' }). Claude interpreta mejor un string estructurado y consistente que un objeto crudo o un mensaje de error suelto, y eso reduce muchísimo los casos donde el modelo se queda repitiendo la misma pregunta o inventa una respuesta genérica en vez de explicar la falla real.

Transcript

12NEXT CLASS

What should we cover next?

  • Supabase Edge Functions1 votes
  • Búsqueda semántica con pgvector1 votes
  • AWS Lambda con CDK en TypeScript0 votes
  • n8n0 votes
  • React Server Components en Next.js 150 votes
  • Prompt caching en la API de Claude1 votes

Vote or propose