可视化入门教程讲解LLM调用流程,后续接Agent系列。社区高互动(111次),适合快速上手。
这是《构建 TinyAgent》系列的第一篇,我们将在 Node.js 中从零开始构建一个小型 agent,不依赖任何框架,只调用 API。
但在编写 agent 之前,我们需要理解调用 LLM 时实际发生了什么。如果你只用过 SDK,你可能从未见过原始请求,也不清楚它是如何工作的。六行代码、一个 API 密钥,一切就能运转,但你对请求分发和响应打印到屏幕这个过程毫无所知。
下面是一个 API 调用样本,每个细节都详细解释过了。
API 是无状态的:每次新的 API 调用都不会记住上次调用的上下文。如果你想要一个"记得"早前消息的聊天机器人,你需要自己维护消息数组,每次都重新发送整个数组。
max_tokens 是硬限制,不是目标。如果达到限制,响应会在句子中间被切断。
API 调用模式是通用的。不同的 URL、Authorization: Bearer 而不是 x-api-key、系统提示放在消息内而不是顶层。但本质上是同样的 POST、同样的 JSON、同样的 {model, messages, max_tokens}。一旦你理解了这个结构,切换服务商只需要查找替换。
API 返回一个 JSON 对象。其中有约 10 个字段,但只有四个真正重要:
经常被忽视的是:stop_reason。
它告诉你模型为什么停止了,在实际系统中可能有以下原因:
end_turn → 自然完成,你完成了
max_tokens → 达到你的上限,响应被截断
tool_use → 模型想调用工具(下一篇!)
stop_sequence → 匹配了你的停止字符串之一
如果你只检查文本而忽视 stop_reason,迟早会发布一个 bug。响应看起来一切正常,直到它突然不正常。
另一个值得牢记的字段是:usage。它显示有多少 token 进入和输出。你希望从第一天起就在日志中记录这个数字,而不是在收到惊人账单后才想起来。🤯
我一直在说"24 个输入 token"。这是什么意思:
单词不等于 token。"Unbelievable" 是一个单词但有四个 token。分词器按常见子串分割,而不是按空格。
代码比看起来的成本高。def add(a, b): 是 8 个 token。每个括号和逗号都是一个独立的 token。
JSON 很昂贵。{"a":1} 是 7 个 token。如果你的工具 schema 臃肿,它们会在每次请求中悄悄侵蚀你的预算。
非英文成本更高。日语、印地语、阿拉伯语的 token 数通常是相同内容英文版本的 2–4 倍。如果你在为全球用户构建应用,这会大幅改变你的成本计算。
英文散文的经验法则:约 1 个 token ≈ 4 个字符 ≈ 0.75 个单词。对于其他一切,在假设之前先用分词器验证一下。
每次调用都有两个度量。它们的价格不同
输出 token 的成本大约是输入 token 的 3–5 倍。这是关于 LLM 价格需要牢记的核心数字。
cost = (input_tokens / 1,000,000) × input_price
+ (output_tokens / 1,000,000) × output_price
从这种不对称性引出三点结论:
长提示很便宜。长响应很昂贵。将 50 KB 的上下文塞进系统提示是没问题的。请求 50 KB 的输出大约贵 5 倍。
"思考"token 计入输出。推理模型按输出价格计费其内部思考过程,即使你看不到。
工具 schema 在每次调用时都会消耗输入 token。它们会随着系统提示一起在每次请求中重新发送。
以每次调用 $0.006 计算,每天 10 万次调用意味着每月要花 $600 用在一个小功能上。现在就添加使用日志,不要等到告警来了才行动。🚨
这是我们上面讨论的 API 调用的完整代码:
Jasmin2895 / TinyAgent
无任何依赖且无安装设置,只是一个带 API 密钥的 Node 文件。
运行它并观察数字。进行十次调用,改变提示长度,看看 usage 如何变化。通过这种方式,你会比阅读任何文档更快地建立真实的成本直觉。
运行它并观察数字。进行十次调用,改变提示长度,看看 usage 如何变化。通过这种方式,你会比阅读任何文档更快地建立真实的成本直觉。
设置 max_tokens: 20 并要求输出长内容。观察它如何被切断。检查 stop_reason。这是一个你在生产环境中迟早会遇到的 bug,最好现在故意遇见它。
设置 max_tokens: 20 并要求输出长内容。观察它如何被切断。检查 stop_reason。这是一个你在生产环境中迟早会遇到的 bug,最好现在故意遇见它。
手动构建多轮对话。保持一个 messages 数组,将每个用户消息和每个模型回复推送到其中,然后每轮都重新发送整个内容。一旦你这样做了,你会立即明白为什么长对话会变得昂贵——你在每次调用时为完整历史支付费用。
手动构建多轮对话。保持一个 messages 数组,将每个用户消息和每个模型回复推送到其中,然后每轮都重新发送整个内容。一旦你这样做了,你会立即明白为什么长对话会变得昂贵——你在每次调用时为完整历史支付费用。
在接下来的系列文章中,我们将扩展 TinyAgent 的能力,使其能够处理比仅仅响应更多的事情。
某些评论可能仅对已登录用户可见。登录以查看所有评论。