🤔 大模型TOKEN是啥
开始前,我觉得很有必要科普下 token 是啥,这关乎到后面 API 调用的计费方式。
大神通俗解释
做的科普视频非常简单接地气地说明了大模型中的 TOKEN 到底是啥👍。跳转地址:B站视频:尝试通俗解释一下:大模型的token究竟是啥。
🔌OpenAI SDK
OpenAI SDK(软件开发工具包)是 OpenAI 提供的官方客户端库,主要用于简化调用 OpenAI API 的流程。目前支持多种语言,其中使用最广泛的是 Python SDK 和 Node.js SDK。
国内大多模型都能兼容 OpenAI SDK,这里我也选择使用它来接入 deepseek 跟豆包大模型😄。
OpenAI SDK 能做什么?
功能 | 说明 |
---|---|
Chat Completion | 聊天对话、问答、多轮对话 |
Text Completion | 补全文本 |
Embedding | 生成文本向量(用于检索、相似度) |
Image Generation | 用 DALL·E 生成图像 |
Speech-to-Text | 用 Whisper 将音频转为文本 |
File 上传/管理 | 用于 fine-tuning 或向量检索 |
Assistants API | 构建多步智能体(Agent) |
🤿 深度求索/Deepseek
目前DeepSeek没有免费额度,调用前需要充值(不过很友好地提供了退款服务😄)。 我们需要创建一个 API key,👉KEY 管理页传送门。
使用感受
- DeepSeek-V3-0324 速度较快,但是资料库很久(截至24年7月),问她
今天星期几
都能回答2023年11月5日星期日
(而且每次答案都可能不一样😂); - DeepSeek-R1-0528 速度会慢些(比上述模型慢一倍),答案较为精准,价格也贵些。
🫘豆包大模型
豆包的网站做的真的是好用,实话实说整体就是比 deepseek 的高一个层级😄。以下操作截图基于 2025-07 的官网。
热门模型对比
在热门模型对比页面,我们可以看到如下的对比图。
申请KEY
- 我们点击
API接入
会弹出 APIKEY 管理页面,按需新增 KEY 即可。 实名认证
(已认证可跳过)- 选择模型(开通后会有短信提醒)
- 查看调用示例,这里选择
node.js
语言(代码里面有个多余的符号😄)
目前有免费 50W tokens 的福利✌。
推理接入点
在豆包控制台使用大模型时,会有
推理接入点
这个词,这里简单介绍下是个什么东西
在使用大语言模型进行推理服务时,推理接入点(Endpoint)是模型调用的关键入口。开发者只需通过指定的 ID 即可向大模型发起 API / SDK 推理请求,实现快速接入与灵活调用。系统提供统一的 API 调用方式、调用监控、限流策略与安全保障机制,确保推理过程的稳定性与安全性。
推理接入点类型
预置推理接入点
:当用户凭借Model ID调用火山方舟模型时,系统会自动匹配对应模型的预置推理服务;若不存在,则自动创建。适合功能测试与轻量级使用场景。其 Endpoint ID 通常为ep-m-xxx
格式。自定义推理接入点
:由用户主动创建推理接入点,支持更全面的配置能力,适用于需要精调模型接入、权限控制、算力保障、数据回流等企业级或业务集成场景。 根据接入模型服务的来源,自定义推理接入点分以下两类:方舟推理接入点
:为火山方舟模型服务创建的推理接入点。其 Endpoint ID 通常为 ep-xxx 格式。MLP 推理接入点
:为 MLP 推理服务创建的推理接入点。其 Endpoint ID 通常为 ep-s-xxx 格式。

目前(截止到8月31日),字节跳动推出数据协作奖励计划
,单模型每日免费50W的tokens,太良心啦!
模型调用监控

