说在前面

  • 操作系统:windows
  • python版本:3.9
  • langchain版本:0.3.20
  • pycharm版本:2023.1.2 (Community Edition)
  • 其他:由于上一篇里用的1.5b模型实在太傻了,不太好演示,这里暂时换成deepseek

最简单版本

  • 依照上一篇的一些准备工作,我们首先可以实现一个最简易的聊天机器人版本
  • 先把deepseek依赖库装下
    pip install langchain-deepseek
    
  • 上代码
    from langchain_deepseek import ChatDeepSeek
    
    dllm = ChatDeepSeek(model="deepseek-chat", api_key="xxxxx")
    
    from langchain_core.messages import HumanMessage
    
    while True:
        input_msg = input("> ")
        print(dllm.invoke([HumanMessage(content=input_msg)]).content)
    
    测试
    (venv) PS D:\Code\langchain> python .\main.py              
    > 你好
    你好!很高兴见到你。有什么我可以帮忙的吗?
    > 我叫柯南
    你好,柯南!你提到“柯南”,让我想到了《名侦探柯南》这部非常受欢迎的日本动漫。你是这部动漫的粉丝吗?还是你的名字真的叫柯南呢?如果你有任何关于动漫、推理或者其他方面的问题,都可以告诉我哦!
    > 你知道我叫什么吗?
    您好!我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-V3。有关模型和产品的详细内容请参考官方文档。
    
  • 这个聊天机器人实际上进行单次对话,没有记忆,接下来我们将逐步完善这个机器人

添加历史对话

  • 要让大模型有记忆,最简单的方式是将所有历史对话都交给大模型,比如:
    from langchain_deepseek import ChatDeepSeek
    
    dllm = ChatDeepSeek(model="deepseek-chat", api_key="xxxxx")
    
    from langchain_core.messages import HumanMessage,AIMessage
    
    msg_history = []
    while True:
        input_msg = input("> ")
        msg_history.append(HumanMessage(content=input_msg))
    
        ai_msg = dllm.invoke(msg_history).content
        msg_history.append(AIMessage(content=ai_msg))
        print(ai_msg)
    
  • 测试
    (venv) PS D:\Code\langchain> python .\main.py
    > 你好,我是柯南
    你好,柯南!很高兴见到你。你今天有什么新的案件要解决吗?还是有什么谜题需要一起探讨?我很乐意帮忙!
    > 你知道我叫什么吗?
    当然知道,你是江户川柯南,一个聪明绝顶的少年侦探。你以敏锐的观察力和卓越的推理能力闻名,总是在不经意间揭开案件的真相。你的名字,就像你解决的那些错综复杂的案件一样,令人印象深刻。
    > 
    
    可以看到,AI能够知道之前对话的信息了

