新闻中心
LangChain.js中追踪OpenAI模型Token用量与成本的实现指南

本教程详细介绍了如何在LangChain.js项目中准确追踪OpenAI模型(如GPT-3.5-turbo)的Token用量和运行成本。针对LangChain.py中`get_openai_callback()`在J*aScript框架中缺失的问题,我们将重点讲解如何利用LangChain.js的`callbacks`属性,通过实现`handleLLMEnd`回调函数来实时捕获并累计每次LLM运行的提示词和完成Token,从而有效管理和分析模型消耗。
引言:LangChain.js中Token用量追踪的挑战
在开发基于大型语言模型(LLM)的应用时,准确追踪Token的消耗至关重要,它直接关系到成本控制和性能优化。在LangChain的Python版本中,get_openai_callback()提供了一个便捷的方式来获取LLM调用的Token用量和成本。然而,在LangChain.js框架中,并没有一个直接对应的getOpenAICallback()函数,这使得许多开发者在尝试获取这些数据时遇到了困难。
例如,一些开发者可能会尝试使用如下代码(由一些AI助手提供),但会发现chain.getOpenAICallback等方法并不存在于LangChain.js的实际API中:
// 这是一个错误的尝试,该函数在LangChain.js中不存在
const { Chain } = require("langchain");
async function getChainRunCost(chainRunId) {
const chain = new Chain();
const callback = await chain.getOpenAICallback(chainRunId); // ❌ 此函数不存在
const cost = callback.cost;
return cost;
}本文将深入探讨LangChain.js中正确追踪OpenAI模型Token用量的方法,核心在于利用其强大的回调(Callbacks)机制。
理解LangChain.js中的回调机制
LangChain.js提供了一个灵活的回调系统,允许开发者在LLM或链(Chain)执行过程中的不同阶段插入自定义逻辑。这些回调函数可以在LLM开始、结束、错误发生时被触发,从而提供了一个观察和干预执行流程的窗口。对于Token用量追踪,我们主要关注handleLLMEnd这个回调事件,它在每次LLM调用完成时触发,并提供该次调用的详细输出信息,包括Token用量。
实现Token用量追踪
要在LangChain.js中追踪Token用量,我们需要在初始化LLM实例时,通过callbacks属性配置一个回调处理器。在这个处理器中,我们将实现handleLLMEnd方法来捕获Token数据。
核心代码示例
以下代码展示了如何使用ChatOpenAI模型,并配置handleLLMEnd回调函数来累计Prompt Token、Completion Token和总Token用量:
Avatar AI
AI成像模型,可以从你的照片中生成逼真的4K头像
92
查看详情
import { ChatOpenAI } from 'langchain/chat_models/openai';
import { HumanMessage } from 'langchain/schema'; // 用于构造Cha
t模型输入
// 定义全局变量用于累计Token用量
// 在实际应用中,这些变量可能需要存储在更持久的存储中,或与用户会话关联
let totalCompletionTokens = 0;
let totalPromptTokens = 0;
let totalExecutionTokens = 0;
// 初始化ChatOpenAI模型实例,并配置回调
const llm = new ChatOpenAI({
// 配置回调函数数组
callbacks: [
{
/**
* 在LLM调用结束时触发
* @param {object} output - LLM调用的输出结果
* @param {string} runId - 当前运行的唯一ID
* @param {string} [parentRunId] - 父级运行的ID
* @param {string[]} [tags] - 与运行相关的标签
*/
handleLLMEnd: (output, runId, parentRunId, tags) => {
// 从输出中提取Token用量信息
// 注意:llmOutput?.tokenUsage 结构可能因模型和版本而异,建议进行空值检查
const { completionTokens, promptTokens, totalTokens } = output.llmOutput?.tokenUsage || {};
// 累计Token用量
totalCompletionTokens += completionTokens ?? 0;
totalPromptTokens += promptTokens ?? 0;
totalExecutionTokens += totalTokens ?? 0;
console.log(`--- LLM Run ID: ${runId} ---`);
console.log(` Prompt Tokens (本次): ${promptTokens ?? 0}`);
console.log(` Completion Tokens (本次): ${completionTokens ?? 0}`);
console.log(` Total Tokens (本次): ${totalTokens ?? 0}`);
console.log(` 累计 Prompt Tokens: ${totalPromptTokens}`);
console.log(` 累计 Completion Tokens: ${totalCompletionTokens}`);
console.log(` 累计 Total Tokens: ${totalExecutionTokens}`);
},
},
],
modelName: 'gpt-3.5-turbo-0613', // 推荐使用此模型版本以确保Token追踪的准确性
temperature: 0.7, // 其他LLM配置,例如温度
// openaiApiKey: process.env.OPENAI_API_KEY, // 确保您的API Key已配置
});
// 示例:如何使用这个LLM实例进行多次调用
async function runTokenTrackingExample() {
console.log("--- 第一次LLM调用 ---");
const response1 = await llm.call([
new HumanMessage('请用一句话介绍大型语言模型。')
]);
console.log("Response 1:", response1.content);
console.log("\n--- 第二次LLM调用 ---");
const response2 = await llm.call([
new HumanMessage('请简述LangChain框架的核心作用。')
]);
console.log("Response 2:", response2.content);
console.log("\n--- 所有LLM调用结束 ---");
console.log(`最终累计 Prompt Tokens: ${totalPromptTokens}`);
console.log(`最终累计 Completion Tokens: ${totalCompletionTokens}`);
console.log(`最终累计 Total Tokens: ${totalExecutionTokens}`);
// 根据Token用量估算成本 (示例,实际成本请参考OpenAI定价)
// 以下价格基于GPT-3.5 Turbo 0613模型,请查阅最新官方定价
const promptCostPerKToken = 0.0015; // 每千个输入Token的价格 (美元)
const completionCostPerKToken = 0.002; // 每千个输出Token的价格 (美元)
const estimatedCost =
(totalPromptTokens / 1000) * promptCostPerKToken +
(totalCompletionTokens / 1000) * completionCostPerKToken;
console.log(`估算总成本: $${estimatedCost.toFixed(6)}`);
}
// 运行示例函数
runTokenTrackingExample();代码解析
- 全局变量: totalCompletionTokens, totalPromptTokens, totalExecutionTokens 用于在多次LLM调用之间累计Token用量。在实际应用中,这些变量可能需要与特定的用户会话或请求上下文绑定。
- ChatOpenAI初始化: 在创建ChatOpenAI实例时,传入一个callbacks数组。数组中的每个元素都是一个回调对象。
-
handleLLMEnd方法: 这是关键所在。当LLM完成一次响应后,handleLLMEnd会被调用。
- output参数包含了LLM调用的结果,其中output.llmOutput?.tokenUsage对象存储了本次调用的completionTokens(完成Token)、promptTokens(提示词Token)和totalTokens(总Token)。
- 我们通过解构赋值获取这些值,并使用空值合并运算符?? 0确保在tokenUsage不存在时默认为0,提高代码健壮性。
- 将获取到的Token用量累加到全局变量中。
- modelName: 'gpt-3.5-turbo-0613': 原始问题提到,在特定版本(如0.0.116)的LangChain.js中,使用ChatOpenAI和gpt-3.5-turbo-0613模型能够更可靠地返回Token用量。对于其他模型或LLM类型,可能需要进行测试验证。
- 成本估算: 示例中包含了基于OpenAI官方定价的简单成本估算逻辑。请务必参考OpenAI最新的定价信息。
注意事项与最佳实践
-
模型与版本兼容性:
- ChatOpenAI与特定模型: 原始问题中提到,在LangChain.js的0.0.116版本中,使用ChatOpenAI结合modelName: 'gpt-3.5-turbo-0613'可以稳定地获取Token用量。对于其他模型或LLM类型(如OpenAI而非ChatOpenAI),或不同版本的LangChain.js,Token用量报告的准确性可能会有所不同,甚至可能无法获取。建议开发者在实际项目中进行测试验证。
- 框架更新: LangChain.js是一个快速迭代的框架,API可能会发生变化。务必查阅最新官方文档,以确保回调机制和Token用量报告的兼容性。
-
集成到复杂链中:
- 即使您使用的是ConversationalRetrievalQAChain、BufferMemory和向量搜索等复杂组件,只要最终调用的底层LLM实例(例如ChatOpenAI)配置了callbacks,handleLLMEnd函数就能够捕获到每次LLM交互的Token用量。这是因为这些高级链的执行流程中,仍然会触发其内部LLM实例的调用。
-
成本估算:
- 获取Token用量是进行成本估算的基础。您可以根据OpenAI官方公布的定价模型(通常按每千个输入/输出Token计费)来计算每次LLM调用或整个会话的预估成本。
- 示例成本计算公式:总成本 = (累计提示词Token / 1000) * 提示词单价 + (累计完成Token / 1000) * 完成单价 请注意,OpenAI的定价会根据模型版本和类型有所不同,务必参考最新的官方价格表。
-
数据持久化与监控:
- 在生产环境中,简单地使用全局变量累计Token可能不足。您可能需要将这些数据发送到日志系统、监控平台或数据库中,以便进行长期分析、生成报告和设置成本预警。
-
健壮性与错误处理:
- 在handleLLMEnd回调函数中,始终对output.llmOutput?.tokenUsage进行空值或未定义检查(例如使用?.操作符和|| {}默认值),以防止因某些特殊情况(如LLM调用失败或响应格式不一致)导致程序崩溃。
总结
通过利用LangChain.js提供的回调机制,特别是handleLLMEnd函数,开发者可以有效地追踪OpenAI模型在每次运行中的Token用量。这种方法不仅解决了LangChain.py中get_openai_callback()在J*aScript框架中缺失的问题,还提供了一个灵活且强大的方式来监控和管理LLM应用的资源消耗。掌握这一技术,对于构建成本效益高、可观测性强的LLM应用至关重要。
以上就是LangChain.js中追踪OpenAI模型Token用量与成本的实现指南的详细内容,更多请关注其它相关文章!
# 不存在
# 网站二维码推广怎么做
# 浏览器网站推广
# 惠山区seo优化
# seo好的连锁
# 网站建设项目验收模板
# 京东全站营销推广效果怎么样
# 滁州网站建设及优化
# 日日做夜夜SEO
# 杭州抖音营销推广有哪些
# 海南seo全网推广
# 如何用
# 在实际
# 至关重要
# 管理器
# javascript
# 有所不同
# 运算符
# 全局变量
# 如何使用
# 回调
# cos
# gpt
# openai
# ai
# 回调函数
# 处理器
# js
# java
# python
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
QQ邮箱网页版入口 QQ邮箱官方邮箱登录通道
composer的"require-dev"部分是用来做什么的?
Sublime Text怎么设置垂直标尺_Sublime配置Rulers规范代码长度
理解Python模块与全局变量的作用域管理
怎样更改Windows系统的默认安装路径_避免C盘爆满的终极设置【技巧】
sublime侧边栏怎么增强功能_SideBarEnhancements for sublime安装与配置
cad怎么合并重叠的线段_cad清理重复重叠线条的操作方法
内存检查:在VS Code中调试C++时的内存视图
Bilibili动漫最新防封地址发布-Bilibili动漫2025年最稳正版入口推荐
12306几点到几点不能订票? | 官方最新系统维护时间全解析
Adobe PDF表单中利用J*aScript解析与格式化日期组件的教程
学习通网页版快速入口 学习通官网网页版直接打开
HTML空白字符处理机制:渲染、DOM与编码实践
PHP中获取MongoDB服务器运行时间(Uptime)的专业指南
不会效仿卡普空!《铁拳》制作人澄清:不采取赛事付费|直播|
抖音怎么赚钱_抖音创作者变现方法与途径指南
消息称三星明年 2 月正式发布 HBM4,与 SK 海力士同台竞技
mysql通配符支持数字匹配吗_mysql通配符能否用于数字匹配的解析
蛙漫限时开放最深处链接_蛙漫全站漫画会员同款秒开地址
微信商城在哪里打开【步骤】
2025年云电脑操作系统体验 | 无需本地硬件,随时随地使用高性能PC
Yandex免登录网页版地址 Yandex搜索引擎官方访问入口
怎么去除衣服上的口红印_生活小妙招教你用酒精轻松擦除
QQ邮箱正确登录入口_QQ邮箱官方网站使用地址
php源码怎么在电脑上测试_电脑测试php源码方法步骤【教程】
Angular中单选按钮的正确使用与常见陷阱解析
Kafka Streams中基于消息头条件过滤消息的实现指南
C++如何操作注册表_Windows平台下C++读写注册表的API函数详解
探索高级语言到原生C/C++的转译:挑战与内存管理策略
QQ邮箱登录首页官网地址2026 QQ邮箱官方网页入口
单射、满射与双射的关系 一文理清所有逻辑
微博网页版官方账号登录 微博网页版内容浏览使用指南
小红书网页版入口链接分享 小红书官网直接进
《明末:渊虚之羽》设计师谈设计角色:那会刚毕业 充满激情
win11如何加载ICC颜色配置文件 Win11校色文件安装与显示器色彩管理【指南】
俄罗斯Yandex免登录入口_Yandex搜索引擎官网一键直达
向日葵客户端怎么进行远程CentOS控制_向日葵客户端远程CentOS控制操作教程
如何使用CaptainHook和Composer管理Git钩子_在提交前自动运行代码检查的Composer配置
Go语言中Map值调用指针接收器方法的限制与应对
qq游戏网页版直接玩_qq游戏免下载快速入口
Win10如何开启蓝牙功能_Windows10找不到蓝牙开关解决方法
铁路12306官网网页端快速入口 铁路12306官方首页登录教程
抖音DOU+怎么投最有效 抖音付费推广的ROI提升技巧
在J*a中如何在J*a中使用异常机制记录错误日志_异常日志实践经验
微信网页版官方入口教程 微信网页版网页版快速登录步骤
J*aScript数组对象转换:按指定键分组与值收集
126邮箱手机版登录官网2026_126手机邮箱免费入口最新
小米汽车11月交付量突破40000台!雷军:将继续努力
在J*a中如何开发简易博客标签推荐系统_博客标签推荐项目实战解析
深入理解J*a合成构造器:何时以及为何阻止其生成


