0

0

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

DDD

DDD

发布时间:2025-11-24 17:36:06

|

399人浏览过

|

来源于php中文网

原创

langchain.js中追踪openai模型token用量与成本的实现指南

本教程详细介绍了如何在LangChain.js项目中准确追踪OpenAI模型(如GPT-3.5-turbo)的Token用量和运行成本。针对LangChain.py中`get_openai_callback()`在JavaScript框架中缺失的问题,我们将重点讲解如何利用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用量:

云从科技AI开放平台
云从科技AI开放平台

云从AI开放平台

下载
import { ChatOpenAI } from 'langchain/chat_models/openai';
import { HumanMessage } from 'langchain/schema'; // 用于构造Chat模型输入

// 定义全局变量用于累计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();

代码解析

  1. 全局变量: totalCompletionTokens, totalPromptTokens, totalExecutionTokens 用于在多次LLM调用之间累计Token用量。在实际应用中,这些变量可能需要与特定的用户会话或请求上下文绑定。
  2. ChatOpenAI初始化: 在创建ChatOpenAI实例时,传入一个callbacks数组。数组中的每个元素都是一个回调对象。
  3. handleLLMEnd方法: 这是关键所在。当LLM完成一次响应后,handleLLMEnd会被调用。
    • output参数包含了LLM调用的结果,其中output.llmOutput?.tokenUsage对象存储了本次调用的completionTokens(完成Token)、promptTokens(提示词Token)和totalTokens(总Token)。
    • 我们通过解构赋值获取这些值,并使用空值合并运算符?? 0确保在tokenUsage不存在时默认为0,提高代码健壮性。
    • 将获取到的Token用量累加到全局变量中。
  4. modelName: 'gpt-3.5-turbo-0613': 原始问题提到,在特定版本(如0.0.116)的LangChain.js中,使用ChatOpenAI和gpt-3.5-turbo-0613模型能够更可靠地返回Token用量。对于其他模型或LLM类型,可能需要进行测试验证。
  5. 成本估算: 示例中包含了基于OpenAI官方定价的简单成本估算逻辑。请务必参考OpenAI最新的定价信息。

注意事项与最佳实践

  1. 模型与版本兼容性:

    • ChatOpenAI与特定模型: 原始问题中提到,在LangChain.js的0.0.116版本中,使用ChatOpenAI结合modelName: 'gpt-3.5-turbo-0613'可以稳定地获取Token用量。对于其他模型或LLM类型(如OpenAI而非ChatOpenAI),或不同版本的LangChain.js,Token用量报告的准确性可能会有所不同,甚至可能无法获取。建议开发者在实际项目中进行测试验证。
    • 框架更新: LangChain.js是一个快速迭代的框架,API可能会发生变化。务必查阅最新官方文档,以确保回调机制和Token用量报告的兼容性。
  2. 集成到复杂链中:

    • 即使您使用的是ConversationalRetrievalQAChain、BufferMemory和向量搜索等复杂组件,只要最终调用的底层LLM实例(例如ChatOpenAI)配置了callbacks,handleLLMEnd函数就能够捕获到每次LLM交互的Token用量。这是因为这些高级链的执行流程中,仍然会触发其内部LLM实例的调用。
  3. 成本估算:

    • 获取Token用量是进行成本估算的基础。您可以根据OpenAI官方公布的定价模型(通常按每千个输入/输出Token计费)来计算每次LLM调用或整个会话的预估成本。
    • 示例成本计算公式:总成本 = (累计提示词Token / 1000) * 提示词单价 + (累计完成Token / 1000) * 完成单价 请注意,OpenAI的定价会根据模型版本和类型有所不同,务必参考最新的官方价格表。
  4. 数据持久化与监控:

    • 在生产环境中,简单地使用全局变量累计Token可能不足。您可能需要将这些数据发送到日志系统、监控平台或数据库中,以便进行长期分析、生成报告和设置成本预警。
  5. 健壮性与错误处理:

    • 在handleLLMEnd回调函数中,始终对output.llmOutput?.tokenUsage进行空值或未定义检查(例如使用?.操作符和|| {}默认值),以防止因某些特殊情况(如LLM调用失败或响应格式不一致)导致程序崩溃。

总结

通过利用LangChain.js提供的回调机制,特别是handleLLMEnd函数,开发者可以有效地追踪OpenAI模型在每次运行中的Token用量。这种方法不仅解决了LangChain.py中get_openai_callback()在JavaScript框架中缺失的问题,还提供了一个灵活且强大的方式来监控和管理LLM应用的资源消耗。掌握这一技术,对于构建成本效益高、可观测性强的LLM应用至关重要。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1567

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

241

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

150

2025.10.17

登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

6629

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

843

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

1092

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

2190

2024.03.01

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

95

2025.09.18

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

1

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 6万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 3.4万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号