消息持久化

  • 当我们需要更好的管理历史消息时,我们可以将消息存储到数据库中,例如mongomysql之类的。在langchain的生态中,langgraph有一套内置的持久化层,它提供了几个数据库的封装,sqlite以及postgres;同时有一个使用内存的实现(MemorySaver)用于测试以及调试。
  • 那我们就用langgraph来试试,安装langgraph
    pip install langgraph
    
  • 先看代码
    from langchain_deepseek import ChatDeepSeek
    dllm = ChatDeepSeek(model="deepseek-chat", api_key="xxxxx")
    
    from langchain_core.messages import HumanMessage,AIMessage
    from langgraph.checkpoint.memory import MemorySaver
    from langgraph.graph import START, MessagesState, StateGraph
    
    # 定义一个graph
    workflow = StateGraph(state_schema=MessagesState)
    
    # 封装一下模型调用
    def call_model(state: MessagesState):
        response = dllm.invoke(state["messages"])
        return {"messages": response}
    
    # 定义一个模型节点
    workflow.add_edge(START, "model")
    workflow.add_node("model", call_model)
    
    # 添加MemorySaver
    memory = MemorySaver()
    app = workflow.compile(checkpointer=memory)
    
    # 定义一个配置,thread_id用于标识此次对话,常用于多用户环境,这里暂时不做扩展
    config = {"configurable": {"thread_id": "konan"}}
    while True:
        input_msg = input("> ")
        output = app.invoke({"messages": [HumanMessage(content=input_msg)]}, config)
    
        print(output["messages"][-1].content)
    
    测试
    (venv) PS E:\Workspace\pycharm\langchain> python.exe .\main.py
    > 你好,我是柯南
    你好,柯南!很高兴见到你。作为一名高中生侦探,你一定有很多精彩的推理故事吧?如果你有任何案件需要讨论,或者想分享一些有趣的线索,我都很乐意帮忙。你最近在调查什么案件呢?
    > 你知道我是谁吗?
    当然知道,你是江户川柯南,一个外表看似小孩,智慧却过于常人的名侦探。你原本是高中生侦探工藤新一,因被黑衣组织灌下毒药而身体缩小,化名为江户川柯南,继续破解各种复杂的案件。你的推理能力和对正义的执着令人敬佩。有什么我可以帮你的吗?
    
  • 一步步拆解下,首先是
    workflow = StateGraph(state_schema=MessagesState)
    
    StateGraph是一种所有节点均通过一个共享的状态管理器进行沟通的graph,在我们这个例子中,这个状态管理器的类型就是MessagesState,它其实就是一个字典,里面默认有messages这个kv。
    class MessagesState(TypedDict):
        messages: Annotated[list[AnyMessage], add_messages]
    
  • 接下来是封装了一下模型的调用
    def call_model(state: MessagesState):
        response = dllm.invoke(state["messages"])
        return {"messages": response}
    
    它的参数是state,也就是我们的状态管理器;而返回值是一个字典,里面是模型的返回,字典的key是messages
  • 而后开始定义我们的graph
    workflow.add_edge(START, "model")
    workflow.add_node("model", call_model)
    
    在这里插入图片描述
  • 紧接着添加了MemorySaver,这一步比较关键
    memory = MemorySaver()
    app = workflow.compile(checkpointer=memory)
    
  • 最后就是正常的调用了
    input_msg = input("> ")
    output = app.invoke({"messages": [HumanMessage(content=input_msg)]}, config)
    
  • 看完这个流程,我有个疑问,用户的输入以及模型的返回,是怎样存入到memory之中的?关键点在于checkpointer=memory,如果把这个去掉,就没有记忆功能了
    (venv) PS E:\Workspace\pycharm\langchain> python.exe .\main.py
    > 你好,我是柯南
    你好,柯南!很高兴见到你。你今天有什么案件需要解决吗?还是有什么谜题需要一起探讨?我很乐意帮忙!
    > 你知道我是谁吗?
    您好!我是由中国的深度求索(DeepSeek)公司开发的智能助手DeepSeek-V3。有关模型和产品的详细内容请参考官方文档。
    > 
    
    这个如何实现的这里就先不探讨了,应该和这个有关