👨💻完整代码
运行代码前需要安装依赖:pnpm i openai picocolors
控制台问答框架
既然我们都是使用 openAI SDK 调用大模型,是不是可以写一个抽象的聊天交互工具?把用户输入的内容反馈给大模型,输出结果,接着用户继续输入问题。
于是我封装了以下的控制台(基于 node.js 自带 readline 模块)聊天工具,支持流式调用噢。
js
import OpenAI from "openai"
import { createInterface } from 'node:readline'
import pc from 'picocolors'
/**
* @typedef {Object} ModelConfig - 模型配置
* @property {String} name - 大模型名称
* @property {String} hit - 输入提示,默认为"请输入:"
* @property {Boolean} stream - 是否流式响应
* @property {Number} temperature
* @property {Number} maxToken - 默认200
* @property {Array<import("openai/resources").ChatCompletionMessageParam>} messages
* @property {String} apiKey
* @property {String} baseURL
* @property {String} model - 使用的模型标识
*/
/**@returns {ModelConfig} */
const defaultConfig = ()=>({
hit : "请输入:",
stream : false,
temperature : 0.7,
maxToken : 200,
messages : [{ role:'system', content:'你是一个专业的中文AI助理,回答问题简练明了,绝不浪费多一个字' } ],
})
/**
* @param {ModelConfig} config
* @param {String} exitCode
*/
export default (config, exitCode='exit')=>{
config = Object.assign(defaultConfig(), config)
if(!(config.baseURL && config.apiKey)){
console.error(pc.red(`请设置 apiKey、baseURL 参数`))
process.exit(0)
}
const ai = new OpenAI({ apiKey: config.apiKey, baseURL: config.baseURL })
console.debug(pc.gray(`构建 👉${config.name}👈 openai 客户端:URL=${config.baseURL} MODEL=${config.model} STREAM=${config.stream}`))
const cmd = createInterface({ input: process.stdin, output: process.stdout })
const ask = ()=> cmd.question(pc.cyan(config.hit), async content=>{
if(content == exitCode){
cmd.close()
console.debug(pc.gray("Bye!"))
process.exit(0)
}
else if(content.trim().length == 0){
console.debug(pc.gray("不支持空内容噢"))
ask()
}
else{
const started = Date.now()
const resp = await ai.chat.completions.create({
model: config.model,
messages: [
...config.messages,
{ role:'user', content }
],
temperature: config.temperature,
max_completion_tokens: config.maxToken,
stream: config.stream
})
if(!config.stream){
console.debug(pc.magenta(resp.choices[0].message.content))
}
else{
/**
* 流式返回内容
{
choices: [ { delta: [Object], index: 0 } ],
created: 1752564493,
id: '0217525644935796745cec05f59d3465a7b2d90de3637dff8b65d',
model: 'doubao-seed-1-6-flash-250615',
service_tier: 'default',
object: 'chat.completion.chunk',
usage: null
}
{
choices: [ { delta: [Object], finish_reason: 'stop', index: 0 } ],
created: 1752564493,
id: '0217525644935796745cec05f59d3465a7b2d90de3637dff8b65d',
model: 'doubao-seed-1-6-flash-250615',
service_tier: 'default',
object: 'chat.completion.chunk',
usage: null
}
*/
for await (const e of resp){
/**@type {import("openai/resources").ChatCompletionChunk.Choice} */
let d = e.choices[0]
if(d && d.delta){
process.stdout.write(pc.magenta(d.delta.content))
// 纠正输出
// if(!!d.finish_reason) console.debug("")
}
}
}
console.debug(pc.gray(`${config.stream?"\n":""}used ${((Date.now() - started)/1000).toFixed(1)} s`))
ask()
}
})
ask()
}
deepseek 调用
js
import chat from "./chat.js"
/**
* model参数:
* deepseek-chat 模型指向 DeepSeek-V3-0324
* deepseek-reasoner 模型指向 DeepSeek-R1-0528(速度慢些)
*/
chat({
name: "Deepseek/深度求索",
apiKey:"{填写你的KEY}",
baseURL:"https://api.deepseek.com",
model: "deepseek-chat"
})
豆包调用
js
import chat from "./chat.js"
chat({
stream: true,
name:"doubao/豆包",
apiKey:"{填写你的KEY}",
baseURL:'https://ark.cn-beijing.volces.com/api/v3',
model: 'doubao-seed-1-6-flash-250615'
// model: 'doubao-seed-1-6-250615'
})
运行效果
