Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
1 line
48 KiB
JSON
1 line
48 KiB
JSON
{"repo": "anh627/easygame", "files": {"docs/.vitepress/theme/components/appendix/api-intro/ApiFunctionVsHttp.vue": {"64900140d8920e20989a8ac4227900703b4f73e8": {"t": 1785746538.0167036, "n": 17080, "h": "055825151fe86cb8", "c": "<template>\n <div class=\"api-compare-root\">\n <div class=\"demo-header\">\n <span class=\"title\">📚 函数 API vs HTTP API</span>\n <span class=\"subtitle\">本地调用 vs 网络请求,文档怎么看?</span>\n </div>\n\n <div class=\"control-panel\">\n <button\n v-for=\"tab in tabs\"\n :key=\"tab.id\"\n :class=\"['tab-btn', { active: activeTab === tab.id }]\"\n @click=\"activeTab = tab.id\"\n >\n {{ tab.icon }} {{ tab.name }}\n </button>\n </div>\n\n <div class=\"visualization-area\">\n <!-- 对比视图 -->\n <div v-if=\"activeTab === 'compare'\" class=\"compare-view\">\n <div class=\"compare-cards\">\n <div class=\"compare-card\">\n <div class=\"card-header function\">\n <span class=\"card-icon\">📦</span>\n <span class=\"card-title\">函数 API</span>\n </div>\n <div class=\"card-body\">\n <div class=\"feature-list\">\n <div class=\"feature-item\">\n <span class=\"feature-label\">调用方式</span>\n <span class=\"feature-value\">直接函数调用</span>\n </div>\n <div class=\"feature-item\">\n <span class=\"feature-label\">参数传递</span>\n <span class=\"feature-value\">括号内传参</span>\n </div>\n <div class=\"feature-item\">\n <span class=\"feature-label\">返回值</span>\n <span class=\"feature-value\">直接获得结果</span>\n </div>\n <div class=\"feature-item\">\n <span class=\"feature-label\">错误处理</span>\n <span class=\"feature-value\">异常/返回值</span>\n </div>\n </div>\n <div class=\"code-block\">\n <div class=\"code-label\">Python 示例</div>\n <pre><code># 调用内置函数\nlength = len(\"hello\") # 返回 5\n\n# 调用库函数\nimport math\nresult = math.sqrt(16) # 返回 4.0\n\n# 调用自定义函数\ndef add(a, b):\n return a + b\nsum = add(3, 5) # 返回 8</code></pre>\n </div>\n </div>\n </div>\n\n <div class=\"vs-divider\">\n <span class=\"vs-text\">VS</span>\n </div>\n\n <div class=\"compare-card\">\n <div class=\"card-header http\">\n <span class=\"card-icon\">🌐</span>\n <span class=\"card-title\">HTTP API</span>\n </div>\n <div class=\"card-body\">\n <div class=\"feature-list\">\n <div class=\"feature-item\">\n <span class=\"feature-label\">调用方式</span>\n <span class=\"feature-value\">网络请求</span>\n </div>\n <div class=\"feature-item\">\n <span class=\"feature-label\">参数传递</span>\n <span class=\"feature-value\">URL/Body/Header</span>\n </div>\n <div class=\"feature-item\">\n <span class=\"feature-label\">返回值</span>\n <span class=\"feature-value\">JSON/XML 响应</span>\n </div>\n <div class=\"feature-item\">\n <span class=\"feature-label\">错误处理</span>\n <span class=\"feature-value\">状态码判断</span>\n </div>\n </div>\n <div class=\"code-block\">\n <div class=\"code-label\">HTTP 请求示例</div>\n <pre><code>POST /v1/chat/completions HTTP/1.1\nHost: api.deepseek.com\nAuthorization: Bearer sk-xxx\nContent-Type: application/json\n\n{\n \"model\": \"deepseek-chat\",\n \"messages\": [\n {\"role\": \"user\", \"content\": \"你好\"}\n ]\n}</code></pre>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- 文档对比视图 -->\n <div v-if=\"activeTab === 'docs'\" class=\"docs-view\">\n <div class=\"docs-cards\">\n <div class=\"doc-card\">\n <div class=\"doc-header\">\n <span class=\"doc-icon\">📖</span>\n <span class=\"doc-title\">函数文档怎么看</span>\n </div>\n <div class=\"doc-content\">\n <div class=\"doc-section\">\n <div class=\"doc-section-title\">🔍 关注重点</div>\n <ul class=\"doc-list\">\n <li><strong>函数签名</strong>:函数名和参数列表</li>\n <li><strong>参数类型</strong>:每个参数要什么类型</li>\n <li><strong>返回值</strong>:函数返回什么</li>\n <li><strong>异常说明</strong>:可能抛出什么错误</li>\n </ul>\n </div>\n <div class=\"doc-example\">\n <div class=\"doc-example-label\">Python 文档示例</div>\n <pre><code>def open(file: str, mode: str = 'r') -> TextIO:\n \"\"\"\n 打开文件并返回文件对象\n \n Args:\n file: 文件路径\n mode: 打开模式 ('r', 'w', 'a')\n \n Returns:\n 文件对象\n \n Raises:\n FileNotFoundError: 文件不存在\n \"\"\"</code></pre>\n </div>\n </div>\n </div>\n\n <div class=\"doc-card\">\n <div class=\"doc-header\">\n <span class=\"doc-icon\">📡</span>\n <span class=\"doc-title\">HTTP API 文档怎么看</span>\n </div>\n <div class=\"doc-content\">\n <div class=\"doc-section\">\n <div class=\"doc-section-title\">🔍 关注重点</div>\n <ul class=\"doc-list\">\n <li><strong>Endpoint</strong>:URL 路径和 HTTP 方法</li>\n <li><strong>认证方式</strong>:API Key / Token 怎么传</li>\n <li><strong>请求参数</strong>:Body / Query / Header</li>\n <li><strong>响应格式</strong>:成功和错误返回什么</li>\n </ul>\n </div>\n <div class=\"doc-example\">\n <div class=\"doc-example-label\">API 文档示例</div>\n <pre><code>POST /v1/chat/completions\n\nHeaders:\n Authorization: Bearer {api_key}\n Content-Type: application/json\n\nBody:\n{\n \"model\": \"deepseek-chat\",\n \"messages\": [...],\n \"temperature\": 0.7\n}\n\nResponse:\n{\n \"choices\": [{\n \"message\": {\"content\": \"...\"}\n }]\n}</code></pre>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- 快速判断视图 -->\n <div v-if=\"activeTab === 'quick'\" class=\"quick-view\">\n <div class=\"quick-cards\">\n <div class=\"quick-card\">\n <div class=\"quick-header\">\n <span class=\"quick-icon\">⚡</span>\n <span class=\"quick-title\">快速判断指南</span>\n </div>\n <div class=\"quick-content\">\n <div class=\"decision-tree\">\n <div class=\"decision-item\">\n <div class=\"decision-question\">看到代码里有 <code>()</code> 调用?</div>\n <div class=\"decision-answer\">→ 这是 <strong>函数 API</strong></div>\n <div class=\"decision-example\">如:len(), print(), requests.get()</div>\n </div>\n <div class=\"decision-arrow\">↓</div>\n <div class=\"decision-item\">\n <div class=\"decision-question\">看到 URL 和 HTTP 方法?</div>\n <div class=\"decision-answer\">→ 这是 <strong>HTTP API</strong></div>\n <div class=\"decision-example\">如:POST /api/users, GET https://...</div>\n </div>\n <div class=\"decision-arrow\">↓</div>\n <div class=\"decision-item\">\n <div class=\"decision-question\">看到 SDK/Client 对象?</div>\n <div class=\"decision-answer\">→ 这是 <strong>封装后的 HTTP API</strong></div>\n <div class=\"decision-example\">如:client.chat.completions.create()</div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"quick-card\">\n <div class=\"quick-header\">\n <span class=\"quick-icon\">🎯</span>\n <span class=\"quick-title\">使用场景对比</span>\n </div>\n <div class=\"quick-content\">\n <div class=\"scenario-table\">\n <div class=\"scenario-row header\">\n <div class=\"scenario-cell\">场景</div>\n <div class=\"scenario-cell\">推荐方式</div>\n <div class=\"scenario-cell\">原因</div>\n </div>\n <div class=\"scenario-row\">\n <div class=\"scenario-cell\">本地数据处理</div>\n <div class=\"scenario-cell\"><span class=\"badge function\">函数 API</span></div>\n <div class=\"scenario-cell\">快速、无需网络</div>\n </div>\n <div class=\"scenario-row\">\n <div class=\"scenario-cell\">调用 AI 模型</div>\n <div class=\"scenario-cell\"><span class=\"badge http\">HTTP API</span></div>\n <div class=\"scenario-cell\">模型在远程服务器</div>\n </div>\n <div class=\"scenario-row\">\n <div class=\"scenario-cell\">获取天气数据</div>\n <div class=\"scenario-cell\"><span class=\"badge http\">HTTP API</span></div>\n <div class=\"scenario-cell\">数据在服务商那里</div>\n </div>\n <div class=\"scenario-row\">\n <div class=\"scenario-cell\">文件读写操作</div>\n <div class=\"scenario-cell\"><span class=\"badge function\">函数 API</span></div>\n <div class=\"scenario-cell\">直接操作本地文件</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"info-box\">\n <strong>核心要点:</strong>函数 API 是\"本地办事\",HTTP API 是\"远程通信\"。看文档时,函数关注参数和返回值,HTTP API 关注 Endpoint、认证和请求/响应格式。\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref } from 'vue'\n\nconst activeTab = ref('compare')\n\nconst tabs = [\n { id: 'compare', name: '核心区别', icon: '🔍' },\n { id: 'docs', name: '文档对比', icon: '📚' },\n { id: 'quick', name: '快速判断', icon: '⚡' }\n]\n</script>\n\n<style scoped>\n.api-compare-root {\n margin: 20px 0;\n border: 1px solid var(--vp-c-divider);\n border-radius: 8px;\n background: var(--vp-c-bg-soft);\n overflow: hidden;\n}\n\n.demo-header {\n padding: 16px 20px;\n background: var(--vp-c-bg);\n border-bottom: 1px solid var(--vp-c-divider);\n}\n\n.title {\n display: block;\n font-size: 1rem;\n font-weight: 600;\n color: var(--vp-c-text-1);\n margin-bottom: 4px;\n}\n\n.subtitle {\n font-size: 0.85rem;\n color: var(--vp-c-text-2);\n}\n\n.control-panel {\n display: flex;\n gap: 0;\n border-bottom: 1px solid var(--vp-c-divider);\n background: var(--vp-c-bg);\n}\n\n.tab-btn {\n flex: 1;\n padding: 12px 16px;\n background: transparent;\n border: none;\n border-right: 1px solid var(--vp-c-divider);\n font-size: 0.85rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n color: var(--vp-c-text-2);\n}\n\n.tab-btn:last-child {\n border-right: none;\n}\n\n.tab-btn:hover {\n background: var(--vp-c-bg-mute);\n}\n\n.tab-btn.active {\n background: var(--vp-c-brand);\n color: white;\n}\n\n.visualization-area {\n padding: 20px;\n background: var(--vp-c-bg);\n}\n\n/* 对比视图 */\n.compare-view {\n width: 100%;\n}\n\n.compare-cards {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 16px;\n align-items: stretch;\n}\n\n@media (max-width: 768px) {\n .compare-cards {\n grid-template-columns: 1fr;\n }\n .vs-divider {\n display: none;\n }\n}\n\n.compare-card {\n border: 1px solid var(--vp-c-divider);\n border-radius: 8px;\n overflow: hidden;\n background: var(--vp-c-bg-soft);\n}\n\n.card-header {\n padding: 12px 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.card-header.function {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n color: white;\n}\n\n.card-header.http {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n}\n\n.card-icon {\n font-size: 1.2rem;\n}\n\n.card-body {\n padding: 16px;\n}\n\n.feature-list {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n margin-bottom: 16px;\n}\n\n@media (max-width: 480px) {\n .feature-list {\n grid-template-columns: 1fr;\n }\n}\n\n.feature-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 10px 12px;\n background: var(--vp-c-bg);\n border-radius: 6px;\n border: 1px solid var(--vp-c-divider);\n}\n\n.feature-label {\n font-size: 0.7rem;\n color: var(--vp-c-text-3);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.feature-value {\n font-size: 0.85rem;\n color: var(--vp-c-text-1);\n font-weight: 500;\n}\n\n.code-block {\n background: #0a0a0a;\n border-radius: 6px;\n overflow: hidden;\n}\n\n.code-label {\n padding: 8px 12px;\n background: #18181b;\n color: #71717a;\n font-size: 0.75rem;\n font-weight: 600;\n border-bottom: 1px solid #27272a;\n}\n\n.code-block pre {\n margin: 0;\n padding: 12px;\n color: #e4e4e7;\n font-size: 0.8rem;\n line-height: 1.6;\n overflow-x: auto;\n}\n\n.code-block code {\n font-family: 'Menlo', 'Monaco', 'Courier New', monospace;\n}\n\n.vs-divider {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.vs-text {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: var(--vp-c-bg-alt);\n border: 2px solid var(--vp-c-divider);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n font-size: 0.85rem;\n color: var(--vp-c-text-2);\n}\n\n/* 文档视图 */\n.docs-view {\n width: 100%;\n}\n\n.docs-cards {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 20px;\n}\n\n@media (max-width: 768px) {\n .docs-cards {\n grid-template-columns: 1fr;\n }\n}\n\n.doc-card {\n border: 1px solid var(--vp-c-divider);\n border-radius: 8px;\n overflow: hidden;\n background: var(--vp-c-bg-soft);\n}\n\n.doc-header {\n padding: 14px 16px;\n background: var(--vp-c-bg-alt);\n border-bottom: 1px solid var(--vp-c-divider);\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n font-size: 0.95rem;\n color: var(--vp-c-text-1);\n}\n\n.doc-icon {\n font-size: 1.2rem;\n}\n\n.doc-content {\n padding: 16px;\n}\n\n.doc-section {\n margin-bottom: 16px;\n}\n\n.doc-section-title {\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--vp-c-text-1);\n margin-bottom: 10px;\n}\n\n.doc-list {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n\n.doc-list li {\n padding: 6px 0;\n font-size: 0.85rem;\n color: var(--vp-c-text-2);\n border-bottom: 1px dashed var(--vp-c-divider);\n}\n\n.doc-list li:last-child {\n border-bottom: none;\n}\n\n.doc-list strong {\n color: var(--vp-c-brand);\n}\n\n.doc-example {\n background: #0a0a0a;\n border-radius: 6px;\n overflow: hidden;\n margin-top: 12px;\n}\n\n.doc-example-label {\n padding: 8px 12px;\n background: #18181b;\n color: #71717a;\n font-size: 0.75rem;\n font-weight: 600;\n border-bottom: 1px solid #27272a;\n}\n\n.doc-example pre {\n margin: 0;\n padding: 12px;\n color: #e4e4e7;\n font-size: 0.75rem;\n line-height: 1.6;\n overflow-x: auto;\n}\n\n.doc-example code {\n font-family: 'Menlo', 'Monaco', 'Courier New', monospace;\n}\n\n/* 快速判断视图 */\n.quick-view {\n width: 100%;\n}\n\n.quick-cards {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 20px;\n}\n\n@media (max-width: 768px) {\n .quick-cards {\n grid-template-columns: 1fr;\n }\n}\n\n.quick-card {\n border: 1px solid var(--vp-c-divider);\n border-radius: 8px;\n overflow: hidden;\n background: var(--vp-c-bg-soft);\n}\n\n.quick-header {\n padding: 14px 16px;\n background: var(--vp-c-bg-alt);\n border-bottom: 1px solid var(--vp-c-divider);\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n font-size: 0.95rem;\n color: var(--vp-c-text-1);\n}\n\n.quick-icon {\n font-size: 1.2rem;\n}\n\n.quick-content {\n padding: 16px;\n}\n\n.decision-tree {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.decision-item {\n padding: 14px;\n background: var(--vp-c-bg);\n border-radius: 8px;\n border: 1px solid var(--vp-c-divider);\n}\n\n.decision-question {\n font-size: 0.85rem;\n color: var(--vp-c-text-2);\n margin-bottom: 6px;\n}\n\n.decision-question code {\n background: var(--vp-c-bg-mute);\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 0.8rem;\n}\n\n.decision-answer {\n font-size: 0.9rem;\n color: var(--vp-c-text-1);\n font-weight: 600;\n}\n\n.decision-example {\n font-size: 0.75rem;\n color: var(--vp-c-text-3);\n margin-top: 6px;\n padding-top: 6px;\n border-top: 1px dashed var(--vp-c-divider);\n}\n\n.decision-arrow {\n text-align: center;\n color: var(--vp-c-text-3);\n font-size: 1.2rem;\n}\n\n.scenario-table {\n display: flex;\n flex-direction: column;\n gap: 1px;\n background: var(--vp-c-divider);\n border-radius: 6px;\n overflow: hidden;\n}\n\n.scenario-row {\n display: grid;\n grid-template-columns: 1.2fr 1fr 1.2fr;\n gap: 12px;\n padding: 12px;\n background: var(--vp-c-bg);\n align-items: center;\n}\n\n.scenario-row.header {\n background: var(--vp-c-bg-alt);\n font-weight: 600;\n font-size: 0.8rem;\n color: var(--vp-c-text-2);\n}\n\n.scenario-cell {\n font-size: 0.8rem;\n color: var(--vp-c-text-1);\n}\n\n.badge {\n display: inline-block;\n padding: 4px 10px;\n border-radius: 4px;\n font-size: 0.75rem;\n font-weight: 600;\n}\n\n.badge.function {\n background: rgba(16, 185, 129, 0.15);\n color: #059669;\n}\n\n.badge.http {\n background: rgba(59, 130, 246, 0.15);\n color: #2563eb;\n}\n\n/* Info Box */\n.info-box {\n display: flex;\n gap: 0.5rem;\n padding: 14px 20px;\n background: var(--vp-c-bg-soft);\n border-top: 1px solid var(--vp-c-divider);\n font-size: 0.85rem;\n color: var(--vp-c-text-2);\n line-height: 1.6;\n}\n\n.info-box strong {\n white-space: nowrap;\n flex-shrink: 0;\n color: var(--vp-c-text-1);\n}\n</style>\n"}, "78db819e841b2c0117cf1e09ceb18bb2a17b65a2": {"t": 1785765449.108592, "n": 17080, "h": "055825151fe86cb8", "c": "<template>\n <div class=\"api-compare-root\">\n <div class=\"demo-header\">\n <span class=\"title\">📚 函数 API vs HTTP API</span>\n <span class=\"subtitle\">本地调用 vs 网络请求,文档怎么看?</span>\n </div>\n\n <div class=\"control-panel\">\n <button\n v-for=\"tab in tabs\"\n :key=\"tab.id\"\n :class=\"['tab-btn', { active: activeTab === tab.id }]\"\n @click=\"activeTab = tab.id\"\n >\n {{ tab.icon }} {{ tab.name }}\n </button>\n </div>\n\n <div class=\"visualization-area\">\n <!-- 对比视图 -->\n <div v-if=\"activeTab === 'compare'\" class=\"compare-view\">\n <div class=\"compare-cards\">\n <div class=\"compare-card\">\n <div class=\"card-header function\">\n <span class=\"card-icon\">📦</span>\n <span class=\"card-title\">函数 API</span>\n </div>\n <div class=\"card-body\">\n <div class=\"feature-list\">\n <div class=\"feature-item\">\n <span class=\"feature-label\">调用方式</span>\n <span class=\"feature-value\">直接函数调用</span>\n </div>\n <div class=\"feature-item\">\n <span class=\"feature-label\">参数传递</span>\n <span class=\"feature-value\">括号内传参</span>\n </div>\n <div class=\"feature-item\">\n <span class=\"feature-label\">返回值</span>\n <span class=\"feature-value\">直接获得结果</span>\n </div>\n <div class=\"feature-item\">\n <span class=\"feature-label\">错误处理</span>\n <span class=\"feature-value\">异常/返回值</span>\n </div>\n </div>\n <div class=\"code-block\">\n <div class=\"code-label\">Python 示例</div>\n <pre><code># 调用内置函数\nlength = len(\"hello\") # 返回 5\n\n# 调用库函数\nimport math\nresult = math.sqrt(16) # 返回 4.0\n\n# 调用自定义函数\ndef add(a, b):\n return a + b\nsum = add(3, 5) # 返回 8</code></pre>\n </div>\n </div>\n </div>\n\n <div class=\"vs-divider\">\n <span class=\"vs-text\">VS</span>\n </div>\n\n <div class=\"compare-card\">\n <div class=\"card-header http\">\n <span class=\"card-icon\">🌐</span>\n <span class=\"card-title\">HTTP API</span>\n </div>\n <div class=\"card-body\">\n <div class=\"feature-list\">\n <div class=\"feature-item\">\n <span class=\"feature-label\">调用方式</span>\n <span class=\"feature-value\">网络请求</span>\n </div>\n <div class=\"feature-item\">\n <span class=\"feature-label\">参数传递</span>\n <span class=\"feature-value\">URL/Body/Header</span>\n </div>\n <div class=\"feature-item\">\n <span class=\"feature-label\">返回值</span>\n <span class=\"feature-value\">JSON/XML 响应</span>\n </div>\n <div class=\"feature-item\">\n <span class=\"feature-label\">错误处理</span>\n <span class=\"feature-value\">状态码判断</span>\n </div>\n </div>\n <div class=\"code-block\">\n <div class=\"code-label\">HTTP 请求示例</div>\n <pre><code>POST /v1/chat/completions HTTP/1.1\nHost: api.deepseek.com\nAuthorization: Bearer sk-xxx\nContent-Type: application/json\n\n{\n \"model\": \"deepseek-chat\",\n \"messages\": [\n {\"role\": \"user\", \"content\": \"你好\"}\n ]\n}</code></pre>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- 文档对比视图 -->\n <div v-if=\"activeTab === 'docs'\" class=\"docs-view\">\n <div class=\"docs-cards\">\n <div class=\"doc-card\">\n <div class=\"doc-header\">\n <span class=\"doc-icon\">📖</span>\n <span class=\"doc-title\">函数文档怎么看</span>\n </div>\n <div class=\"doc-content\">\n <div class=\"doc-section\">\n <div class=\"doc-section-title\">🔍 关注重点</div>\n <ul class=\"doc-list\">\n <li><strong>函数签名</strong>:函数名和参数列表</li>\n <li><strong>参数类型</strong>:每个参数要什么类型</li>\n <li><strong>返回值</strong>:函数返回什么</li>\n <li><strong>异常说明</strong>:可能抛出什么错误</li>\n </ul>\n </div>\n <div class=\"doc-example\">\n <div class=\"doc-example-label\">Python 文档示例</div>\n <pre><code>def open(file: str, mode: str = 'r') -> TextIO:\n \"\"\"\n 打开文件并返回文件对象\n \n Args:\n file: 文件路径\n mode: 打开模式 ('r', 'w', 'a')\n \n Returns:\n 文件对象\n \n Raises:\n FileNotFoundError: 文件不存在\n \"\"\"</code></pre>\n </div>\n </div>\n </div>\n\n <div class=\"doc-card\">\n <div class=\"doc-header\">\n <span class=\"doc-icon\">📡</span>\n <span class=\"doc-title\">HTTP API 文档怎么看</span>\n </div>\n <div class=\"doc-content\">\n <div class=\"doc-section\">\n <div class=\"doc-section-title\">🔍 关注重点</div>\n <ul class=\"doc-list\">\n <li><strong>Endpoint</strong>:URL 路径和 HTTP 方法</li>\n <li><strong>认证方式</strong>:API Key / Token 怎么传</li>\n <li><strong>请求参数</strong>:Body / Query / Header</li>\n <li><strong>响应格式</strong>:成功和错误返回什么</li>\n </ul>\n </div>\n <div class=\"doc-example\">\n <div class=\"doc-example-label\">API 文档示例</div>\n <pre><code>POST /v1/chat/completions\n\nHeaders:\n Authorization: Bearer {api_key}\n Content-Type: application/json\n\nBody:\n{\n \"model\": \"deepseek-chat\",\n \"messages\": [...],\n \"temperature\": 0.7\n}\n\nResponse:\n{\n \"choices\": [{\n \"message\": {\"content\": \"...\"}\n }]\n}</code></pre>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <!-- 快速判断视图 -->\n <div v-if=\"activeTab === 'quick'\" class=\"quick-view\">\n <div class=\"quick-cards\">\n <div class=\"quick-card\">\n <div class=\"quick-header\">\n <span class=\"quick-icon\">⚡</span>\n <span class=\"quick-title\">快速判断指南</span>\n </div>\n <div class=\"quick-content\">\n <div class=\"decision-tree\">\n <div class=\"decision-item\">\n <div class=\"decision-question\">看到代码里有 <code>()</code> 调用?</div>\n <div class=\"decision-answer\">→ 这是 <strong>函数 API</strong></div>\n <div class=\"decision-example\">如:len(), print(), requests.get()</div>\n </div>\n <div class=\"decision-arrow\">↓</div>\n <div class=\"decision-item\">\n <div class=\"decision-question\">看到 URL 和 HTTP 方法?</div>\n <div class=\"decision-answer\">→ 这是 <strong>HTTP API</strong></div>\n <div class=\"decision-example\">如:POST /api/users, GET https://...</div>\n </div>\n <div class=\"decision-arrow\">↓</div>\n <div class=\"decision-item\">\n <div class=\"decision-question\">看到 SDK/Client 对象?</div>\n <div class=\"decision-answer\">→ 这是 <strong>封装后的 HTTP API</strong></div>\n <div class=\"decision-example\">如:client.chat.completions.create()</div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"quick-card\">\n <div class=\"quick-header\">\n <span class=\"quick-icon\">🎯</span>\n <span class=\"quick-title\">使用场景对比</span>\n </div>\n <div class=\"quick-content\">\n <div class=\"scenario-table\">\n <div class=\"scenario-row header\">\n <div class=\"scenario-cell\">场景</div>\n <div class=\"scenario-cell\">推荐方式</div>\n <div class=\"scenario-cell\">原因</div>\n </div>\n <div class=\"scenario-row\">\n <div class=\"scenario-cell\">本地数据处理</div>\n <div class=\"scenario-cell\"><span class=\"badge function\">函数 API</span></div>\n <div class=\"scenario-cell\">快速、无需网络</div>\n </div>\n <div class=\"scenario-row\">\n <div class=\"scenario-cell\">调用 AI 模型</div>\n <div class=\"scenario-cell\"><span class=\"badge http\">HTTP API</span></div>\n <div class=\"scenario-cell\">模型在远程服务器</div>\n </div>\n <div class=\"scenario-row\">\n <div class=\"scenario-cell\">获取天气数据</div>\n <div class=\"scenario-cell\"><span class=\"badge http\">HTTP API</span></div>\n <div class=\"scenario-cell\">数据在服务商那里</div>\n </div>\n <div class=\"scenario-row\">\n <div class=\"scenario-cell\">文件读写操作</div>\n <div class=\"scenario-cell\"><span class=\"badge function\">函数 API</span></div>\n <div class=\"scenario-cell\">直接操作本地文件</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n\n <div class=\"info-box\">\n <strong>核心要点:</strong>函数 API 是\"本地办事\",HTTP API 是\"远程通信\"。看文档时,函数关注参数和返回值,HTTP API 关注 Endpoint、认证和请求/响应格式。\n </div>\n </div>\n</template>\n\n<script setup>\nimport { ref } from 'vue'\n\nconst activeTab = ref('compare')\n\nconst tabs = [\n { id: 'compare', name: '核心区别', icon: '🔍' },\n { id: 'docs', name: '文档对比', icon: '📚' },\n { id: 'quick', name: '快速判断', icon: '⚡' }\n]\n</script>\n\n<style scoped>\n.api-compare-root {\n margin: 20px 0;\n border: 1px solid var(--vp-c-divider);\n border-radius: 8px;\n background: var(--vp-c-bg-soft);\n overflow: hidden;\n}\n\n.demo-header {\n padding: 16px 20px;\n background: var(--vp-c-bg);\n border-bottom: 1px solid var(--vp-c-divider);\n}\n\n.title {\n display: block;\n font-size: 1rem;\n font-weight: 600;\n color: var(--vp-c-text-1);\n margin-bottom: 4px;\n}\n\n.subtitle {\n font-size: 0.85rem;\n color: var(--vp-c-text-2);\n}\n\n.control-panel {\n display: flex;\n gap: 0;\n border-bottom: 1px solid var(--vp-c-divider);\n background: var(--vp-c-bg);\n}\n\n.tab-btn {\n flex: 1;\n padding: 12px 16px;\n background: transparent;\n border: none;\n border-right: 1px solid var(--vp-c-divider);\n font-size: 0.85rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n color: var(--vp-c-text-2);\n}\n\n.tab-btn:last-child {\n border-right: none;\n}\n\n.tab-btn:hover {\n background: var(--vp-c-bg-mute);\n}\n\n.tab-btn.active {\n background: var(--vp-c-brand);\n color: white;\n}\n\n.visualization-area {\n padding: 20px;\n background: var(--vp-c-bg);\n}\n\n/* 对比视图 */\n.compare-view {\n width: 100%;\n}\n\n.compare-cards {\n display: grid;\n grid-template-columns: 1fr auto 1fr;\n gap: 16px;\n align-items: stretch;\n}\n\n@media (max-width: 768px) {\n .compare-cards {\n grid-template-columns: 1fr;\n }\n .vs-divider {\n display: none;\n }\n}\n\n.compare-card {\n border: 1px solid var(--vp-c-divider);\n border-radius: 8px;\n overflow: hidden;\n background: var(--vp-c-bg-soft);\n}\n\n.card-header {\n padding: 12px 16px;\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n font-size: 0.95rem;\n}\n\n.card-header.function {\n background: linear-gradient(135deg, #10b981 0%, #059669 100%);\n color: white;\n}\n\n.card-header.http {\n background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);\n color: white;\n}\n\n.card-icon {\n font-size: 1.2rem;\n}\n\n.card-body {\n padding: 16px;\n}\n\n.feature-list {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 12px;\n margin-bottom: 16px;\n}\n\n@media (max-width: 480px) {\n .feature-list {\n grid-template-columns: 1fr;\n }\n}\n\n.feature-item {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: 10px 12px;\n background: var(--vp-c-bg);\n border-radius: 6px;\n border: 1px solid var(--vp-c-divider);\n}\n\n.feature-label {\n font-size: 0.7rem;\n color: var(--vp-c-text-3);\n text-transform: uppercase;\n letter-spacing: 0.5px;\n}\n\n.feature-value {\n font-size: 0.85rem;\n color: var(--vp-c-text-1);\n font-weight: 500;\n}\n\n.code-block {\n background: #0a0a0a;\n border-radius: 6px;\n overflow: hidden;\n}\n\n.code-label {\n padding: 8px 12px;\n background: #18181b;\n color: #71717a;\n font-size: 0.75rem;\n font-weight: 600;\n border-bottom: 1px solid #27272a;\n}\n\n.code-block pre {\n margin: 0;\n padding: 12px;\n color: #e4e4e7;\n font-size: 0.8rem;\n line-height: 1.6;\n overflow-x: auto;\n}\n\n.code-block code {\n font-family: 'Menlo', 'Monaco', 'Courier New', monospace;\n}\n\n.vs-divider {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.vs-text {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n background: var(--vp-c-bg-alt);\n border: 2px solid var(--vp-c-divider);\n display: flex;\n align-items: center;\n justify-content: center;\n font-weight: 700;\n font-size: 0.85rem;\n color: var(--vp-c-text-2);\n}\n\n/* 文档视图 */\n.docs-view {\n width: 100%;\n}\n\n.docs-cards {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 20px;\n}\n\n@media (max-width: 768px) {\n .docs-cards {\n grid-template-columns: 1fr;\n }\n}\n\n.doc-card {\n border: 1px solid var(--vp-c-divider);\n border-radius: 8px;\n overflow: hidden;\n background: var(--vp-c-bg-soft);\n}\n\n.doc-header {\n padding: 14px 16px;\n background: var(--vp-c-bg-alt);\n border-bottom: 1px solid var(--vp-c-divider);\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n font-size: 0.95rem;\n color: var(--vp-c-text-1);\n}\n\n.doc-icon {\n font-size: 1.2rem;\n}\n\n.doc-content {\n padding: 16px;\n}\n\n.doc-section {\n margin-bottom: 16px;\n}\n\n.doc-section-title {\n font-size: 0.85rem;\n font-weight: 600;\n color: var(--vp-c-text-1);\n margin-bottom: 10px;\n}\n\n.doc-list {\n list-style: none;\n padding: 0;\n margin: 0;\n}\n\n.doc-list li {\n padding: 6px 0;\n font-size: 0.85rem;\n color: var(--vp-c-text-2);\n border-bottom: 1px dashed var(--vp-c-divider);\n}\n\n.doc-list li:last-child {\n border-bottom: none;\n}\n\n.doc-list strong {\n color: var(--vp-c-brand);\n}\n\n.doc-example {\n background: #0a0a0a;\n border-radius: 6px;\n overflow: hidden;\n margin-top: 12px;\n}\n\n.doc-example-label {\n padding: 8px 12px;\n background: #18181b;\n color: #71717a;\n font-size: 0.75rem;\n font-weight: 600;\n border-bottom: 1px solid #27272a;\n}\n\n.doc-example pre {\n margin: 0;\n padding: 12px;\n color: #e4e4e7;\n font-size: 0.75rem;\n line-height: 1.6;\n overflow-x: auto;\n}\n\n.doc-example code {\n font-family: 'Menlo', 'Monaco', 'Courier New', monospace;\n}\n\n/* 快速判断视图 */\n.quick-view {\n width: 100%;\n}\n\n.quick-cards {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 20px;\n}\n\n@media (max-width: 768px) {\n .quick-cards {\n grid-template-columns: 1fr;\n }\n}\n\n.quick-card {\n border: 1px solid var(--vp-c-divider);\n border-radius: 8px;\n overflow: hidden;\n background: var(--vp-c-bg-soft);\n}\n\n.quick-header {\n padding: 14px 16px;\n background: var(--vp-c-bg-alt);\n border-bottom: 1px solid var(--vp-c-divider);\n display: flex;\n align-items: center;\n gap: 8px;\n font-weight: 600;\n font-size: 0.95rem;\n color: var(--vp-c-text-1);\n}\n\n.quick-icon {\n font-size: 1.2rem;\n}\n\n.quick-content {\n padding: 16px;\n}\n\n.decision-tree {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.decision-item {\n padding: 14px;\n background: var(--vp-c-bg);\n border-radius: 8px;\n border: 1px solid var(--vp-c-divider);\n}\n\n.decision-question {\n font-size: 0.85rem;\n color: var(--vp-c-text-2);\n margin-bottom: 6px;\n}\n\n.decision-question code {\n background: var(--vp-c-bg-mute);\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 0.8rem;\n}\n\n.decision-answer {\n font-size: 0.9rem;\n color: var(--vp-c-text-1);\n font-weight: 600;\n}\n\n.decision-example {\n font-size: 0.75rem;\n color: var(--vp-c-text-3);\n margin-top: 6px;\n padding-top: 6px;\n border-top: 1px dashed var(--vp-c-divider);\n}\n\n.decision-arrow {\n text-align: center;\n color: var(--vp-c-text-3);\n font-size: 1.2rem;\n}\n\n.scenario-table {\n display: flex;\n flex-direction: column;\n gap: 1px;\n background: var(--vp-c-divider);\n border-radius: 6px;\n overflow: hidden;\n}\n\n.scenario-row {\n display: grid;\n grid-template-columns: 1.2fr 1fr 1.2fr;\n gap: 12px;\n padding: 12px;\n background: var(--vp-c-bg);\n align-items: center;\n}\n\n.scenario-row.header {\n background: var(--vp-c-bg-alt);\n font-weight: 600;\n font-size: 0.8rem;\n color: var(--vp-c-text-2);\n}\n\n.scenario-cell {\n font-size: 0.8rem;\n color: var(--vp-c-text-1);\n}\n\n.badge {\n display: inline-block;\n padding: 4px 10px;\n border-radius: 4px;\n font-size: 0.75rem;\n font-weight: 600;\n}\n\n.badge.function {\n background: rgba(16, 185, 129, 0.15);\n color: #059669;\n}\n\n.badge.http {\n background: rgba(59, 130, 246, 0.15);\n color: #2563eb;\n}\n\n/* Info Box */\n.info-box {\n display: flex;\n gap: 0.5rem;\n padding: 14px 20px;\n background: var(--vp-c-bg-soft);\n border-top: 1px solid var(--vp-c-divider);\n font-size: 0.85rem;\n color: var(--vp-c-text-2);\n line-height: 1.6;\n}\n\n.info-box strong {\n white-space: nowrap;\n flex-shrink: 0;\n color: var(--vp-c-text-1);\n}\n</style>\n"}}, "docs/zh-cn/appendix/4-server-and-backend/api-intro.md": {"64900140d8920e20989a8ac4227900703b4f73e8": {"t": 1786067813.1449256, "n": 6234, "h": "0df34a2201308e92", "c": "# API 入门:从零理解\"程序之间的对话\"\n\n::: tip 🎯 核心问题\n**什么是 API?** 这就像问:餐厅的菜单怎么设计,客人一看就懂?服务员怎么记单,不会出错?API 解决的就是\"程序之间如何对话\"的问题。你写代码的第一天就在用 API,只是你可能没意识到。\n:::\n\n---\n\n## 0. 新手常见的三个困惑\n\n**困惑一:API 是很高深的东西吗?**\n\n很多人一听到 API,就觉得是高级工程师才能理解的概念。其实你早就用过 API 了:\n\n```python\nlen(\"hello\") # 这就是 Python 提供的 API\nopen(\"file.txt\") # 这也是 API\nrequests.get(url) # 这还是 API\n```\n\n**困惑二:Web API 和普通 API 有什么区别?**\n\n| 类型 | 调用对象 | 通信方式 | 典型场景 |\n| :--- | :--- | :--- | :--- |\n| **函数 API** | 本地代码 | 函数调用 | `len()`, `open()` |\n| **操作系统 API** | 操作系统 | 系统调用 | 读写文件、创建进程 |\n| **Web API** | 远程服务器 | HTTP 请求 | 调用 AI 模型、获取天气 |\n\n**困惑三:我该用 HTTP 还是 SDK?**\n\n```python\n# HTTP 方式:自己处理所有细节\nimport requests\nresponse = requests.post(\n \"https://api.deepseek.com/v1/chat/completions\",\n headers={\"Authorization\": \"Bearer sk-xxx\"},\n json={\"model\": \"deepseek-chat\", \"messages\": [...]}\n)\nresult = response.json()[\"choices\"][0][\"message\"][\"content\"]\n\n# SDK 方式:管家帮你处理\nfrom openai import OpenAI\nclient = OpenAI(api_key=\"sk-xxx\")\nresponse = client.chat.completions.create(\n model=\"deepseek-chat\",\n messages=[...]\n)\nresult = response.choices[0].message.content\n```\n\n---\n\n## 1. API 的本质:插头与插座\n\n**API**(Application Programming Interface,应用程序编程接口)就是\"程序之间对话的约定\"。\n\n### 1.1 用电器来类比\n\n| 概念 | 电器类比 | API 对应 |\n| :--- | :--- | :--- |\n| **接口** | 插座形状 | 函数签名 / URL |\n| **输入** | 电流输入 | 函数参数 / 请求体 |\n| **输出** | 电器工作 | 返回值 / 响应体 |\n\n### 1.2 三种 API 形态对比\n\n<ApiTypesComparison />\n\n### 1.3 函数 API vs HTTP API 的区别\n\n很多初学者会困惑:函数 API 和 HTTP API 到底有什么区别?看文档时该如何区分?\n\n<ApiFunctionVsHttp />\n\n### 1.4 不同类型的 API 文档怎么看\n\n面对不同类型的 API 文档,关注重点各不相同:\n\n<DocumentTypesComparison />\n\n---\n\n## 2. 一次完整的 API 调用\n\n👇 **动手试试看**:点击下方按钮,观察一次完整的 API 请求-响应流程:\n\n<ApiRequestDemo />\n\n### 2.1 API 调用的四个阶段\n\n| 阶段 | 发生了什么 | 电器类比 |\n| :--- | :--- | :--- |\n| **请求** | 客户端向服务器发送请求 | 按下开关 |\n| **传输** | 请求通过网络传输到服务器 | 电流通过电线 |\n| **处理** | 服务器处理请求并返回数据 | 电器开始工作 |\n| **响应** | 客户端接收并处理返回结果 | 灯泡发光 |\n\n### 2.2 餐厅类比\n\n| 餐厅角色 | API 对应 | 说明 |\n| :--- | :--- | :--- |\n| **菜单** | API 文档 | 告诉你有哪些\"菜\"可以点 |\n| **服务员** | HTTP 协议 | 标准化的\"对话方式\" |\n| **后厨** | 服务端 | 按\"订单\"处理请求 |\n| **上菜** | 响应 | 把结果返回给\"客人\" |\n\n---\n\n## 3. HTTP 方法:你是在\"问\"还是在\"做\"?\n\n调用 Web API 时,你需要告诉服务器你想做什么。这就是 HTTP 方法的由来。\n\n### 3.1 用餐厅点餐来理解\n\n| 场景 | 现实中你会怎么说? | 对应的 HTTP 方法 |\n| :--- | :--- | :--- |\n| 你想知道今天有什么菜 | \"服务员,菜单给我看看\" | **GET** - 纯\"问\",不改数据 |\n| 你想点一份宫保鸡丁 | \"给我来份宫保鸡丁\" | **POST** - \"做\"件事,创建数据 |\n| 你想换一道菜 | \"把宫保鸡丁改成糖醋里脊\" | **PUT** - 替换数据 |\n| 你想改口味 | \"宫保鸡丁不要放花生\" | **PATCH** - 部分修改 |\n| 你不想要了 | \"算了,那道菜不要了\" | **DELETE** - 删除数据 |\n\n<HttpMethodsDemo />\n\n::: warning 关于幂等性\n**幂等性**:多次执行结果是否相同?\n\n- **幂等的操作**(GET/PUT/DELETE):点 10 次和点 1 次,结果一样\n- **不幂等的操作**(POST):点 10 次,可能创建 10 个订单\n\n**解决方案**:POST 操作用唯一 ID 校验,避免重复处理。\n:::\n\n### 3.2 HTTP 方法速查表\n\n| 方法 | 用途 | 幂等性 | 安全性 | 典型场景 |\n| :--- | :--- | :--- | :--- | :--- |\n| **GET** | 获取资源 | 是 | 是 | 查询列表、查看详情 |\n| **POST** | 创建资源 | 否 | 否 | 新增用户、提交订单 |\n| **PUT** | 全量更新 | 是 | 否 | 替换整个用户资料 |\n| **PATCH** | 部分更新 | 否 | 否 | 只修改昵称 |\n| **DELETE** | 删除资源 | 是 | 否 | 删除用户、取消订单 |\n\n---\n\n## 4. HTTP 状态码:服务器在告诉你什么?\n\n服务器回复时,会先返回一个状态码,告诉你请求是否成功。\n\n### 4.1 状态码分类\n\n<StatusCodeCategories />\n\n### 4.2 常见状态码详解\n\n| 状态码 | 含义 | 典型场景 | 客户端处理 |\n| :--- | :--- | :--- | :--- |\n| **200 OK** | 成功 | 请求正常处理 | 展示数据 |\n| **201 Created** | 创建成功 | POST 请求成功创建资源 | 跳转到新资源 |\n| **400 Bad Request** | 请求格式错误 | 参数缺失或格式不对 | 检查参数 |\n| **401 Unauthorized** | 未认证 | 没有提供有效的 API Key | 引导用户登录 |\n| **403 Forbidden** | 无权限 | API Key 没有访问该资源的权限 | 提示权限不足 |\n| **404 Not Found** | 不存在 | 请求的地址或资源不存在 | 检查 URL |\n| **429 Too Many Requests** | 请求过多 | 超过了速率限制 | 稍后重试 |\n| **500 Internal Server Error** | 服务器错误 | 服务端出了问题 | 提示用户稍后重试 |\n\n👇 **动手试试看**:点击下方按钮,了解常见状态码的含义:\n\n<StatusCodeDemo />\n\n---\n\n## 5. HTTP vs SDK:自己跑腿还是让管家代办?\n\n### 5.1 两种调用方式对比\n\n| | 🏃 **HTTP API** | 🤵 **SDK** |\n| :--- | :--- | :--- |\n| **比喻** | 自己跑腿 | 管家代办 |\n| **优点** | ✓ 所有语言都能用<br>✓ 完全控制请求细节<br>✓ 无需额外依赖 | ✓ 代码简洁易读<br>✓ 自动处理鉴权<br>✓ 内置错误重试 |\n| **缺点** | ✗ 需要处理所有细节<br>✗ 代码冗长易出错 | ✗ 需要安装依赖<br>✗ 可能有版本问题 |\n| **代码示例** | `requests.post(url, json=..., headers={...})` | `client.chat.completions.create(...)` |\n\n### 5.2 如何选择?\n\n| 场景 | 推荐方式 | 原因 |\n| :--- | :--- | :--- |\n| **快速开发** | SDK | 自动处理鉴权、错误、重试 |\n| **学习原理** | HTTP | 理解底层机制 |\n| **不支持的语言** | HTTP | 任何语言都能用 |\n| **需要定制** | HTTP | 灵活控制每个细节 |\n\n::: tip 💡 建议\n**能用 SDK 就用 SDK**,把麻烦事留给库,把时间留给自己。\n:::\n\n---\n\n## 6. 如何阅读 API 文档?\n\nAPI 文档就像说明书和菜单的结合体。你不需要从头读到尾,只需要学会\"查字典\"。\n\n### 6.1 文档阅读清单\n\n打开任何一个 API 文档(比如 OpenAI 或 DeepSeek),你只需要找这几样东西:\n\n<ApiDocumentDemo />\n\n| 项目 | 说明 | 示例 |\n| :--- | :--- | :--- |\n| **Base URL** | API 的根地址 | `https://api.deepseek.com` |\n| **Authentication** | 如何证明身份 | `Authorization: Bearer sk-xxx` |\n| **Endpoints** | 具体的接口列表 | `/v1/chat/completions` |\n| **Parameters** | 必填/可选参数 | `model`(必填)、`temperature`(可选) |\n| **Response** | 返回数据结构 | `{\"choices\": [...]}` |\n\n### 6.2 阅读文档的步骤\n\n1. **找到 Base URL** - 这是所有请求的前缀\n2. **看懂认证方式** - API Key 放在 Header 还是 Query?\n3. **找到需要的 Endpoint** - 你要调用的具体接口\n4. **查看请求参数** - 哪些必填?哪些可选?\n5. **理解返回格式** - 数据是如何组织的?\n\n---\n\n## 7. 动手练习:模拟 API 调用\n\n光说不练假把式。这里有个模拟 API,你可以随便填参数、随便改地址,看看会发生什么。\n\n<ApiPlayground />\n\n试着触发以下场景:\n- ✅ **成功请求**:填入正确的 Endpoint 和 API Key\n- ❌ **401 错误**:不填 API Key,看看服务器怎么拒绝你\n- ❌ **404 错误**:填一个不存在的地址\n\n---\n\n## 8. 小结\n\n::: info 核心要点\n1. **API 就是传声筒**,帮你把话传给另一段代码或远程服务器\n2. **你早就用过 API 了**,从 `len()` 到 `open()` 都是 API\n3. **Web API 是超能力**,让你调用千里之外的超级电脑\n4. **SDK 是好管家**,能用 SDK 就别自己跑腿\n5. **看文档找三样**:地址、鉴权、参数\n:::\n\n在 AI 编程的时代,你只需要记住这几个核心概念。剩下的细节,IDE 和 AI 助手会帮你处理。\n\n---\n\n## 名词速查表\n\n| 名词 | 全称 | 解释 |\n| :--- | :--- | :--- |\n| **API** | Application Programming Interface | 应用程序编程接口,定义了软件之间如何交互 |\n| **Web API** | - | 基于 HTTP 协议的 API,用于网络通信 |\n| **Endpoint** | - | 端点,API 的具体地址 |\n| **HTTP** | HyperText Transfer Protocol | Web API 使用的通信协议 |\n| **GET** | - | 获取资源的方法 |\n| **POST** | - | 提交数据的方法 |\n| **SDK** | Software Development Kit | 软件开发工具包,封装了底层 API 调用 |\n| **URL** | Uniform Resource Locator | API 的网络地址 |\n| **JSON** | JavaScript Object Notation | 常用的数据格式 |\n| **Authentication** | - | 验证身份的过程 |\n| **Status Code** | - | HTTP 响应中的状态码 |\n| **Request** | - | 请求 |\n| **Response** | - | 响应 |\n| **Header** | - | HTTP 头,包含元信息 |\n| **Payload** | - | 请求或响应的实际数据 |\n| **Rate Limit** | - | 速率限制 |\n| **Idempotent** | - | 幂等,多次执行结果相同 |\n| **REST** | Representational State Transfer | 一种 API 架构风格 |\n| **RPC** | Remote Procedure Call | 远程过程调用 |\n| **GraphQL** | - | 一种查询语言 API |\n| **gRPC** | - | Google 开发的高性能 RPC 框架 |\n"}}}} |