我用 30 行代码,搞懂了大模型是怎么"读"中文的

我用 30 行代码,搞懂了大模型是怎么"读"中文的

💡 你知道吗?你发给 ChatGPT 的每一句话,它其实根本看不懂。它看到的是一串数字,而你看到的文字,在它眼里只是"Token"。

写在前面

前两天有个朋友问我:"为什么我让 AI 帮我翻译一篇文章,明明没几个字,API 调用花了好几块钱?"

我当时就想,这哥们肯定不知道 Token 这玩意儿。

后来我花了一下午,从 GPT 之父 Karpathy 的视频啃到源码,终于把 Token 和 Embedding 这俩概念彻底搞明白了。今天分享给大家,保证看完你就知道:

  • 为什么中文比英文"贵"
  • 为什么 AI 能理解"猫"和"狗"是相似的东西
  • 为什么你写的 Prompt 越长,钱包越疼
  • 为什么网传的"文言文省钱法"其实是个坑

一、先说结论:AI 是个"文盲"

你没看错,大模型本质上是个文盲

它不认识字,不认识单词,不认识任何人类语言。它只认识数字。

这就很离谱了------一个不认识字的东西,怎么写出那么流畅的文章?

秘密就在于:在它"看"文字之前,先把文字变成数字了。

这个过程叫 Tokenization(分词) ,而变出来的数字就叫 Token


二、Token 到底是啥?

你可以把 Token 理解为大模型的"词汇单位"

但这里有个坑:Token ≠ 单词,Token ≠ 汉字

举个例子:

javascript 复制代码
// "Hello" → 1 个 token
// "Tokenization" → 可能被拆成 3-4 个 token
// "你好世界" → 大概 2-4 个 token

为什么不能直接用一个字/单词当一个 token 呢?

因为:

  1. 词表会爆炸:英语几十万单词,中文几万个汉字,再加上各种组合,词表会大到离谱
  2. 没见过的词怎么办:你总不能说"这个词不在词表里,我就不处理了吧"
  3. 效率问题:token 太细,一句话变成几百个 token,计算量扛不住

所以 GPT 用了一个叫 BPE(Byte Pair Encoding) 的算法,简单说就是:

高频出现的字符组合,会被合并成一个 token

就像"的"字在中文里出现频率超高,它就会被单独编码成一个 token。而一些生僻词,可能会被拆成几个常见的 token 组合。


三、动手试试:30 行代码搞懂分词

光说不练假把式,直接上代码:

javascript 复制代码
import { getEncoding } from 'js-tiktoken';

// GPT-4 用的编码器
const enc = getEncoding('cl100k_base');

// 试试中英文混合
const text = "Hello, tiktoken! 你好,世界!";
const tokens = enc.encode(text);

console.log("原始文本:", text);
console.log("Token IDs:", tokens);
console.log("Token 数量:", tokens.length);

// 反向解码验证
console.log("解码回来:", enc.decode(tokens));

输出大概长这样:

yaml 复制代码
原始文本: Hello, tiktoken! 你好,世界!
Token IDs: [9906, 11, 65402, 9039, 0, 57668, 3837, 35148, 120657, 30982]
Token 数量: 10
解码回来: Hello, tiktoken! 你好,世界!

看到了吧,一句看起来很短的话,已经用了 10 个 token。

而且中文特别吃亏------一个汉字大概 0.6-1 个 token,而英文一个字母才 0.3 个 token。所以同样的意思,中文表达会更贵。

这就是为什么很多程序员写 Prompt 喜欢用英文的原因之一(不是耍帅,是真的省钱)。


四、网传的"文言文省钱大法",靠谱吗?

最近网上有个特别火的说法:用文言文写 Prompt,token 数直接腰斩

我一开始也觉得离谱,直到我亲自测了一下......结果发现事情没那么简单。

实测:文言文常用字反而更贵!

javascript 复制代码
import { getEncoding } from 'js-tiktoken';
const enc = getEncoding('cl100k_base');

