惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Vercel News
Vercel News
博客园 - 司徒正美
大猫的无限游戏
大猫的无限游戏
Last Week in AI
Last Week in AI
V
Visual Studio Blog
阮一峰的网络日志
阮一峰的网络日志
小众软件
小众软件
宝玉的分享
宝玉的分享
Apple Machine Learning Research
Apple Machine Learning Research
美团技术团队
WordPress大学
WordPress大学
博客园 - 聂微东
人人都是产品经理
人人都是产品经理
罗磊的独立博客
The Cloudflare Blog
V
V2EX
月光博客
月光博客
有赞技术团队
有赞技术团队
Y
Y Combinator Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
GbyAI
GbyAI
博客园 - 【当耐特】
T
Tailwind CSS Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
DeepSeek's Response API Isn't OpenAI Responses. That One ...
tokenmixai · 2026-06-27 · via DEV Community

I keep seeing developers use "DeepSeek response API" and "OpenAI Responses API" as if they mean the same thing.

They do not.

That small naming mistake can make your integration look like it works while quietly dropping the most important field in the response: reasoning_content.

I spent time checking the DeepSeek V4 docs and the live TokenMix model catalog. The practical answer is simple:

DeepSeek is OpenAI-compatible at the Chat Completions layer. It is not documented as OpenAI /responses compatible.

TL;DR

  • No, DeepSeek's response protocol is not the OpenAI /responses API. It is /chat/completions.
  • The important extra field is choices[0].message.reasoning_content.
  • If your wrapper only parses message.content, you may lose DeepSeek's thinking output.
  • DeepSeek V4 now uses deepseek-v4-flash and deepseek-v4-pro; old deepseek-chat and deepseek-reasoner names are scheduled for deprecation.
  • TokenMix supports DeepSeek V4 Flash and Pro through one OpenAI-compatible base URL, with reasoning, streaming, JSON, tools, structured output, and prompt caching marked in its live catalog.

What actually changed

DeepSeek V4 moved the model naming story forward.

The old mental model was:

Old model name What people assumed
deepseek-chat normal chat
deepseek-reasoner reasoning model

The newer V4 model IDs are:

New model Best read
deepseek-v4-flash cheaper/high-throughput V4
deepseek-v4-pro stronger reasoning/coding V4

DeepSeek's docs say the older deepseek-chat and deepseek-reasoner names are compatibility aliases heading toward deprecation on 2026-07-24 15:59 UTC.

That means I would not build new production code around the old names.

The response object that matters

If you are used to OpenAI Chat Completions, this will look familiar:

