2026-04-15

Cómo usar DeepSeek V4 en Node.js: TypeScript, streaming, tool use

DeepSeek V4 es compatible con OpenAI, así que en Node.js basta con el paquete openai de npm. Esta guía cubre en TypeScript: instalación, primera llamada, streaming desde un route handler de Next.js, tool use validado con Zod y consejos para mantener a raya el coste de tokens.

1. Instalación y configuración

El paquete oficial openai soporta baseURL para apuntar a DeepSeek. Guarda la clave en .env; nunca la subas a Git ni la expongas en el navegador.

npm install openai zod
echo "DEEPSEEK_API_KEY=sk-..." >> .env.local

2. Primera llamada en TypeScript

Instancia el cliente una sola vez. baseURL al endpoint de DeepSeek y model deepseek-chat para uso general.

import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.DEEPSEEK_API_KEY,
  baseURL: "https://api.deepseek.com/v1",
});

export async function ask(question: string): Promise<string> {
  const res = await client.chat.completions.create({
    model: "deepseek-chat",
    messages: [
      { role: "system", content: "You are a concise technical assistant." },
      { role: "user", content: question },
    ],
    temperature: 0.2,
  });
  return res.choices[0].message.content ?? "";
}

3. Streaming desde un route handler de Next.js

Para UI de chat quieres tokens en tiempo real. Lo más sencillo es transformar el iterable async del SDK en un ReadableStream y devolverlo directo como Response.

// app/api/chat/route.ts
import OpenAI from "openai";

export const runtime = "nodejs";

const client = new OpenAI({
  apiKey: process.env.DEEPSEEK_API_KEY,
  baseURL: "https://api.deepseek.com/v1",
});

export async function POST(req: Request) {
  const { messages } = await req.json();

  const stream = await client.chat.completions.create({
    model: "deepseek-chat",
    messages,
    stream: true,
  });

  const encoder = new TextEncoder();
  const body = new ReadableStream({
    async start(controller) {
      for await (const chunk of stream) {
        const delta = chunk.choices[0]?.delta?.content ?? "";
        if (delta) controller.enqueue(encoder.encode(delta));
      }
      controller.close();
    },
  });

  return new Response(body, {
    headers: { "Content-Type": "text/plain; charset=utf-8" },
  });
}

4. Validar argumentos de tool use con Zod

V4 maneja tool use lo bastante bien para agentes reales, pero el modelo puede alucinar argumentos. Parsea siempre con un esquema Zod antes de ejecutar.

import { z } from "zod";

const GetWeatherArgs = z.object({ city: z.string().min(1) });

const tools = [{
  type: "function" as const,
  function: {
    name: "get_weather",
    description: "Get the current weather for a city",
    parameters: {
      type: "object",
      properties: { city: { type: "string" } },
      required: ["city"],
    },
  },
}];

const res = await client.chat.completions.create({
  model: "deepseek-chat",
  messages: [{ role: "user", content: "Weather in Tokyo?" }],
  tools,
});

const call = res.choices[0].message.tool_calls?.[0];
if (call?.function.name === "get_weather") {
  const args = GetWeatherArgs.parse(JSON.parse(call.function.arguments));
  // … execute tool and feed result back as a { role: "tool" } message …
}

5. Control de coste en Node.js

Entrada y salida se facturan por separado, con la salida a ~2×. El system prompt y el historial se suman a la entrada, así que una conversación sin recortes escala la factura rápido.

Usa maxTokens, resume turnos antiguos y cachea chunks de RAG. Si tu volumen es alto, /pricing tiene claves oficiales con descuento.

FAQ

¿Puedo llamar a DeepSeek desde el navegador?

No. Expondrías la clave. Siempre a través de un server Node.js, serverless o un route handler de Next.js.

¿Funciona en Bun, Deno o Cloudflare Workers?

Sí. El SDK openai trae build ESM y basta con que haya fetch. Para streaming de larga duración, preferible Node.js.

¿Compatible con LangChain o Vercel AI SDK?

Sí, cualquier librería que acepte baseURL compatible con OpenAI sirve.

¿Y la API Key barata?

/pricing lista claves oficiales con descuento.

Si ya tienes Node.js o Next.js, migrar a DeepSeek V4 son dos líneas: baseURL y model. Conservas prompts, herramientas y retries, y recortas el coste por tokens en un orden de magnitud.