// 单字对比
console.log("我:", enc.encode("我").length);  // 1 token
console.log("吾:", enc.encode("吾").length);  // 2 tokens!

console.log("你:", enc.encode("你").length);  // 1 token
console.log("汝:", enc.encode("汝").length);  // 2 tokens!

console.log("看:", enc.encode("看").length);  // 1 token
console.log("观:", enc.encode("观").length);  // 2 tokens!

// 生僻字更离谱
console.log("矣:", enc.encode("矣").length);  // 3 tokens!
console.log("兮:", enc.encode("兮").length);  // 2 tokens

文言文那些"古风"字,很多反而要 2-3 个 token!

那为什么整体看起来省了?

因为文言文句子更短。虽然单字贵,但字数少,总 token 数可能还是少一些:

场景 现代中文 文言文 差异
简单指令 "帮我翻译成英文" (11) "译为英文" (5) -55%
复杂指令 "请帮我分析这段代码的性能问题..." (28) "析此码之性能..." (22) -21%
带专业术语 "用 React hooks 实现防抖" (11) "以 React hooks 作防抖" (11) 0%

但问题来了:省的那点钱,值吗?

不值。 原因如下:

  1. 歧义风险:文言文表达可能让 AI 理解偏差,回答不对 → 多轮追问 → 总成本更高
  2. 专业术语省不了:React、TypeScript、API 这些该几个 token 还是几个
  3. 维护成本:你写 Prompt 要先"翻译"成文言文,累不累?

真正省钱的方法:结构化格式

javascript 复制代码
// 啰嗦版:47 tokens
"请帮我分析一下这段代码的性能问题,我想知道有哪些地方可以优化,能不能给出具体的优化建议和代码示例。"

// 文言文版:24 tokens(但有歧义风险)
"析此码之性能,寻可优化之处,予策并示其码。"

// 结构化版:32 tokens(清晰 + 省钱)✅ 推荐
"分析代码性能:\n- 找出瓶颈\n- 给出优化建议\n- 附代码示例"

// 极简版:15 tokens(最省,但可能丢信息)
"性能分析 + 优化建议 + 代码示例"

结论:用现代中文 + 结构化格式(bullet points、markdown headers),既省 token 又保证质量。

别迷信文言文,那是噱头。真正省 token 的是精简表达 + 结构化


五、Embedding:让 AI 看懂语义

好,现在我们知道文字变成 Token ID 了。但问题来了:

javascript 复制代码
// "猫" → token ID: 1234
// "狗" → token ID: 5678

这两个数字在数学上毫无关系,模型怎么知道它们都是动物?

答案是 Embedding(向量化)

什么是 Embedding?

简单说,就是把每个 token 映射到一个高维空间里的一个点。

arduino 复制代码
"猫" → [0.2, -0.5, 0.8, 0.1, ...]  // 1024 维向量
"狗" → [0.3, -0.4, 0.7, 0.2, ...]  // 很接近!
"汽车" → [-0.8, 0.1, 0.3, -0.6, ...]  // 差很远

在这个空间里,语义相近的词,距离也相近

这就像你在地图上找位置------北京和天津很近,和纽约很远。Embedding 就是给每个词画了一张"语义地图"。

实测:用 API 算语义相似度

javascript 复制代码
import OpenAI from 'openai';

const client = new OpenAI({
    apiKey: process.env.DASHSCOPE_API_KEY,
    baseURL: process.env.DASHSCOPE_baseURL,
});

async function getEmbedding(text) {
    const res = await client.embeddings.create({
        model: 'text-embedding-v4',
        input: text,
        dimensions: 1024
    });
    return res.data[0].embedding;
}

// 余弦相似度:算两个向量有多"像"
function cosineSimilarity(a, b) {
    let dot = 0, magA = 0, magB = 0;
    for (let i = 0; i < a.length; i++) {
        dot += a[i] * b[i];
        magA += a[i] ** 2;
        magB += b[i] ** 2;
    }
    return dot / (Math.sqrt(magA) * Math.sqrt(magB));
}