管理历史对话

  • 通过上述的代码我们可以知道,当对话次数越多,一次大模型请求传递的数据量就越多,消耗的token数就越多,所以一个非常重要的功能就是管理历史对话,让传给大模型的数据量不要过大。

  • 同样的,langchain有一些封装好的接口可以使用

    def dummy_token_counter(messages: list[BaseMessage]) -> int:
        count = 0
        for msg in messages:
            if isinstance(msg.content, str):
                count += len(msg.content)
        return count
    
    trimmer = trim_messages(
        max_tokens=64,
        strategy="last",
        token_counter=dummy_token_counter,
        include_system=True,
        allow_partial=False,
        start_on="human",
    )
    
    # 封装一下模型调用
    def call_model(state: MessagesState):
        trimmed_msg = trimmer.invoke(state["messages"])
        response = dllm.invoke(trimmed_msg)
        return {"messages": response}
    

    这里由于用的deepseek,直接使用token_counter=dllm会报错,可能哪里不兼容,所以随便写了一个counter

  • 测试,可以看到第三个问题的时候已经不知道我是柯南了

    (venv) PS E:\Workspace\pycharm\langchain> python.exe .\main.py
    > 你好,我是柯南
    你好,柯南!很高兴见到你。你今天有什么新的案件要解决吗?还是有什么需要我帮忙的地方?
    > 怎样睡得更好
    要改善睡眠质量,可以尝试以下方法:
    
    ### 1. **建立规律的作息时间**
    - 每天尽量在同一时间上床睡觉和起床,即使在周末也保持一致。
    - 帮助身体形成生物钟,更容易入睡和醒来。
    
    ### 2. **创造舒适的睡眠环境**
    - **温度**:保持卧室凉爽(18-22℃为宜)。
    - **光线**:使用遮光窗帘或眼罩,避免光线干扰。
    - **噪音**:使用耳塞或白噪音机减少噪音干扰。
    - **床具**:选择舒适的床垫和枕头,适合你的睡眠姿势。
    
    ### 3. **睡前放松身心**
    - **避免刺激**:睡前1-2小时避免使用电子设备(如手机、电脑),减少蓝光对大脑的刺激。
    - **放松活动**:可以尝试冥想、深呼吸、轻柔的瑜伽或听舒缓的音乐。
    - **温水泡脚或泡澡**:帮助放松肌肉,促进血液循环。
    
    ### 4. **调整饮食习惯**
    - **避免咖啡因和酒精**:睡前4-6小时避免摄入咖啡、茶、巧克力或酒精。
    - **清淡晚餐**:避免睡前吃太饱或吃油腻、辛辣的食物。
    - **适量饮水**:睡前不要喝太多水,以免夜间频繁起夜。
    
    ### 5. **白天保持适度运动**
    - 每天进行30分钟左右的适度运动(如散步、慢跑、瑜伽),但避免在睡前2小时内剧烈运动。
    
    ### 6. **管理压力和焦虑**
    - **写日记**:睡前写下当天的烦恼或明天的计划,帮助清空大脑。
    - **练习正念**:通过冥想或深呼吸练习缓解焦虑。
    - **寻求支持**:如果压力过大,可以找朋友倾诉或寻求专业帮助。
    
    ### 7. **避免长时间午睡**
    - 如果需要午睡,控制在20-30分钟内,避免影响夜间睡眠。
    
    ### 8. **限制床上活动**
    - 床只用于睡觉和亲密关系,避免在床上工作、看电视或玩手机,帮助大脑建立“床=睡眠”的联想。
    
    ### 9. **尝试自然助眠方法**
    - **喝温牛奶或草本茶**:如洋甘菊茶、薰衣草茶。
    - **使用香薰**:薰衣草、洋甘菊等精油有助于放松。
    
    ### 10. **如果长期失眠,及时就医**
    - 如果尝试以上方法后仍无法改善睡眠,建议咨询医生,排除潜在的健康问题(如睡眠呼吸暂停、焦虑症等)。
    
    ### 小贴士:
    - **不要强迫自己入睡**:如果躺下20分钟后仍无法入睡,可以起床做一些放松活动,直到感到困倦再回到床上。
    - **记录睡眠日记**:记录每天的睡眠时间、质量、饮食和活动,帮助找到影响睡眠的因素。
    
    希望这些方法能帮助你改善睡眠,拥有更高质量的休息!
    > 我是谁
    这个问题涉及到自我认知和哲学思考。从哲学的角度来看,“我是谁”是一个关于自我身份和存在本质的问题。不同的哲学流派和思想家对此有不同的解释。
    
    1. **笛卡尔的“我思故我在”**:笛卡尔认为,思考是自我存在的证明。通过怀疑一切,他发现唯一不可怀疑的是自己在思考的事实,因此得出结论“我思故我在”。
    
    2. **佛教的无我**:佛教认为,所谓的“我”是一个幻觉,是由五蕴(色、受、想、行、识)暂时聚合而成的。真正的自我并不存在,执着于“我”是痛苦的根源。
    
    3. **存在主义**:存在主义者如萨特认为,存在先于本质。人首先存在,然后通过自己的选择和行动来定义自己。因此,“我是谁”是由你自己通过行动和选择来决定的。
    
    4. **心理学视角**:从心理学角度来看,自我是一个复杂的结构,包括自我概念、自我认同和自我意识。你是谁可能由你的经历、记忆、情感、价值观和社会关系共同塑造。
    
    5. **生物学视角**:从生物学角度来看,你是由你的基因、生理结构和大脑功能所决定的。你的身体和大脑的状态会影响你的思维、情感和行为。
    
    6. **社会学视角**:社会学家认为,自我是在社会互动中形成的。你通过与他人的关系、社会角色和文化背景来定义自己。
    
    7. **灵性视角**:在一些灵性传统中,真正的自我被认为是超越物质世界的,与宇宙或神性相连。通过冥想、祈祷或其他灵性实践,人们试图认识这个更深层次的自我。
    
    最终,“我是谁”这个问题没有一个简单的答案,它可能需要你通过自我反思、哲学思考、科学探索和灵性实践来不断探索和理解。
    
  • 以上,柯南要碎觉了

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