Files
metona-ai-desktop/apis/deepseek-api-docs-20260518.html
thzxx 1d185db6b3 feat: MetonaAI Desktop 初始项目
- Electron + React + TypeScript 架构
- 三栏布局: Sidebar | ChatPanel | DetailPanel
- 9 个内置工具 (文件系统/网络/记忆/命令)
- SQLite 持久化 (better-sqlite3)
- MUI 暗色/亮色主题系统
- Agent Loop ReAct 状态机引擎
- DeepSeek / Agnes AI / Ollama Provider 适配器
- MCP 协议集成
- 系统托盘 + 全局快捷键
- Tailwind CSS v4 + Tailwind Merge
- 修复: Sidebar 缺失 TextField 导入导致黑屏
2026-06-27 21:33:27 +08:00

1053 lines
54 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DeepSeek API 完整接口文档 | 20260518</title>
<style>
:root {
--bg: #0f1117;
--bg-card: #1a1d27;
--bg-code: #12141c;
--bg-nav: #141620;
--text: #e1e4ed;
--text-dim: #8b8fa7;
--accent: #4f6ef7;
--accent2: #7c3aed;
--green: #34d399;
--orange: #fb923c;
--red: #f87171;
--cyan: #22d3ee;
--border: #2a2d3a;
--get: #34d399;
--post: #4f6ef7;
--delete: #f87171;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
background: var(--bg);
color: var(--text);
line-height: 1.7;
display: flex;
}
/* === SIDEBAR === */
.sidebar {
position: fixed;
top: 0; left: 0;
width: 280px;
height: 100vh;
background: var(--bg-nav);
border-right: 1px solid var(--border);
overflow-y: auto;
z-index: 100;
padding: 24px 0;
}
.sidebar-logo {
padding: 0 20px 20px;
border-bottom: 1px solid var(--border);
margin-bottom: 16px;
}
.sidebar-logo h2 {
font-size: 20px;
background: linear-gradient(135deg, var(--accent), var(--accent2));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
display: flex;
align-items: center;
gap: 8px;
}
.sidebar-logo .badge {
font-size: 11px;
background: var(--accent);
color: #fff;
padding: 2px 8px;
border-radius: 10px;
-webkit-text-fill-color: #fff;
}
.sidebar-section {
padding: 8px 20px;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 1.2px;
color: var(--text-dim);
font-weight: 600;
}
.sidebar a {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 20px;
color: var(--text-dim);
text-decoration: none;
font-size: 13.5px;
transition: all 0.15s;
}
.sidebar a:hover, .sidebar a.active {
color: var(--text);
background: rgba(79, 110, 247, 0.06);
}
.sidebar a .method {
font-size: 10px;
font-weight: 700;
padding: 1px 6px;
border-radius: 3px;
min-width: 42px;
text-align: center;
font-family: 'SF Mono', 'Fira Code', monospace;
}
.method-get { background: rgba(52,211,153,0.15); color: var(--get); }
.method-post { background: rgba(79,110,247,0.15); color: var(--post); }
.method-delete { background: rgba(248,113,113,0.15); color: var(--delete); }
/* === MAIN === */
.main {
margin-left: 280px;
flex: 1;
min-height: 100vh;
}
.hero {
background: linear-gradient(135deg, rgba(79,110,247,0.08), rgba(124,58,237,0.08));
border-bottom: 1px solid var(--border);
padding: 60px 60px 50px;
}
.hero h1 {
font-size: 36px;
font-weight: 800;
background: linear-gradient(135deg, var(--accent), var(--accent2));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
margin-bottom: 12px;
}
.hero p {
color: var(--text-dim);
font-size: 16px;
max-width: 680px;
}
.hero-meta {
display: flex;
gap: 24px;
margin-top: 20px;
flex-wrap: wrap;
}
.hero-meta span {
font-size: 13px;
color: var(--text-dim);
display: flex;
align-items: center;
gap: 6px;
}
.hero-meta .dot {
width: 6px; height: 6px;
border-radius: 50%;
display: inline-block;
}
.dot-green { background: var(--green); }
.dot-blue { background: var(--accent); }
.dot-orange { background: var(--orange); }
.content {
padding: 40px 60px 100px;
max-width: 1000px;
}
/* === SECTION === */
.api-section {
margin-bottom: 60px;
scroll-margin-top: 20px;
}
.api-section h2 {
font-size: 24px;
font-weight: 700;
margin-bottom: 8px;
display: flex;
align-items: center;
gap: 12px;
}
.api-section .desc {
color: var(--text-dim);
font-size: 15px;
margin-bottom: 24px;
}
/* === ENDPOINT BAR === */
.endpoint-bar {
display: flex;
align-items: center;
gap: 12px;
background: var(--bg-code);
border: 1px solid var(--border);
border-radius: 10px;
padding: 12px 18px;
margin-bottom: 24px;
font-family: 'SF Mono', 'Fira Code', monospace;
font-size: 14px;
}
.endpoint-bar .http-method {
font-weight: 700;
padding: 4px 10px;
border-radius: 5px;
font-size: 12px;
}
.endpoint-bar .url {
color: var(--text);
}
/* === PARAMS TABLE === */
.params-title {
font-size: 14px;
font-weight: 600;
color: var(--accent);
margin-bottom: 10px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
table.params {
width: 100%;
border-collapse: collapse;
margin-bottom: 28px;
font-size: 13.5px;
}
table.params th {
text-align: left;
padding: 10px 14px;
background: var(--bg-card);
border-bottom: 1px solid var(--border);
color: var(--text-dim);
font-weight: 600;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.8px;
}
table.params td {
padding: 10px 14px;
border-bottom: 1px solid rgba(42,45,58,0.5);
vertical-align: top;
}
table.params tr:last-child td { border-bottom: none; }
.param-name {
font-family: 'SF Mono', 'Fira Code', monospace;
color: var(--cyan);
font-weight: 600;
font-size: 13px;
}
.param-type {
font-family: 'SF Mono', 'Fira Code', monospace;
color: var(--accent2);
font-size: 12px;
}
.param-required {
color: var(--red);
font-size: 11px;
font-weight: 600;
}
.param-optional {
color: var(--text-dim);
font-size: 11px;
}
.param-default {
color: var(--text-dim);
font-size: 12px;
}
/* === CODE BLOCK === */
.code-tabs {
display: flex;
gap: 0;
border-bottom: 1px solid var(--border);
margin-bottom: 0;
flex-wrap: wrap;
}
.code-tab {
padding: 10px 20px;
font-size: 13px;
font-weight: 600;
color: var(--text-dim);
cursor: pointer;
border-bottom: 2px solid transparent;
transition: all 0.15s;
background: transparent;
border-top: none;
border-left: none;
border-right: none;
}
.code-tab:hover { color: var(--text); }
.code-tab.active {
color: var(--accent);
border-bottom-color: var(--accent);
}
.code-block {
background: var(--bg-code);
border: 1px solid var(--border);
border-top: none;
border-radius: 0 0 10px 10px;
padding: 20px;
overflow-x: auto;
margin-bottom: 24px;
}
.code-block pre {
margin: 0;
font-family: 'SF Mono', 'Fira Code', 'Cascadia Code', monospace;
font-size: 13px;
line-height: 1.65;
color: var(--text);
}
.code-panel { display: none; }
.code-panel.active { display: block; }
/* Syntax colors */
.hl-kw { color: var(--accent2); }
.hl-str { color: var(--green); }
.hl-num { color: var(--orange); }
.hl-cm { color: var(--text-dim); font-style: italic; }
.hl-fn { color: var(--accent); }
.hl-prop { color: var(--cyan); }
/* === RESPONSE === */
.response-title {
font-size: 14px;
font-weight: 600;
color: var(--green);
margin-bottom: 10px;
}
.response-block {
background: var(--bg-code);
border: 1px solid var(--border);
border-radius: 10px;
padding: 20px;
overflow-x: auto;
margin-bottom: 28px;
}
.response-block pre {
margin: 0;
font-family: 'SF Mono', 'Fira Code', monospace;
font-size: 13px;
line-height: 1.65;
color: var(--text);
}
/* === DIVIDER === */
.section-divider {
border: none;
height: 1px;
background: var(--border);
margin: 60px 0;
}
/* === OVERVIEW TABLE === */
.overview-table {
width: 100%;
border-collapse: collapse;
margin: 24px 0 40px;
font-size: 13.5px;
}
.overview-table th {
text-align: left;
padding: 12px 16px;
background: var(--bg-card);
border-bottom: 2px solid var(--border);
color: var(--text-dim);
font-weight: 600;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.8px;
}
.overview-table td {
padding: 10px 16px;
border-bottom: 1px solid rgba(42,45,58,0.5);
}
.overview-table a {
color: var(--accent);
text-decoration: none;
}
.overview-table a:hover { text-decoration: underline; }
/* === PRICING TABLE === */
.pricing-table {
width: 100%;
border-collapse: collapse;
margin: 24px 0;
font-size: 13.5px;
}
.pricing-table th {
text-align: left;
padding: 12px 16px;
background: var(--bg-card);
border-bottom: 2px solid var(--border);
color: var(--text-dim);
font-weight: 600;
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.8px;
}
.pricing-table td {
padding: 10px 16px;
border-bottom: 1px solid rgba(42,45,58,0.5);
}
.pricing-table tr:last-child td { border-bottom: none; }
/* === SCROLLBAR === */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--text-dim); }
/* === NOTE BOX === */
.note-box {
background: rgba(79,110,247,0.06);
border-left: 3px solid var(--accent);
border-radius: 0 8px 8px 0;
padding: 14px 18px;
margin-bottom: 24px;
font-size: 13.5px;
color: var(--text-dim);
}
.note-box strong { color: var(--accent); }
@media (max-width: 900px) {
.sidebar { display: none; }
.main { margin-left: 0; }
.hero { padding: 30px 24px; }
.content { padding: 24px; }
}
</style>
</head>
<body>
<!-- ========== SIDEBAR ========== -->
<nav class="sidebar">
<div class="sidebar-logo">
<h2>🔮 DeepSeek API <span class="badge">最新</span></h2>
</div>
<div class="sidebar-section">概述</div>
<a href="#overview">📋 接口总览</a>
<a href="#quickstart">⚡ 快速开始</a>
<a href="#pricing">💰 模型 & 价格</a>
<div class="sidebar-section">对话接口</div>
<a href="#chat-completions"><span class="method method-post">POST</span> /chat/completions</a>
<a href="#completions-fim"><span class="method method-post">POST</span> /completions (FIM)</a>
<div class="sidebar-section">模型管理</div>
<a href="#models"><span class="method method-get">GET</span> /models</a>
<div class="sidebar-section">账户</div>
<a href="#balance"><span class="method method-get">GET</span> /user/balance</a>
<div class="sidebar-section">指南</div>
<a href="#thinking-mode">🧠 思考模式</a>
<a href="#tool-calling">🔧 工具调用</a>
<a href="#json-output">📄 JSON 输出</a>
<a href="#anthropic-compat">🔗 Anthropic 兼容</a>
</nav>
<!-- ========== MAIN CONTENT ========== -->
<div class="main">
<!-- HERO -->
<div class="hero">
<h1>DeepSeek API 完整接口文档</h1>
<p>基于官方文档 <a href="https://api-docs.deepseek.com" style="color:var(--accent)">api-docs.deepseek.com</a> 全面解析。兼容 OpenAI / Anthropic SDK 格式,支持 deepseek-v4-flash 和 deepseek-v4-pro 模型。</p>
<div class="hero-meta">
<span><span class="dot dot-green"></span> 支持模型: <strong>deepseek-v4-flash · deepseek-v4-pro</strong></span>
<span><span class="dot dot-blue"></span> 文档日期: <strong>2026-05-18</strong></span>
<span><span class="dot dot-orange"></span> Base URL: <strong>https://api.deepseek.com</strong></span>
</div>
</div>
<div class="content">
<!-- ========== 接口总览 ========== -->
<section class="api-section" id="overview">
<h2>📋 接口总览</h2>
<p class="desc">DeepSeek API 提供 RESTful HTTP 接口,兼容 OpenAI 和 Anthropic SDK 格式。所有请求与响应均使用 JSON 格式。流式响应使用 SSEServer-Sent Events)。</p>
<table class="overview-table">
<thead>
<tr><th>方法</th><th>接口路径</th><th>描述</th></tr>
</thead>
<tbody>
<tr><td><span class="method method-post">POST</span></td><td><a href="#chat-completions">/chat/completions</a></td><td>对话补全(主接口)</td></tr>
<tr><td><span class="method method-post">POST</span></td><td><a href="#completions-fim">/completions</a></td><td>FIM 补全(Beta</td></tr>
<tr><td><span class="method method-get">GET</span></td><td><a href="#models">/models</a></td><td>列出可用模型</td></tr>
<tr><td><span class="method method-get">GET</span></td><td><a href="#balance">/user/balance</a></td><td>查询账户余额</td></tr>
</tbody>
</table>
</section>
<!-- ========== 快速开始 ========== -->
<section class="api-section" id="quickstart">
<h2>⚡ 快速开始</h2>
<p class="desc">获取 API Key 后即可开始调用。支持 OpenAI SDK 兼容格式,也可直接使用 HTTP 请求。</p>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'qs-curl')">curl</button>
<button class="code-tab" onclick="switchTab(this, 'qs-python')">Python (OpenAI SDK)</button>
</div>
<div class="code-block">
<div class="code-panel active" id="qs-curl">
<pre><span class="hl-fn">curl</span> <span class="hl-str">https://api.deepseek.com/chat/completions</span> \
-H <span class="hl-str">"Content-Type: application/json"</span> \
-H <span class="hl-str">"Authorization: Bearer ${DEEPSEEK_API_KEY}"</span> \
-d <span class="hl-str">'{
"model": "deepseek-v4-pro",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hello!"}
],
"thinking": {"type": "enabled"},
"reasoning_effort": "high",
"stream": false
}'</span></pre>
</div>
<div class="code-panel" id="qs-python">
<pre><span class="hl-kw">from</span> openai <span class="hl-kw">import</span> OpenAI
client = <span class="hl-fn">OpenAI</span>(
<span class="hl-prop">api_key</span>=<span class="hl-str">"&lt;your api key&gt;"</span>,
<span class="hl-prop">base_url</span>=<span class="hl-str">"https://api.deepseek.com"</span>
)
response = client.chat.completions.<span class="hl-fn">create</span>(
<span class="hl-prop">model</span>=<span class="hl-str">"deepseek-v4-pro"</span>,
<span class="hl-prop">messages</span>=[
{<span class="hl-str">"role"</span>: <span class="hl-str">"system"</span>, <span class="hl-str">"content"</span>: <span class="hl-str">"You are a helpful assistant."</span>},
{<span class="hl-str">"role"</span>: <span class="hl-str">"user"</span>, <span class="hl-str">"content"</span>: <span class="hl-str">"Hello!"</span>}
],
<span class="hl-prop">extra_body</span>={<span class="hl-str">"thinking"</span>: {<span class="hl-str">"type"</span>: <span class="hl-str">"enabled"</span>}},
<span class="hl-prop">reasoning_effort</span>=<span class="hl-str">"high"</span>
)
<span class="hl-fn">print</span>(response.choices[<span class="hl-num">0</span>].message.content)</pre>
</div>
</div>
</section>
<!-- ========== 模型 & 价格 ========== -->
<section class="api-section" id="pricing">
<h2>💰 模型 & 价格</h2>
<p class="desc">DeepSeek 提供两个模型版本,均支持 1M 上下文长度和最大 384K 输出长度。</p>
<table class="pricing-table">
<thead>
<tr><th>项目</th><th>deepseek-v4-flash</th><th>deepseek-v4-pro</th></tr>
</thead>
<tbody>
<tr><td>模型版本</td><td>DeepSeek-V4-Flash</td><td>DeepSeek-V4-Pro</td></tr>
<tr><td>上下文长度</td><td>1M</td><td>1M</td></tr>
<tr><td>输出长度</td><td>最大 384K</td><td>最大 384K</td></tr>
<tr><td>思考模式</td><td>支持非思考与思考模式(默认)</td><td>支持</td></tr>
<tr><td>JSON Output</td><td>支持</td><td>支持</td></tr>
<tr><td>Tool Calls</td><td>支持</td><td>支持</td></tr>
<tr><td>FIM 补全(Beta</td><td>仅非思考模式</td><td>仅非思考模式</td></tr>
<tr><td>输入(缓存命中)</td><td>0.02 元/百万tokens</td><td>0.1 元/百万tokens</td></tr>
<tr><td>输入(缓存未命中)</td><td>1 元/百万tokens</td><td>3 元/百万tokens2.5折)</td></tr>
<tr><td>输出</td><td>2 元/百万tokens</td><td>6 元/百万tokens2.5折)</td></tr>
</tbody>
</table>
<div class="note-box"><strong>⚠️ 注意:</strong><code>deepseek-chat</code><code>deepseek-reasoner</code> 将于 2026/07/24 下线,分别映射到 deepseek-v4-flash 的非思考模式和思考模式。</div>
</section>
<hr class="section-divider">
<!-- ==================== POST /chat/completions ==================== -->
<section class="api-section" id="chat-completions">
<h2><span class="method method-post">POST</span> /chat/completions</h2>
<p class="desc">DeepSeek 核心对话接口。支持多轮对话、思考模式、工具调用、JSON 结构化输出、流式响应等全部功能。</p>
<div class="endpoint-bar">
<span class="http-method method-post">POST</span>
<span class="url">https://api.deepseek.com/chat/completions</span>
</div>
<div class="params-title">📥 请求参数</div>
<table class="params">
<thead><tr><th>参数名</th><th>类型</th><th>必填</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">model</td><td class="param-type">string</td><td class="param-required">必填</td><td>模型 ID: "deepseek-v4-flash" 或 "deepseek-v4-pro"</td></tr>
<tr><td class="param-name">messages</td><td class="param-type">array</td><td class="param-required">必填</td><td>对话消息列表</td></tr>
<tr><td class="param-name">messages[].role</td><td class="param-type">string</td><td class="param-required">必填</td><td>角色: "system" / "user" / "assistant" / "tool"</td></tr>
<tr><td class="param-name">messages[].content</td><td class="param-type">string</td><td class="param-required">必填</td><td>消息内容</td></tr>
<tr><td class="param-name">thinking</td><td class="param-type">object</td><td class="param-optional">可选</td><td>思考模式控制</td></tr>
<tr><td class="param-name">thinking.type</td><td class="param-type">string</td><td class="param-optional">可选</td><td>"enabled" 或 "disabled"(默认 enabled</td></tr>
<tr><td class="param-name">reasoning_effort</td><td class="param-type">string</td><td class="param-optional">可选</td><td>推理强度: "high"(默认)或 "max"</td></tr>
<tr><td class="param-name">max_tokens</td><td class="param-type">integer</td><td class="param-optional">可选</td><td>最大生成 token 数</td></tr>
<tr><td class="param-name">response_format</td><td class="param-type">object</td><td class="param-optional">可选</td><td>响应格式,支持 {"type": "json_object"}</td></tr>
<tr><td class="param-name">stop</td><td class="param-type">string / string[]</td><td class="param-optional">可选</td><td>停止序列(最多16个)</td></tr>
<tr><td class="param-name">stream</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>是否 SSE 流式输出</td></tr>
<tr><td class="param-name">stream_options</td><td class="param-type">object</td><td class="param-optional">可选</td><td>流式选项</td></tr>
<tr><td class="param-name">temperature</td><td class="param-type">number</td><td class="param-optional">可选</td><td>采样温度 0-2(默认 1</td></tr>
<tr><td class="param-name">top_p</td><td class="param-type">number</td><td class="param-optional">可选</td><td>核采样概率(默认 1</td></tr>
<tr><td class="param-name">tools</td><td class="param-type">array</td><td class="param-optional">可选</td><td>工具列表(最多128个)</td></tr>
<tr><td class="param-name">tool_choice</td><td class="param-type">string/object</td><td class="param-optional">可选</td><td>"none" / "auto" / "required" / 指定函数</td></tr>
<tr><td class="param-name">logprobs</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>返回 token 对数概率</td></tr>
<tr><td class="param-name">top_logprobs</td><td class="param-type">integer</td><td class="param-optional">可选</td><td>每位置返回 top N token0-20</td></tr>
<tr><td class="param-name">user_id</td><td class="param-type">string</td><td class="param-optional">可选</td><td>自定义用户标识</td></tr>
</tbody>
</table>
<div class="params-title">📤 响应字段 (choices[].message)</div>
<table class="params">
<thead><tr><th>字段名</th><th>类型</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">content</td><td class="param-type">string</td><td>模型回复内容</td></tr>
<tr><td class="param-name">reasoning_content</td><td class="param-type">string</td><td>思考模式的推理内容</td></tr>
<tr><td class="param-name">role</td><td class="param-type">string</td><td>始终为 "assistant"</td></tr>
<tr><td class="param-name">tool_calls</td><td class="param-type">array</td><td>工具调用请求</td></tr>
</tbody>
</table>
<div class="params-title">📤 响应字段 (usage)</div>
<table class="params">
<thead><tr><th>字段名</th><th>类型</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">prompt_tokens</td><td class="param-type">integer</td><td>输入 token 数</td></tr>
<tr><td class="param-name">prompt_cache_hit_tokens</td><td class="param-type">integer</td><td>缓存命中 token 数</td></tr>
<tr><td class="param-name">prompt_cache_miss_tokens</td><td class="param-type">integer</td><td>缓存未命中 token 数</td></tr>
<tr><td class="param-name">completion_tokens</td><td class="param-type">integer</td><td>输出 token 数</td></tr>
<tr><td class="param-name">total_tokens</td><td class="param-type">integer</td><td>总 token 数</td></tr>
<tr><td class="param-name">completion_tokens_details.reasoning_tokens</td><td class="param-type">integer</td><td>推理 token 数</td></tr>
</tbody>
</table>
<div class="note-box"><strong>💡 提示:</strong>思考模式下(thinking.type="enabled"),<code>reasoning_content</code> 字段包含模型的推理过程,<code>content</code> 为最终回答。多轮对话中,非工具调用轮次的 reasoning_content 不需要携带回上下文,工具调用轮次的 reasoning_content 必须携带。</div>
<!-- 示例 -->
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'cc-sdk-1')">SDK · 非流式对话</button>
<button class="code-tab" onclick="switchTab(this, 'cc-http-1')">HTTP · 流式对话</button>
<button class="code-tab" onclick="switchTab(this, 'cc-sdk-2')">SDK · 思考模式</button>
<button class="code-tab" onclick="switchTab(this, 'cc-http-2')">HTTP · 工具调用</button>
<button class="code-tab" onclick="switchTab(this, 'cc-sdk-3')">SDK · JSON 输出</button>
<button class="code-tab" onclick="switchTab(this, 'cc-sdk-4')">SDK · 多轮对话</button>
</div>
<div class="code-block">
<div class="code-panel active" id="cc-sdk-1">
<pre><span class="hl-kw">from</span> openai <span class="hl-kw">import</span> OpenAI
client = <span class="hl-fn">OpenAI</span>(<span class="hl-prop">api_key</span>=<span class="hl-str">"&lt;your api key&gt;"</span>, <span class="hl-prop">base_url</span>=<span class="hl-str">"https://api.deepseek.com"</span>)
response = client.chat.completions.<span class="hl-fn">create</span>(
<span class="hl-prop">model</span>=<span class="hl-str">"deepseek-v4-pro"</span>,
<span class="hl-prop">messages</span>=[
{<span class="hl-str">"role"</span>: <span class="hl-str">"system"</span>, <span class="hl-str">"content"</span>: <span class="hl-str">"你是一个专业的编程助手,请用中文回答。"</span>},
{<span class="hl-str">"role"</span>: <span class="hl-str">"user"</span>, <span class="hl-str">"content"</span>: <span class="hl-str">"解释 JavaScript 的事件循环机制"</span>}
],
<span class="hl-prop">stream</span>=<span class="hl-kw">False</span>
)
<span class="hl-fn">print</span>(response.choices[<span class="hl-num">0</span>].message.content)
<span class="hl-fn">print</span>(<span class="hl-str">f"输入: </span>{response.usage.prompt_tokens}<span class="hl-str"> tokens, 输出: </span>{response.usage.completion_tokens}<span class="hl-str"> tokens"</span>)</pre>
</div>
<div class="code-panel" id="cc-http-1">
<pre><span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'https://api.deepseek.com/chat/completions'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: {
<span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span>,
<span class="hl-str">'Authorization'</span>: <span class="hl-str">`Bearer ${API_KEY}`</span>
},
<span class="hl-prop">body</span>: JSON.<span class="hl-fn">stringify</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'deepseek-v4-pro'</span>,
<span class="hl-prop">messages</span>: [
{ <span class="hl-prop">role</span>: <span class="hl-str">'system'</span>, <span class="hl-prop">content</span>: <span class="hl-str">'你是一个专业的编程助手。'</span> },
{ <span class="hl-prop">role</span>: <span class="hl-str">'user'</span>, <span class="hl-prop">content</span>: <span class="hl-str">'解释 JavaScript 的事件循环机制'</span> }
],
<span class="hl-prop">stream</span>: <span class="hl-kw">true</span>
})
});
<span class="hl-kw">const</span> reader = response.body.<span class="hl-fn">getReader</span>();
<span class="hl-kw">const</span> decoder = <span class="hl-kw">new</span> <span class="hl-fn">TextDecoder</span>();
<span class="hl-kw">let</span> buffer = <span class="hl-str">''</span>;
<span class="hl-kw">while</span> (<span class="hl-kw">true</span>) {
<span class="hl-kw">const</span> { done, value } = <span class="hl-kw">await</span> reader.<span class="hl-fn">read</span>();
<span class="hl-kw">if</span> (done) <span class="hl-kw">break</span>;
buffer += decoder.<span class="hl-fn">decode</span>(value, { <span class="hl-prop">stream</span>: <span class="hl-kw">true</span> });
<span class="hl-kw">const</span> lines = buffer.<span class="hl-fn">split</span>(<span class="hl-str">'\n'</span>);
buffer = lines.<span class="hl-fn">pop</span>();
<span class="hl-kw">for</span> (<span class="hl-kw">const</span> line <span class="hl-kw">of</span> lines) {
<span class="hl-kw">if</span> (!line.<span class="hl-fn">startsWith</span>(<span class="hl-str">'data: '</span>) || line === <span class="hl-str">'data: [DONE]'</span>) <span class="hl-kw">continue</span>;
<span class="hl-kw">const</span> chunk = JSON.<span class="hl-fn">parse</span>(line.<span class="hl-fn">slice</span>(<span class="hl-num">6</span>));
<span class="hl-kw">const</span> content = chunk.choices[<span class="hl-num">0</span>]?.delta?.content;
<span class="hl-kw">if</span> (content) process.stdout.<span class="hl-fn">write</span>(content);
}
}</pre>
</div>
<div class="code-panel" id="cc-sdk-2">
<pre><span class="hl-kw">from</span> openai <span class="hl-kw">import</span> OpenAI
client = <span class="hl-fn">OpenAI</span>(<span class="hl-prop">api_key</span>=<span class="hl-str">"&lt;your api key&gt;"</span>, <span class="hl-prop">base_url</span>=<span class="hl-str">"https://api.deepseek.com"</span>)
response = client.chat.completions.<span class="hl-fn">create</span>(
<span class="hl-prop">model</span>=<span class="hl-str">"deepseek-v4-pro"</span>,
<span class="hl-prop">messages</span>=[{<span class="hl-str">"role"</span>: <span class="hl-str">"user"</span>, <span class="hl-str">"content"</span>: <span class="hl-str">"9.11 和 9.8 哪个更大?"</span>}],
<span class="hl-prop">reasoning_effort</span>=<span class="hl-str">"high"</span>,
<span class="hl-prop">extra_body</span>={<span class="hl-str">"thinking"</span>: {<span class="hl-str">"type"</span>: <span class="hl-str">"enabled"</span>}}
)
msg = response.choices[<span class="hl-num">0</span>].message
<span class="hl-fn">print</span>(<span class="hl-str">f"[思考过程]\n{msg.reasoning_content}"</span>)
<span class="hl-fn">print</span>(<span class="hl-str">f"\n[最终回答]\n{msg.content}"</span>)</pre>
</div>
<div class="code-panel" id="cc-http-2">
<pre><span class="hl-kw">const</span> response = <span class="hl-kw">await</span> <span class="hl-fn">fetch</span>(<span class="hl-str">'https://api.deepseek.com/chat/completions'</span>, {
<span class="hl-prop">method</span>: <span class="hl-str">'POST'</span>,
<span class="hl-prop">headers</span>: {
<span class="hl-str">'Content-Type'</span>: <span class="hl-str">'application/json'</span>,
<span class="hl-str">'Authorization'</span>: <span class="hl-str">`Bearer ${API_KEY}`</span>
},
<span class="hl-prop">body</span>: JSON.<span class="hl-fn">stringify</span>({
<span class="hl-prop">model</span>: <span class="hl-str">'deepseek-v4-pro'</span>,
<span class="hl-prop">messages</span>: [{ <span class="hl-prop">role</span>: <span class="hl-str">'user'</span>, <span class="hl-prop">content</span>: <span class="hl-str">'杭州今天天气怎么样?'</span> }],
<span class="hl-prop">stream</span>: <span class="hl-kw">false</span>,
<span class="hl-prop">tools</span>: [{
<span class="hl-prop">type</span>: <span class="hl-str">'function'</span>,
<span class="hl-prop">function</span>: {
<span class="hl-prop">name</span>: <span class="hl-str">'get_weather'</span>,
<span class="hl-prop">description</span>: <span class="hl-str">'获取指定城市的当前天气信息'</span>,
<span class="hl-prop">parameters</span>: {
<span class="hl-prop">type</span>: <span class="hl-str">'object'</span>,
<span class="hl-prop">properties</span>: {
<span class="hl-prop">location</span>: { <span class="hl-prop">type</span>: <span class="hl-str">'string'</span>, <span class="hl-prop">description</span>: <span class="hl-str">'城市名称'</span> }
},
<span class="hl-prop">required</span>: [<span class="hl-str">'location'</span>]
}
}
}]
})
});
<span class="hl-kw">const</span> data = <span class="hl-kw">await</span> response.<span class="hl-fn">json</span>();
console.<span class="hl-fn">log</span>(<span class="hl-str">'工具调用:'</span>, data.choices[<span class="hl-num">0</span>].message.tool_calls);</pre>
</div>
<div class="code-panel" id="cc-sdk-3">
<pre><span class="hl-kw">from</span> openai <span class="hl-kw">import</span> OpenAI
<span class="hl-kw">import</span> json
client = <span class="hl-fn">OpenAI</span>(<span class="hl-prop">api_key</span>=<span class="hl-str">"&lt;your api key&gt;"</span>, <span class="hl-prop">base_url</span>=<span class="hl-str">"https://api.deepseek.com"</span>)
response = client.chat.completions.<span class="hl-fn">create</span>(
<span class="hl-prop">model</span>=<span class="hl-str">"deepseek-v4-pro"</span>,
<span class="hl-prop">messages</span>=[
{<span class="hl-str">"role"</span>: <span class="hl-str">"system"</span>, <span class="hl-str">"content"</span>: <span class="hl-str">"请以 JSON 格式输出,包含 question 和 answer 字段。"</span>},
{<span class="hl-str">"role"</span>: <span class="hl-str">"user"</span>, <span class="hl-str">"content"</span>: <span class="hl-str">"世界上最高的山是什么?珠穆朗玛峰。"</span>}
],
<span class="hl-prop">response_format</span>={<span class="hl-str">"type"</span>: <span class="hl-str">"json_object"</span>}
)
data = json.<span class="hl-fn">loads</span>(response.choices[<span class="hl-num">0</span>].message.content)
<span class="hl-fn">print</span>(json.<span class="hl-fn">dumps</span>(data, <span class="hl-prop">ensure_ascii</span>=<span class="hl-kw">False</span>, <span class="hl-prop">indent</span>=<span class="hl-num">2</span>))</pre>
</div>
<div class="code-panel" id="cc-sdk-4">
<pre><span class="hl-kw">from</span> openai <span class="hl-kw">import</span> OpenAI
client = <span class="hl-fn">OpenAI</span>(<span class="hl-prop">api_key</span>=<span class="hl-str">"&lt;your api key&gt;"</span>, <span class="hl-prop">base_url</span>=<span class="hl-str">"https://api.deepseek.com"</span>)
messages = [
{<span class="hl-str">"role"</span>: <span class="hl-str">"system"</span>, <span class="hl-str">"content"</span>: <span class="hl-str">"你是一个专业的编程助手,请用中文回答。"</span>},
{<span class="hl-str">"role"</span>: <span class="hl-str">"user"</span>, <span class="hl-str">"content"</span>: <span class="hl-str">"JavaScript 中 Promise 和 async/await 的区别是什么?"</span>}
]
response = client.chat.completions.<span class="hl-fn">create</span>(
<span class="hl-prop">model</span>=<span class="hl-str">"deepseek-v4-pro"</span>,
<span class="hl-prop">messages</span>=messages,
<span class="hl-prop">stream</span>=<span class="hl-kw">True</span>
)
full_reply = <span class="hl-str">""</span>
<span class="hl-kw">for</span> chunk <span class="hl-kw">in</span> response:
content = chunk.choices[<span class="hl-num">0</span>].delta.content
<span class="hl-kw">if</span> content:
full_reply += content
<span class="hl-fn">print</span>(content, <span class="hl-prop">end</span>=<span class="hl-str">""</span>, <span class="hl-prop">flush</span>=<span class="hl-kw">True</span>)
<span class="hl-cm"># Continue conversation</span>
messages.<span class="hl-fn">append</span>({<span class="hl-str">"role"</span>: <span class="hl-str">"assistant"</span>, <span class="hl-str">"content"</span>: full_reply})
messages.<span class="hl-fn">append</span>({<span class="hl-str">"role"</span>: <span class="hl-str">"user"</span>, <span class="hl-str">"content"</span>: <span class="hl-str">"能给一个 async/await 的代码示例吗?"</span>})</pre>
</div>
</div>
<div class="response-title">📤 响应示例</div>
<div class="response-block">
<pre>{
<span class="hl-prop">"id"</span>: <span class="hl-str">"chatcmpl-abc123"</span>,
<span class="hl-prop">"object"</span>: <span class="hl-str">"chat.completion"</span>,
<span class="hl-prop">"created"</span>: <span class="hl-num">1716000000</span>,
<span class="hl-prop">"model"</span>: <span class="hl-str">"deepseek-v4-pro"</span>,
<span class="hl-prop">"choices"</span>: [{
<span class="hl-prop">"index"</span>: <span class="hl-num">0</span>,
<span class="hl-prop">"message"</span>: {
<span class="hl-prop">"role"</span>: <span class="hl-str">"assistant"</span>,
<span class="hl-prop">"content"</span>: <span class="hl-str">"JavaScript 的事件循环(Event Loop)是..."</span>,
<span class="hl-prop">"reasoning_content"</span>: <span class="hl-kw">null</span>,
<span class="hl-prop">"tool_calls"</span>: <span class="hl-kw">null</span>
},
<span class="hl-prop">"finish_reason"</span>: <span class="hl-str">"stop"</span>
}],
<span class="hl-prop">"usage"</span>: {
<span class="hl-prop">"prompt_tokens"</span>: <span class="hl-num">24</span>,
<span class="hl-prop">"prompt_cache_hit_tokens"</span>: <span class="hl-num">12</span>,
<span class="hl-prop">"prompt_cache_miss_tokens"</span>: <span class="hl-num">12</span>,
<span class="hl-prop">"completion_tokens"</span>: <span class="hl-num">156</span>,
<span class="hl-prop">"total_tokens"</span>: <span class="hl-num">180</span>,
<span class="hl-prop">"completion_tokens_details"</span>: {
<span class="hl-prop">"reasoning_tokens"</span>: <span class="hl-num">0</span>
}
},
<span class="hl-prop">"system_fingerprint"</span>: <span class="hl-str">"fp_abc123"</span>
}</pre>
</div>
</section>
<hr class="section-divider">
<!-- ==================== POST /completions (FIM) ==================== -->
<section class="api-section" id="completions-fim">
<h2><span class="method method-post">POST</span> /completions (FIM Beta)</h2>
<p class="desc">FIM (Fill-In-the-Middle) 补全,用于代码补全、内容续写等场景。最大补全长度 4K。仅支持非思考模式。</p>
<div class="endpoint-bar">
<span class="http-method method-post">POST</span>
<span class="url">https://api.deepseek.com/beta/completions</span>
</div>
<div class="params-title">📥 请求参数</div>
<table class="params">
<thead><tr><th>参数名</th><th>类型</th><th>必填</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">model</td><td class="param-type">string</td><td class="param-required">必填</td><td>"deepseek-v4-pro"</td></tr>
<tr><td class="param-name">prompt</td><td class="param-type">string</td><td class="param-required">必填</td><td>前缀提示</td></tr>
<tr><td class="param-name">suffix</td><td class="param-type">string</td><td class="param-optional">可选</td><td>后缀</td></tr>
<tr><td class="param-name">max_tokens</td><td class="param-type">integer</td><td class="param-optional">可选</td><td>最大生成 token 数</td></tr>
<tr><td class="param-name">stop</td><td class="param-type">string/string[]</td><td class="param-optional">可选</td><td>停止序列</td></tr>
<tr><td class="param-name">stream</td><td class="param-type">boolean</td><td class="param-optional">可选</td><td>流式输出</td></tr>
<tr><td class="param-name">temperature</td><td class="param-type">number</td><td class="param-optional">可选</td><td>采样温度</td></tr>
<tr><td class="param-name">top_p</td><td class="param-type">number</td><td class="param-optional">可选</td><td>核采样概率</td></tr>
</tbody>
</table>
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'fim-sdk')">Python SDK</button>
</div>
<div class="code-block">
<div class="code-panel active" id="fim-sdk">
<pre><span class="hl-kw">from</span> openai <span class="hl-kw">import</span> OpenAI
client = <span class="hl-fn">OpenAI</span>(<span class="hl-prop">api_key</span>=<span class="hl-str">"&lt;your api key&gt;"</span>, <span class="hl-prop">base_url</span>=<span class="hl-str">"https://api.deepseek.com/beta"</span>)
response = client.completions.<span class="hl-fn">create</span>(
<span class="hl-prop">model</span>=<span class="hl-str">"deepseek-v4-pro"</span>,
<span class="hl-prop">prompt</span>=<span class="hl-str">"def fib(a):"</span>,
<span class="hl-prop">suffix</span>=<span class="hl-str">" return fib(a-1) + fib(a-2)"</span>,
<span class="hl-prop">max_tokens</span>=<span class="hl-num">128</span>
)
<span class="hl-fn">print</span>(response.choices[<span class="hl-num">0</span>].text)</pre>
</div>
</div>
</section>
<hr class="section-divider">
<!-- ==================== GET /models ==================== -->
<section class="api-section" id="models">
<h2><span class="method method-get">GET</span> /models</h2>
<p class="desc">列出所有可用的模型。</p>
<div class="endpoint-bar">
<span class="http-method method-get">GET</span>
<span class="url">https://api.deepseek.com/models</span>
</div>
<div class="params-title">📤 响应字段</div>
<table class="params">
<thead><tr><th>字段名</th><th>类型</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">data[].id</td><td class="param-type">string</td><td>模型标识符</td></tr>
<tr><td class="param-name">data[].object</td><td class="param-type">string</td><td>始终为 "model"</td></tr>
<tr><td class="param-name">data[].owned_by</td><td class="param-type">string</td><td>模型所属组织</td></tr>
</tbody>
</table>
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'models-sdk')">Python SDK</button>
</div>
<div class="code-block">
<div class="code-panel active" id="models-sdk">
<pre><span class="hl-kw">from</span> openai <span class="hl-kw">import</span> OpenAI
client = <span class="hl-fn">OpenAI</span>(<span class="hl-prop">api_key</span>=<span class="hl-str">"&lt;your api key&gt;"</span>, <span class="hl-prop">base_url</span>=<span class="hl-str">"https://api.deepseek.com"</span>)
models = client.models.<span class="hl-fn">list</span>()
<span class="hl-kw">for</span> model <span class="hl-kw">in</span> models.data:
<span class="hl-fn">print</span>(<span class="hl-str">f"{model.id} - {model.owned_by}"</span>)</pre>
</div>
</div>
</section>
<hr class="section-divider">
<!-- ==================== GET /user/balance ==================== -->
<section class="api-section" id="balance">
<h2><span class="method method-get">GET</span> /user/balance</h2>
<p class="desc">查询当前账户的余额信息,包括赠金和充值余额。</p>
<div class="endpoint-bar">
<span class="http-method method-get">GET</span>
<span class="url">https://api.deepseek.com/user/balance</span>
</div>
<div class="params-title">📤 响应字段</div>
<table class="params">
<thead><tr><th>字段名</th><th>类型</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">currency</td><td class="param-type">string</td><td>货币: "CNY" 或 "USD"</td></tr>
<tr><td class="param-name">total_balance</td><td class="param-type">string</td><td>总可用余额</td></tr>
<tr><td class="param-name">granted_balance</td><td class="param-type">string</td><td>赠金余额</td></tr>
<tr><td class="param-name">topped_up_balance</td><td class="param-type">string</td><td>充值余额</td></tr>
</tbody>
</table>
<div class="params-title">💻 代码示例</div>
<div class="code-tabs">
<button class="code-tab active" onclick="switchTab(this, 'bal-curl')">curl</button>
</div>
<div class="code-block">
<div class="code-panel active" id="bal-curl">
<pre><span class="hl-fn">curl</span> <span class="hl-str">https://api.deepseek.com/user/balance</span> \
-H <span class="hl-str">"Authorization: Bearer ${DEEPSEEK_API_KEY}"</span></pre>
</div>
</div>
</section>
<hr class="section-divider">
<!-- ==================== 思考模式 ==================== -->
<section class="api-section" id="thinking-mode">
<h2>🧠 思考模式</h2>
<p class="desc">DeepSeek 模型支持思考模式(Thinking Mode),让模型在回答前进行深度推理。适用于数学、逻辑、编程等需要复杂推理的场景。</p>
<div class="params-title">核心参数</div>
<table class="params">
<thead><tr><th>参数名</th><th>类型</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">thinking.type</td><td class="param-type">string</td><td>"enabled"(默认)或 "disabled"</td></tr>
<tr><td class="param-name">reasoning_effort</td><td class="param-type">string</td><td>"high"(默认)或 "max"。Agent 工具(如 Claude Code)会自动设为 "max"</td></tr>
</tbody>
</table>
<div class="note-box">
<strong>💡 映射规则:</strong><code>low</code> / <code>medium</code> 映射到 <code>high</code><code>xhigh</code> 映射到 <code>max</code>。思考模式下,<code>temperature</code><code>top_p</code><code>presence_penalty</code><code>frequency_penalty</code> 参数将被忽略。
</div>
<div class="note-box">
<strong>💡 多轮对话注意事项:</strong>非工具调用轮次的 <code>reasoning_content</code> 不需要携带回上下文;工具调用轮次的 <code>reasoning_content</code> <strong>必须</strong>携带回上下文。
</div>
</section>
<hr class="section-divider">
<!-- ==================== 工具调用 ==================== -->
<section class="api-section" id="tool-calling">
<h2>🔧 工具调用</h2>
<p class="desc">DeepSeek 支持 Function Calling(工具调用),允许模型调用外部函数来获取信息或执行操作。</p>
<div class="params-title">核心要点</div>
<table class="params">
<thead><tr><th>特性</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">工具数量</td><td>最多 128 个工具</td></tr>
<tr><td class="param-name">tool_choice</td><td>"none" / "auto" / "required" / 指定函数名</td></tr>
<tr><td class="param-name">strict 模式 (Beta)</td><td>使用 <code>base_url="https://api.deepseek.com/beta"</code>,设置 <code>strict: true</code></td></tr>
<tr><td class="param-name">思考模式兼容</td><td>DeepSeek-V3.2 起支持思考模式下的工具调用</td></tr>
</tbody>
</table>
</section>
<hr class="section-divider">
<!-- ==================== JSON 输出 ==================== -->
<section class="api-section" id="json-output">
<h2>📄 JSON 输出</h2>
<p class="desc">DeepSeek 支持结构化 JSON 输出,确保模型返回合法的 JSON 格式数据。</p>
<div class="params-title">使用方法</div>
<table class="params">
<thead><tr><th>步骤</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">1. 设置格式</td><td>请求参数中设置 <code>response_format: {"type": "json_object"}</code></td></tr>
<tr><td class="param-name">2. 指示模型</td><td>必须在 system 或 user 消息中明确指示模型生成 JSON 格式输出</td></tr>
</tbody>
</table>
</section>
<hr class="section-divider">
<!-- ==================== Anthropic 兼容 ==================== -->
<section class="api-section" id="anthropic-compat">
<h2>🔗 Anthropic 兼容</h2>
<p class="desc">DeepSeek 提供 Anthropic Messages API 兼容接口,可直接使用 Anthropic SDK 调用。</p>
<div class="params-title">接入方式</div>
<table class="params">
<thead><tr><th>配置项</th><th>描述</th></tr></thead>
<tbody>
<tr><td class="param-name">Base URL</td><td><code>https://api.deepseek.com/anthropic</code></td></tr>
<tr><td class="param-name">SDK</td><td>直接使用 Anthropic SDK,无需修改代码</td></tr>
<tr><td class="param-name">支持内容类型</td><td>text content、tool_use、thinkingarray type="thinking"</td></tr>
</tbody>
</table>
</section>
<!-- FOOTER -->
<div style="text-align:center; padding: 40px 0 20px; color: var(--text-dim); font-size: 13px; border-top: 1px solid var(--border);">
<p>📄 本文档基于 <a href="https://api-docs.deepseek.com" style="color:var(--accent)">api-docs.deepseek.com</a> 官方文档生成</p>
<p>支持模型: <strong style="color:var(--green)">deepseek-v4-flash · deepseek-v4-pro</strong> · 文档日期: <strong style="color:var(--accent)">2026-05-18</strong></p>
<p style="margin-top:8px;">平台: <a href="https://platform.deepseek.com" style="color:var(--accent)">platform.deepseek.com</a> · SDK: <a href="https://github.com/openai/openai-python" style="color:var(--accent)">OpenAI SDK</a> · <a href="https://github.com/anthropics/anthropic-sdk-python" style="color:var(--accent)">Anthropic SDK</a></p>
</div>
</div>
</div>
<script>
function switchTab(clickedTab, panelId) {
const tabContainer = clickedTab.parentElement;
const blockContainer = tabContainer.nextElementSibling;
tabContainer.querySelectorAll('.code-tab').forEach(t => t.classList.remove('active'));
blockContainer.querySelectorAll('.code-panel').forEach(p => p.classList.remove('active'));
clickedTab.classList.add('active');
document.getElementById(panelId).classList.add('active');
}
// Smooth scroll for sidebar links
document.querySelectorAll('.sidebar a[href^="#"]').forEach(a => {
a.addEventListener('click', e => {
e.preventDefault();
const target = document.querySelector(a.getAttribute('href'));
if (target) target.scrollIntoView({ behavior: 'smooth', block: 'start' });
});
});
// Highlight active sidebar item on scroll
const sections = document.querySelectorAll('.api-section');
const sidebarLinks = document.querySelectorAll('.sidebar a[href^="#"]');
window.addEventListener('scroll', () => {
let current = '';
sections.forEach(s => {
if (window.scrollY >= s.offsetTop - 100) current = s.id;
});
sidebarLinks.forEach(a => {
a.classList.toggle('active', a.getAttribute('href') === '#' + current);
});
});
</script>
</body>
</html>