// 测试!
const vec1 = await getEmbedding("Karpathy 讲解大模型分词原理");
const vec2 = await getEmbedding("GPT 之父解释 Tokenization");
const vec3 = await getEmbedding("今天中午吃什么");

console.log(cosineSimilarity(vec1, vec2));  // 0.85+ ← 语义相似
console.log(cosineSimilarity(vec1, vec3));  // 0.15- ← 毫不相干

神奇吧? 两句话用词完全不同,但 Embedding 知道它们"意思差不多"。


六、这玩意儿有啥用?

你可能觉得"哦知道了,然后呢?"

其实 Token + Embedding 是很多 AI 应用的基石:

1. 语义搜索

传统搜索只能关键词匹配,搜"苹果手机"找不到"iPhone"。

有了 Embedding,你可以算语义相似度,搜"苹果手机"也能找到"iPhone 15 Pro Max 评测"。

2. RAG(检索增强生成)

就是让大模型先在你的文档里搜相关内容,再基于搜到的内容回答问题。

没有 Embedding,RAG 就是个笑话。

3. 智能推荐

用户喜欢看"JavaScript 性能优化",你就可以用 Embedding 找语义相似的文章推荐给他。

4. 去重

一堆文章里有很多重复内容?Embedding + 相似度阈值,轻松去重。


七、一些踩坑经验

1. Token 数量决定成本

调 API 是按 Token 计费的。你发给模型的 Prompt 越长,返回的内容越多,钱包越疼。

所以写 Prompt 的时候:

  • 能用一句说清的,别写三句
  • 别把无关的上下文塞进去
  • 善用 System Prompt 复用
  • 用结构化格式,别用文言文

2. 中文真的贵

同样的意思,英文表达比中文便宜 30-50%。如果你的场景对语言没要求,用英文 Prompt 能省不少钱。

3. 不是维度越高越好

Embedding 维度越高,理论上表达能力越强,但计算成本也越高。1024 维对于大多数场景已经够用了。

最后

Token 和 Embedding 这两个概念,说难不难,说简单也不简单。但理解它们之后,你会对大模型的工作原理有质的认知。

下次再看到 API 按 Token 计费,你就知道为什么了。

下次再写 Prompt,你会更注意精简,用结构化格式而不是啰嗦的长句。

下次再做 RAG,你会知道底层是怎么检索的。

这就是底层知识的价值------它不会让你立刻变强,但会让你理解"为什么"。

相关推荐
武子康4 小时前
调查研究-196 CEO-Bench:Agent 不再只是“做任务“,而是要学会“经营一个系统“
人工智能
默_笙4 小时前
🍞 我用 CSS 画了一个会转的 3D 立方体,同事以为我学了 Three.js(这节课真的很神奇,我很喜欢)
javascript
用户329901675054 小时前
把AI返回的Markdown表格渲染成可排序表格
人工智能
还好还好不是吗4 小时前
MatrixMedia HTTP 发布接口:让 AI 工作流直接驱动多平台视频发布
人工智能
贵慜_Derek4 小时前
复杂系统没法一把梭重构:Semi-Autoresearch 怎么小步迁移还不掉功能
人工智能·agent·ai编程
ctxinf4 小时前
Vercel Eve 实际上手初探
人工智能
HjhIron4 小时前
工具调用:当LLM学会使用"武器",AI Agent的底层逻辑拆解
llm·agent
用户5191495848454 小时前
利用ShellcodePack实现DLL劫持与COM对象劫持技术详解
人工智能·aigc
sarasuki4 小时前
JavaScript的对象、new的机制与原型包装类
javascript·后端
武子康4 小时前
调查研究-195 从 AmEx 支付系统看 Cell-based Architecture:真正的高可用,不是无限重试,而是控制失败边界
人工智能·openai·agent