LangChain实战课AI练中学遇到的问题及其解决办法 | 豆包MarsCode AI刷题

126 阅读4分钟

位置1

08_链上_03_Running_Chain.py

屏幕截图 2024-11-18 214648.png

问题1

File "/home/cloudide/.local/lib/python3.12/site-packages/langchain_openai/chat_models/base.py", line 564, in _combine_llm_outputs
    overall_token_usage[k] += v
TypeError: unsupported operand type(s) for +=: 'NoneType' and 'NoneType'

分析1

在给定的错误代码中,可以发现错误出现在overall_token_usage 字典中的键值对可能包含了 None 类型的数据。当尝试对 None 类型的数据进行加法操作时,Python 会抛出 TypeError 错误。

可以在编辑器中打开直接跳转到出现问题的代码上,非常的方便

"/home/cloudide/.local/lib/python3.12/site-packages/langchain_openai/chat_models/base.py", line 564

错误代码

        if token_usage is not None:
                for k, v in token_usage.items():
                    if k in overall_token_usage:
                        overall_token_usage[k] += v
                    else:
                        overall_token_usage[k] = v

解决办法1

  1. 检查类型:使用 isinstance(value, (int, float)) 检查字典中的值是否为整数或浮动点数类型。
  2. 处理非数字类型:如果值不是数字类型,我们将其设置为 0(或其他你选择的默认值)。
  3. 进行加法操作:对于数值类型的值,继续执行加法操作。

这样就能确保在执行加法之前,字典中的所有值都是有效的数字类型,从而避免因 None 类型的数据或其他非数字类型导致的错误。

正确代码

            if token_usage is not None:
                for k, v in token_usage.items():
                    if k in overall_token_usage:
                        # 确保 v 是数字类型,如果不是则忽略
                        if isinstance(v, (int, float)):
                            overall_token_usage[k] += v
                    else:
                        # 如果 k 不存在于 overall_token_usage 中,且 v 是数字类型,则初始化 k 的值为 v
                        if isinstance(v, (int, float)):
                            overall_token_usage[k] = v

输出

屏幕截图 2024-11-18 222618.png

解决了该问题之后,无论是链上还是链下的程序都可以正常运行了。

位置2

10_链上_04_ConversationSummaryMemory.py

屏幕截图 2024-11-18 232906.png

问题2

File "/home/cloudide/.local/lib/python3.12/site-packages/langchain_openai/chat_models/base.py", line 906, in get_num_tokens_from_messages
    raise NotImplementedError(
NotImplementedError: get_num_tokens_from_messages() is not presently implemented for model cl100k_base.

分析2

根据报错所给出的提示,不难发现,NotImplementedError 异常表示该方法在特定模型(这里是 cl100k_base)上没有实现。也就是说,OpenAI 在为 cl100k_base 模型提供 API 时,还没有实现用于计算 tokens 的功能。

屏幕截图 2024-11-18 224642.png

"/home/cloudide/.local/lib/python3.12/site-packages/langchain_openai/chat_models/base.py", line 906

解决办法2

根据分析可得,我们需要定义一个子类ChildChatOpenAI 类重写 get_num_tokens_from_messages 方法。这个方法通常用于计算给定消息列表的token数量,这对于确定模型能够处理的输入大小很重要。

正确代码

# 设置OpenAI API密钥
import os

# 导入所需的库
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.chains.conversation.memory import ConversationSummaryBufferMemory

from typing import List
from langchain_core.messages import BaseMessage
from langchain_openai.chat_models.base import BaseChatOpenAI

class ChildChatOpenAI(ChatOpenAI):
    def get_num_tokens_from_messages(self, messages: List[BaseMessage]) -> int:
        # 获取模型类型
        model, encoding = self._get_encoding_model()
        # 根据模型类型选择不同的 token 计算逻辑
        if model.startswith("cl100k_base"):
            # 调用父类的函数
            return super(BaseChatOpenAI, self).get_num_tokens_from_messages(messages)
        else:
            return super().get_num_tokens_from_messages(messages)


llm = ChildChatOpenAI(
    temperature=0.5,
    model=os.environ.get("LLM_MODELEND"),
)

# 初始化对话链
conversation = ConversationChain(
    llm=llm, memory=ConversationSummaryBufferMemory(llm=llm, max_token_limit=300)
)

# 第一天的对话
# 回合1
result = conversation("我姐姐明天要过生日,我需要一束生日花束。")
print(result)
# 回合2
result = conversation("她喜欢粉色玫瑰,颜色是粉色的。")
# print("\n第二次对话后的记忆:\n", conversation.memory.buffer)
print(result)

# 第二天的对话
# 回合3
result = conversation("我又来了,还记得我昨天为什么要来买花吗?")
print(result)

输出

同样的问题,同样的解决办法,10_05的程序也可以正常运行了。

屏幕截图 2024-11-18 231846.png

总结

通过使用AI可以检查出代码中存在的问题,很方便,可以提醒我们想不到的地方,总体而言,使用 AI 技术检查代码错误并修正,可以给我们带来的是一种高效、便捷、并且能持续学习的体验。它减少了错误的出现,提升了代码质量。AI 尤其对于新手开发者或繁琐的调试过程来说,提供了巨大的帮助。但是AI不是全面的,也有解决不到的问题,所以,我也通过向其他作者的文章学习,帮助我解决了代码上面的错误。