{
  "choices": [
    {
      "message": {
        "content": "final answer",
        "reasoning_content": "thinking output",
        "tool_calls": []
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 123,
    "completion_tokens": 456,
    "completion_tokens_details": {
      "reasoning_tokens": 300
    }
  }
}

The trap is that most basic wrappers only do this:

answer = response.choices[0].message.content

That gets the final answer.

It does not get the thinking output.

For some products, that is fine. For debugging, evals, agent traces, and tool workflows, it is not fine.

The parser I would use

I would parse DeepSeek responses explicitly:

def parse_deepseek_response(response):
    choice = response.choices[0]
    message = choice.message

    return {
        "answer": getattr(message, "content", None),
        "reasoning": getattr(message, "reasoning_content", None),
        "tool_calls": getattr(message, "tool_calls", None),
        "finish_reason": choice.finish_reason,
        "usage": getattr(response, "usage", None),
    }

That is not fancy. It is the minimum safe parser.

The point is not to show chain of thought to users. The point is to avoid silently losing fields that affect debugging, evals, and tool-call continuation.

The tool-call caveat

This is the part I would not ignore.

DeepSeek's thinking-mode docs distinguish normal multi-turn chat from tool-call workflows.

For ordinary multi-turn conversations, you do not need to pass prior chain-of-thought content back.

But when tool calls are involved, DeepSeek says the intermediate reasoning_content after a tool call must be passed back in the following request.

That means a generic OpenAI wrapper can fail in a very boring way:

  1. It receives reasoning_content.
  2. It stores only role and content.
  3. It calls your tool.
  4. It sends the next request without the reasoning field.
  5. The model's tool workflow loses context.

That is the kind of bug that does not always crash. It just makes the agent worse.

The decision tree

Here is how I would decide what to implement:

def deepseek_integration_plan(app):
    if app["uses_old_model_names"]:
        return "Migrate from deepseek-chat/deepseek-reasoner to deepseek-v4-flash or deepseek-v4-pro."

    if app["uses_tools"] and app["thinking_enabled"]:
        return "Preserve reasoning_content across tool-call turns. Do not use a content-only wrapper."

    if app["needs_json"]:
        return "Use response_format={\"type\":\"json_object\"} and still validate the result."

    if app["high_volume"]:
        return "Start with deepseek-v4-flash and track cache hit/miss tokens."

    if app["hard_reasoning"]:
        return "Benchmark deepseek-v4-pro with reasoning enabled."

    return "Use Chat Completions compatibility, but parse DeepSeek-specific fields explicitly."

I like this tree because it avoids the biggest false choice.

The question is not "Is DeepSeek OpenAI-compatible?"

The question is "Which compatibility layer are you depending on?"

TokenMix angle: one endpoint, but still parse the fields

TokenMix exposes DeepSeek through an OpenAI-compatible base URL:

https://api.tokenmix.ai/v1

The live catalog currently lists:

Model Reasoning JSON Tools Streaming Prompt cache
deepseek/deepseek-v4-flash yes yes yes yes yes
deepseek/deepseek-v4-pro yes yes yes yes yes

That is useful because you can route DeepSeek alongside OpenAI, Claude, Gemini, Qwen, GLM, and other models through one endpoint.

But the same caveat remains:

OpenAI-compatible routing gets the request through.

Correct parsing still belongs to you.

Cost math in one minute

The cost story is also easy to misunderstand.

DeepSeek direct pricing separates cache-hit input, cache-miss input, and output tokens.

TokenMix publishes catalog rates for routing through its endpoint.

For example, using the live TokenMix catalog rates I checked:

Model Input / 1M Output / 1M
DeepSeek V4 Flash $0.132353 $0.264706
DeepSeek V4 Pro $0.419118 $0.838235

So a 10M input / 2M output workload is roughly:

Flash = 10 * 0.132353 + 2 * 0.264706 = $1.85
Pro   = 10 * 0.419118 + 2 * 0.838235 = $5.87

That makes Flash the obvious first route for high-volume tasks.

I would only pay for Pro where Flash fails on your actual evals.

What I'd do in production

If I were shipping DeepSeek V4 this week, I would:

  • Stop using old model names in new code.
  • Parse content, reasoning_content, tool_calls, finish_reason, and usage.
  • Preserve reasoning_content in thinking-mode tool workflows.
  • Use JSON mode only with explicit prompt instructions and validation.
  • Track cache hit/miss tokens separately.
  • Start with Flash, then escalate to Pro only on failing tasks.
  • Put DeepSeek behind a router instead of making it the only backend.

That last point matters.

One endpoint does not remove the need for fallback.

It just makes fallback less painful.

Disclosure

If you want DeepSeek, OpenAI, Claude, Gemini, Qwen, GLM and other models behind one OpenAI-compatible endpoint, that is roughly what TokenMix does. Disclosure: I work on the research side. Full cited breakdown is on the original article.

Bottom line

DeepSeek response compatibility is real, but it is not the OpenAI Responses API.

Treat it as Chat Completions compatibility plus DeepSeek-specific fields. Parse reasoning_content intentionally, migrate to V4 model IDs, and do not let a generic wrapper quietly erase the data you need for reasoning, tools, and evals.

Have you seen OpenAI-compatible wrappers drop provider-specific fields like reasoning_content or cache usage? How did you handle it?