2025-11-24
浏览次数:次
返回列表
t模型输入
// 定义全局变量用于累计Token用量
// 在实际应用中,这些变量可能需要存储在更持久的存储中,或与用户会话关联
let totalCompletionTokens = 0;
let totalPromptTokens = 0;
let totalExecutionTokens = 0;
// 初始化ChatOpenAI模型实例,并配置回调
const llm = new ChatOpenAI({
// 配置回调函数数组
callbacks: [
{
/**
* 在LLM调用结束时触发
* @param {object} output - LLM调用的输出结果
* @param {string} runId - 当前运行的唯一ID
* @param {string} [parentRunId] - 父级运行的ID
* @param {string[]} [tags] - 与运行相关的标签
*/
handleLLMEnd: (output, runId, parentRunId, tags) => {
// 从输出中提取Token用量信息
// 注意:llmOutput?.tokenUsage 结构可能因模型和版本而异,建议进行空值检查
const { completionTokens, promptTokens, totalTokens } = output.llmOutput?.tokenUsage || {};
// 累计Token用量
totalCompletionTokens += completionTokens ?? 0;
totalPromptTokens += promptTokens ?? 0;
totalExecutionTokens += totalTokens ?? 0;
console.log(`--- LLM Run ID: ${runId} ---`);
console.log(` Prompt Tokens (本次): ${promptTokens ?? 0}`);
console.log(` Completion Tokens (本次): ${completionTokens ?? 0}`);
console.log(` Total Tokens (本次): ${totalTokens ?? 0}`);
console.log(` 累计 Prompt Tokens: ${totalPromptTokens}`);
console.log(` 累计 Completion Tokens: ${totalCompletionTokens}`);
console.log(` 累计 Total Tokens: ${totalExecutionTokens}`);
},
},
],
modelName: 'gpt-3.5-turbo-0613', // 推荐使用此模型版本以确保Token追踪的准确性
temperature: 0.7, // 其他LLM配置,例如温度
// openaiApiKey: process.env.OPENAI_API_KEY, // 确保您的API Key已配置
});
// 示例:如何使用这个LLM实例进行多次调用
async function runTokenTrackingExample() {
console.log("--- 第一次LLM调用 ---");
const response1 = await llm.call([
new HumanMessage('请用一句话介绍大型语言模型。')
]);
console.log("Response 1:", response1.content);
console.log("\n--- 第二次LLM调用 ---");
const response2 = await llm.call([
new HumanMessage('请简述LangChain框架的核心作用。')
]);
console.log("Response 2:", response2.content);
console.log("\n--- 所有LLM调用结束 ---");
console.log(`最终累计 Prompt Tokens: ${totalPromptTokens}`);
console.log(`最终累计 Completion Tokens: ${totalCompletionTokens}`);
console.log(`最终累计 Total Tokens: ${totalExecutionTokens}`);
// 根据Token用量估算成本 (示例,实际成本请参考OpenAI定价)
// 以下价格基于GPT-3.5 Turbo 0613模型,请查阅最新官方定价
const promptCostPerKToken = 0.0015; // 每千个输入Token的价格 (美元)
const completionCostPerKToken = 0.002; // 每千个输出Token的价格 (美元)
const estimatedCost =
(totalPromptTokens / 1000) * promptCostPerKToken +
(totalCompletionTokens / 1000) * completionCostPerKToken;
console.log(`估算总成本: $${estimatedCost.toFixed(6)}`);
}
// 运行示例函数
runTokenTrackingExample();