新闻中心
在LangChain.js中高效追踪OpenAI模型令牌消耗与成本

本文旨在解决LangChain.js开发者在监控OpenAI模型令牌使用量和相关成本时遇到的挑战,尤其是在缺乏Python中`get_openai_callback()`直接对应功能的情况下。文章将详细介绍如何通过利用`ChatOpenAI`模型中的`handleLLMEnd`回调函数,精确地追踪每次模型运行的提示令牌、完成令牌及总令牌消耗,从而实现更精细的成本管理和性能分析。
在开发基于LangChain.js和OpenAI的项目时,准确追踪大型语言模型(LLM)的令牌消耗是优化成本和分析性能的关键一环。与LangChain Python框架中提供便捷的get_openai_callback()方法不同,LangChain.js目前并未提供一个直接的、等价的API来轻松获取每次链运行的令牌使用和成本信息,这给许多开发者带来了困扰。本文将详细阐述一种有效的方法,通过利用LangChain.js中LLM回调机制,实现对OpenAI模型令牌消耗的精确监控。
核心方法:利用handleLLMEnd回调函数
LangChain.js提供了强大的回调系统,允许开发者在LLM生命周期的不同阶段注入自定义逻辑。对于追踪令牌消耗,handleLLMEnd回调函数是理想的选择。这个函数会在每次LLM调用结束时被触发,并提供包含令牌使用信息的output参数。
Avatar AI
AI成像模型,可以从你的照片中生成逼真的4K头像
92
查看详情
实现步骤
- 导入ChatOpenAI: 确保您正在使用langchain/chat_models/openai模块中的ChatOpenAI类,因为目前观察到此方法在ChatOpenAI上表现最为稳定,尤其是在特定模型版本下。
- 定义令牌计数器: 初始化几个变量来累计不同类型的令牌消耗,例如totalCompletionTokens、totalPromptTokens和totalExecutionTokens。
- 配置callbacks属性: 在实例化ChatOpenAI时,通过callbacks属性传入一个包含回调函数的数组。
- 实现handleLLMEnd: 在回调对象中,定义handleLLMEnd方法。此方法接收output、runId等参数。关键在于从output.llmOutput?.tokenUsage中提取completionTokens、promptTokens和totalTokens。
- 累加令牌: 将提取到的令牌数量累加到预定义的计数器中。
示例代码
以下是实现令牌追踪的完整代码示例:
import { ChatOpenAI } from 'langchain/chat_models/openai';
import { HumanMessage } from 'langchain/schema';
// 定义全局变量来累积令牌使用量
let totalCompletionTokens = 0;
let totalPromptTokens = 0;
let totalExecutionTokens = 0;
// 实例化ChatOpenAI模型,并配置回调函数
const llm = new ChatOpenAI({
// 配置回调数组
callbacks: [
{
// handleLLMEnd在LLM调用结束后触发
handleLLMEnd: (output, runId, parentRunId?, tags?) => {
// 从output中安全地提取tokenUsage信息
const { completionTokens, promptTokens, totalTokens } = output.llmOutput?.tokenUsage || {};
// 累加令牌数量,确保处理undefined情况
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 for thi
s run: ${totalTokens ?? 0}`);
console.log(`Current Accumulated Total Tokens: ${totalExecutionTokens}`);
},
},
],
// 推荐使用特定的模型版本,例如 'gpt-3.5-turbo-0613'
// 注意:某些模型或版本可能存在令牌统计不准确的问题
modelName: 'gpt-3.5-turbo-0613',
// 其他OpenAI API参数,例如 temperature, openAIApiKey等
temperature: 0.7,
openAIApiKey: process.env.OPENAI_API_KEY, // 确保从环境变量获取API Key
});
// 示例:执行一次LLM调用
async function runExampleChat() {
console.log("Starting LLM call...");
const response = await llm.call([
new HumanMessage("请用一句话介绍一下大型语言模型。"),
]);
console.log("LLM Response:", response.content);
console.log("\n--- Final Token Usage Summary ---");
console.log(`Total Prompt Tokens Across All Runs: ${totalPromptTokens}`);
console.log(`Total Completion Tokens Across All Runs: ${totalCompletionTokens}`);
console.log(`Total Execution Tokens Across All Runs: ${totalExecutionTokens}`);
// 重置计数器以便进行下一次独立测试(可选)
totalCompletionTokens = 0;
totalPromptTokens = 0;
totalExecutionTokens = 0;
}
// 调用示例函数
runExampleChat().catch(console.error);
// 示例:执行另一次LLM调用
async function runAnotherExampleChat() {
console.log("\nStarting another LLM call...");
const response = await llm.call([
new HumanMessage("解释一下云计算的优势。"),
]);
console.log("LLM Response:", response.content);
console.log("\n--- Final Token Usage Summary ---");
console.log(`Total Prompt Tokens Across All Runs: ${totalPromptTokens}`);
console.log(`Total Completion Tokens Across All Runs: ${totalCompletionTokens}`);
console.log(`Total Execution Tokens Across All Runs: ${totalExecutionTokens}`);
}
// 可以在适当的时机调用 runAnotherExampleChat()
// setTimeout(() => runAnotherExampleChat().catch(console.error), 3000);代码解析
- output.llmOutput?.tokenUsage: 这是获取令牌使用信息的关键路径。llmOutput是一个可选属性,其中包含LLM的详细输出信息,而tokenUsage则是一个对象,包含了completionTokens(模型生成的令牌)、promptTokens(输入给模型的令牌)和totalTokens(总令牌)。
- ?? 0: 使用空值合并运算符确保即使tokenUsage属性或其子属性为undefined,也能安全地将其视为0,避免计算错误。
- modelName: 'gpt-3.5-turbo-0613': 这是一个重要的注意事项。根据社区反馈,在LangChain.js的某些版本(如0.0.116)中,令牌统计功能在使用ChatOpenAI和特定模型(如gpt-3.5-turbo-0613)时更为可靠。使用其他LLM类或模型可能无法正确返回令牌信息,这可能是一个框架特性或潜在的bug。
注意事项与成本计算
- 模型兼容性: 强烈建议使用ChatOpenAI类,并尝试使用如gpt-3.5-turbo-0613或更新的聊天模型版本。如果遇到令牌统计不准确的问题,首先检查所使用的LLM类和模型版本。
- 全局计数器: 示例中使用了全局变量来累积令牌。在实际生产环境中,您可能需要更复杂的管理方式,例如将这些计数器封装在一个服务或类中,或者与日志系统、监控系统集成。
-
成本计算: 一旦获取了promptTokens和completionTokens,就可以根据OpenAI的官方定价模型来计算成本。OpenAI通常会为输入(prompt)和输出(completion)令牌设定不同的费率。
- 例如,如果Prompt Token价格为P美元/千令牌,Completion Token价格为C美元/千令牌,则总成本可以计算为: Cost = (totalPromptTokens / 1000) * P + (totalCompletionTokens / 1000) * C 请务必查阅OpenAI的最新定价页面以获取准确的费率。
- 异步与并发: 如果您的应用涉及大量并发的LLM调用,确保您的令牌计数器能够正确处理并发写入,例如使用原子操作或适当的锁机制(在J*aScript中可能需要考虑更高级的并发控制策略,或者将计数逻辑放在单线程事件循环中)。
总结
尽管LangChain.js目前没有像Python那样直接的get_openai_callback()方法来获取令牌消耗,但通过利用ChatOpenAI的callbacks属性和handleLLMEnd回调函数,开发者可以有效地追踪每次LLM调用的令牌使用情况。这种方法不仅有助于精确监控成本,还能为性能分析和资源优化提供宝贵的数据。在实施时,请务必关注模型兼容性、成本计算逻辑以及在复杂应用场景下的计数器管理。
以上就是在LangChain.js中高效追踪OpenAI模型令牌消耗与成本的详细内容,更多请关注其它相关文章!
# python
# java
# js
# 云计算
# 回调函数
# ai
# 环境变量
# javascript
# 可选
# 江苏网站优化服务公司
# 管理器
# 株洲网站建设哪家优惠好
# 政和公司seo优化
# 汕头推广营销软件
# 海口公司网站推广
# 金山区推广网站价格表格
# 莆田网站建设的热点
# 股票网站推广有哪些
# 成都seo优化哪家有
# 网站优化怎么做的快些呢
# 运算符
# 全局变量
# 您的
# 这是
# 是一个
# 如何使用
# 回调
# 令牌
# 资源
# cos
# gpt
# openai
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
特斯拉自动驾驶房车计划曝光 原型车将于2027年亮相
新手怎么开始学化妆 零基础化妆入门教程
Excel中VLOOKUP的第四个参数是干什么用的_Excel VLOOKUP第四参数作用解析
J*a中实现Go语言select通道多路复用机制
CSS Grid如何控制元素对齐_align-items与justify-items组合使用
Lar*el的路由模型绑定怎么用_Lar*el Route Model Binding简化控制器逻辑
顺丰国际快递查询 国际件官方查询入口
PostgreSQL海量数据高效导入策略:Python与Django实践指南
b站如何看历史记录_b站观看历史找回方法
AO3网页版合集入口 Archive of Our Own同人作品浏览指南
sublime怎么设置启动时打开的窗口_sublime会话管理与热退出
夸克浏览器图书入口 夸克手机浏览器阅读入口
2026年发布! 美少女养成动作RPG《神剑少女战记》发布实机演示
离线运行Go语言之旅:本地部署与GOPATH配置指南
c++中的std::forward_list和std::list有什么不同_c++ forward_list与list区别分析
如何在 Excel Online 和 Google 表格中更改日期格式
如何使用Go和Martini动态服务解码后的图片
2306选座时如何选靠窗位置_12306选座靠窗座位查看方法解析
汽车之家官方网站官网入口_汽车之家网页版直接进入
钉钉视频会议声音异常如何处理 钉钉会议音频修复技巧
Golang如何处理RPC请求负载均衡_Golang RPC请求负载均衡策略与实践
Linux如何构建多环境配置管理_Linux多环境配置方案
J*a 递归快速排序中静态变量的状态管理与陷阱
在Go语言中利用后缀数组处理多字符串:实现高效文本匹配与自动补全
J*aScript对象创建方式_J*aScript设计模式应用
KFC套餐升级怎么获取优惠代码_KFC套餐升级活动与优惠代码获取方法
2025俄罗斯Yandex最新入口 官方网站地址及浏览器下载指南
拼多多赚钱渠道_拼多多收益来源
苹果手机如何防止被恶意App追踪
漫蛙MANWA漫画主页官方入口 漫蛙漫画最新在线阅读地址
WordPress插件开发:正确注册卸载钩子与避免常见陷阱
b站赚钱渠道_b站收益来源
QQ邮箱稳定登录入口_QQ邮箱官方网站网页版使用
解决Python logging 中 datefmt 导致时间戳固定不变的问题
高德地图怎么看全景照片_高德地图全景照片浏览教程
HTML转PPT成品工具有哪些?HTML网页转PPT成品工具大全
AO3官网镜像链接 Archive of Our Own同人文在线浏览
TypeScript/J*aScript:高效查找数组中首个唯一ID对象
c++中的const_cast和reinterpret_cast怎么用_c++四种类型转换
msn官网入口地址手机版 msn官方网站手机最新链接
高德地图公交到站提醒失败如何解决 高德提醒权限设置
Win11怎么修改默认浏览器_Windows 11设置Chrome为默认
C++如何检测键盘输入_C++ _kbhit与_getch函数非阻塞输入
php源码怎么在电脑上测试_电脑测试php源码方法步骤【教程】
Angular Material 垂直步进器:实现底部到顶部排序的教程
Excel如何用迷你图显趋势_Excel用迷你图显趋势【趋势小图】
菜鸟取件码是什么怎么查 最全查询渠道汇总
J*aScript中localStorage数据的获取、清洗与格式化教程
一加手机电池耗电快怎么办_一加手机电池耗电快的解决方法
AO3最新入口2025公告_AO3中文官网合集


2025-11-24
浏览次数:次
返回列表
s run: ${totalTokens ?? 0}`);
console.log(`Current Accumulated Total Tokens: ${totalExecutionTokens}`);
},
},
],
// 推荐使用特定的模型版本,例如 'gpt-3.5-turbo-0613'
// 注意:某些模型或版本可能存在令牌统计不准确的问题
modelName: 'gpt-3.5-turbo-0613',
// 其他OpenAI API参数,例如 temperature, openAIApiKey等
temperature: 0.7,
openAIApiKey: process.env.OPENAI_API_KEY, // 确保从环境变量获取API Key
});
// 示例:执行一次LLM调用
async function runExampleChat() {
console.log("Starting LLM call...");
const response = await llm.call([
new HumanMessage("请用一句话介绍一下大型语言模型。"),
]);
console.log("LLM Response:", response.content);
console.log("\n--- Final Token Usage Summary ---");
console.log(`Total Prompt Tokens Across All Runs: ${totalPromptTokens}`);
console.log(`Total Completion Tokens Across All Runs: ${totalCompletionTokens}`);
console.log(`Total Execution Tokens Across All Runs: ${totalExecutionTokens}`);
// 重置计数器以便进行下一次独立测试(可选)
totalCompletionTokens = 0;
totalPromptTokens = 0;
totalExecutionTokens = 0;
}
// 调用示例函数
runExampleChat().catch(console.error);
// 示例:执行另一次LLM调用
async function runAnotherExampleChat() {
console.log("\nStarting another LLM call...");
const response = await llm.call([
new HumanMessage("解释一下云计算的优势。"),
]);
console.log("LLM Response:", response.content);
console.log("\n--- Final Token Usage Summary ---");
console.log(`Total Prompt Tokens Across All Runs: ${totalPromptTokens}`);
console.log(`Total Completion Tokens Across All Runs: ${totalCompletionTokens}`);
console.log(`Total Execution Tokens Across All Runs: ${totalExecutionTokens}`);
}
// 可以在适当的时机调用 runAnotherExampleChat()
// setTimeout(() => runAnotherExampleChat().catch(console.error), 3000);