百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

【AI大模型框架—Langchain】构建简单的LLM的聊天机器人

ccwgpt 2024-11-20 13:15 45 浏览 0 评论

在本文中,我们将带你一步步设计并实现一个基于大语言模型(LLM)的聊天机器人。这个机器人不仅可以与用户进行对话,还能够记住之前的互动记录。

先决条件

在开始之前,建议你熟悉以下概念:

  • 聊天模型(Chat Models)
  • 提示模板(Prompt Templates)
  • 聊天记录(Chat History)

概述

我们将通过一个示例来展示如何设计和实现一个LLM驱动的聊天机器人。需要注意的是,这个机器人只使用语言模型进行对话。你可能还需要了解以下相关概念:

  • Conversational RAG:在外部数据源上启用聊天机器人体验
  • Agents:构建可以执行操作的聊天机器人

本教程将介绍一些基础知识,这些知识对上述更高级的主题也会有所帮助。

环境搭建

安装 LangChain

要安装LangChain,请运行以下命令:

pip install langchain

有关更多详细信息,请参阅我们的安装指南。

快速入门

使用语言模型

LangChain支持许多不同的语言模型,你可以根据需要选择使用。这里以OpenAI的gpt-4o-mini为例:

pip install -qU langchain-openai

from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv())
from langchain_openai import ChatOpenAI

model = ChatOpenAI(model="gpt-4o-mini").bind(logprobs=True)

直接使用模型与之交互:

from langchain_core.messages import HumanMessage

response = model.invoke([HumanMessage(content="Hi! I'm Bob")])
print(response)

响应的结果:

content='Hi Bob! How can I assist you today?' response_metadata={'token_usage': {'completion_tokens': 10, 'prompt_tokens': 11, 'total_tokens': 21}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_ba606877f9', 'finish_reason': 'stop', 'logprobs': {'content': [{'token': 'Hi', 'bytes': [72, 105], 'logprob': -0.023249088, 'top_logprobs': []}, {'token': ' Bob', 'bytes': [32, 66, 111, 98], 'logprob': -0.01416727, 'top_logprobs': []}, {'token': '!', 'bytes': [33], 'logprob': 0.0, 'top_logprobs': []}, {'token': ' How', 'bytes': [32, 72, 111, 119], 'logprob': -0.00035596156, 'top_logprobs': []}, {'token': ' can', 'bytes': [32, 99, 97, 110], 'logprob': -0.00011450992, 'top_logprobs': []}, {'token': ' I', 'bytes': [32, 73], 'logprob': 0.0, 'top_logprobs': []}, {'token': ' assist', 'bytes': [32, 97, 115, 115, 105, 115, 116], 'logprob': -0.03804183, 'top_logprobs': []}, {'token': ' you', 'bytes': [32, 121, 111, 117], 'logprob': 0.0, 'top_logprobs': []}, {'token': ' today', 'bytes': [32, 116, 111, 100, 97, 121], 'logprob': 0.0, 'top_logprobs': []}, {'token': '?', 'bytes': [63], 'logprob': 0.0, 'top_logprobs': []}]}} id='run-c623dce5-1b6a-45ee-ad27-84ddbee0ebad-0' usage_metadata={'input_tokens': 11, 'output_tokens': 10, 'total_tokens': 21}

如果问后续问题,模型默认没有状态概念:

response = model.invoke([HumanMessage(content="What's my name?")])
print(response)

响应结果:

content="I'm sorry, but I don't have access to personal information about users unless it has been shared in the conversation. If you'd like, you can tell me your name!" response_metadata={'token_usage': {'completion_tokens': 33, 'prompt_tokens': 11, 'total_tokens': 44}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_ba606877f9', 'finish_reason': 'stop', 'logprobs': {'content': [{'token': "I'm", 'bytes': [73, 39, 109], 'logprob': -0.47415686, 'top_logprobs': []}, {'token': ' sorry', 'bytes': [32, 115, 111, 114, 114, 121], 'logprob': -0.0006115251, 'top_logprobs': []}, {'token': ',', 'bytes': [44], 'logprob': -4.3202e-07, 'top_logprobs': []}, {'token': ' but', 'bytes': [32, 98, 117, 116], 'logprob': -0.00012356207, 'top_logprobs': []}, {'token': ' I', 'bytes': [32, 73], 'logprob': -7.703444e-06, 'top_logprobs': []}, {'token': " don't", 'bytes': [32, 100, 111, 110, 39, 116], 'logprob': -0.019258404, 'top_logprobs': []}, {'token': ' have', 'bytes': [32, 104, 97, 118, 101], 'logprob': -0.47407743, 'top_logprobs': []}, {'token': ' access', 'bytes': [32, 97, 99, 99, 101, 115, 115], 'logprob': -0.017442156, 'top_logprobs': []}, {'token': ' to', 'bytes': [32, 116, 111], 'logprob': 0.0, 'top_logprobs': []}, {'token': ' personal', 'bytes': [32, 112, 101, 114, 115, 111, 110, 97, 108], 'logprob': -0.047323395, 'top_logprobs': []}, {'token': ' information', 'bytes': [32, 105, 110, 102, 111, 114, 109, 97, 116, 105, 111, 110], 'logprob': -0.20144111, 'top_logprobs': []}, {'token': ' about', 'bytes': [32, 97, 98, 111, 117, 116], 'logprob': -0.19552712, 'top_logprobs': []}, {'token': ' users', 'bytes': [32, 117, 115, 101, 114, 115], 'logprob': -0.9391852, 'top_logprobs': []}, {'token': ' unless', 'bytes': [32, 117, 110, 108, 101, 115, 115], 'logprob': -0.1827523, 'top_logprobs': []}, {'token': ' it', 'bytes': [32, 105, 116], 'logprob': -1.0404304, 'top_logprobs': []}, {'token': ' has', 'bytes': [32, 104, 97, 115], 'logprob': -0.0007059985, 'top_logprobs': []}, {'token': ' been', 'bytes': [32, 98, 101, 101, 110], 'logprob': -5.5577775e-06, 'top_logprobs': []}, {'token': ' shared', 'bytes': [32, 115, 104, 97, 114, 101, 100], 'logprob': -0.007847821, 'top_logprobs': []}, {'token': ' in', 'bytes': [32, 105, 110], 'logprob': -1.5318099, 'top_logprobs': []}, {'token': ' the', 'bytes': [32, 116, 104, 101], 'logprob': -0.15039976, 'top_logprobs': []}, {'token': ' conversation', 'bytes': [32, 99, 111, 110, 118, 101, 114, 115, 97, 116, 105, 111, 110], 'logprob': -1.3203849, 'top_logprobs': []}, {'token': '.', 'bytes': [46], 'logprob': -2.2961513e-05, 'top_logprobs': []}, {'token': ' If', 'bytes': [32, 73, 102], 'logprob': -0.82898766, 'top_logprobs': []}, {'token': " you'd", 'bytes': [32, 121, 111, 117, 39, 100], 'logprob': -0.252001, 'top_logprobs': []}, {'token': ' like', 'bytes': [32, 108, 105, 107, 101], 'logprob': -1.504853e-06, 'top_logprobs': []}, {'token': ',', 'bytes': [44], 'logprob': -1.0768048, 'top_logprobs': []}, {'token': ' you', 'bytes': [32, 121, 111, 117], 'logprob': -0.014669579, 'top_logprobs': []}, {'token': ' can', 'bytes': [32, 99, 97, 110], 'logprob': -0.00018411019, 'top_logprobs': []}, {'token': ' tell', 'bytes': [32, 116, 101, 108, 108], 'logprob': -0.00955621, 'top_logprobs': []}, {'token': ' me', 'bytes': [32, 109, 101], 'logprob': 0.0, 'top_logprobs': []}, {'token': ' your', 'bytes': [32, 121, 111, 117, 114], 'logprob': -5.5122365e-07, 'top_logprobs': []}, {'token': ' name', 'bytes': [32, 110, 97, 109, 101], 'logprob': 0.0, 'top_logprobs': []}, {'token': '!', 'bytes': [33], 'logprob': -0.00811096, 'top_logprobs': []}]}} id='run-ec33c381-a4db-4bb9-9ccb-d1720a8214a6-0' usage_metadata={'input_tokens': 11, 'output_tokens': 33, 'total_tokens': 44}

模型无法回答,体验不佳。为解决这个问题,我们需要传递整个对话历史:

response = model.invoke(
    [
        HumanMessage(content="Hi! I'm Bob"),
        AIMessage(content="Hello Bob! How can I assist you today?"),
        HumanMessage(content="What's my name?"),
    ]
)

print(response)

此时响应的结果可以看出,LLM已经能够识别到我是谁了?

content='Your name is Bob! How can I help you today?' response_metadata={'token_usage': {'completion_tokens': 12, 'prompt_tokens': 33, 'total_tokens': 45}, 'model_name': 'gpt-4o-mini-2024-07-18', 'system_fingerprint': 'fp_ba606877f9', 'finish_reason': 'stop', 'logprobs': {'content': [{'token': 'Your', 'bytes': [89, 111, 117, 114], 'logprob': -0.003211819, 'top_logprobs': []}, {'token': ' name', 'bytes': [32, 110, 97, 109, 101], 'logprob': 0.0, 'top_logprobs': []}, {'token': ' is', 'bytes': [32, 105, 115], 'logprob': -4.3202e-07, 'top_logprobs': []}, {'token': ' Bob', 'bytes': [32, 66, 111, 98], 'logprob': 0.0, 'top_logprobs': []}, {'token': '!', 'bytes': [33], 'logprob': -0.25192946, 'top_logprobs': []}, {'token': ' How', 'bytes': [32, 72, 111, 119], 'logprob': -0.015417111, 'top_logprobs': []}, {'token': ' can', 'bytes': [32, 99, 97, 110], 'logprob': -0.00081379723, 'top_logprobs': []}, {'token': ' I', 'bytes': [32, 73], 'logprob': 0.0, 'top_logprobs': []}, {'token': ' help', 'bytes': [32, 104, 101, 108, 112], 'logprob': -0.023248974, 'top_logprobs': []}, {'token': ' you', 'bytes': [32, 121, 111, 117], 'logprob': 0.0, 'top_logprobs': []}, {'token': ' today', 'bytes': [32, 116, 111, 100, 97, 121], 'logprob': -0.01769961, 'top_logprobs': []}, {'token': '?', 'bytes': [63], 'logprob': -0.6931476, 'top_logprobs': []}]}} id='run-122d5e43-1c05-4bb2-a3cd-1507f7167f4d-0' usage_metadata={'input_tokens': 33, 'output_tokens': 12, 'total_tokens': 45}

管理对话历史

我们可以使用Message History类来记录对话,使模型具有状态。安装必要依赖:

pip install langchain_community

然后设置会话历史记录存储:

def get_session_history(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = InMemoryChatMessageHistory()
    return store[session_id]

with_message_history = RunnableWithMessageHistory(model, get_session_history)

config = {"configurable": {"session_id": "abc2"}}
response = with_message_history.invoke([HumanMessage(content="Hi! I'm Bob")], config=config)
print(response.content)

response = with_message_history.invoke([HumanMessage(content="What's my name?")], config=config)
print(response.content)

运行结果:

Hi Bob! How can I assist you today?
Your name is Bob! How can I help you today?

使用提示模板

提示模板帮助将用户输入转换为LLM可以处理的格式。首先,我们添加系统消息来定制指令:

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a helpful assistant. Answer all questions to the best of your ability."),
        MessagesPlaceholder(variable_name="messages"),
    ]
)

chain = prompt | model

response = chain.invoke({"messages": [HumanMessage(content="hi! I'm bob")]})
print(response.content)

响应结果为:

Hi Bob! How can I assist you today?

将其包装在Message History对象中:

# 包装在Message History对象
with_message_history = RunnableWithMessageHistory(chain, get_session_history)
config = {"configurable": {"session_id": "abc5"}}

response = with_message_history.invoke([HumanMessage(content="Hi! I'm Jim")], config=config)
print(response.content)

response = with_message_history.invoke([HumanMessage(content="What's my name?")], config=config)
print(response.content)
Hi Jim! How can I assist you today?
Your name is Jim! How can I help you today, Jim?

管理对话历史的大小

为了防止对话历史过长,我们可以使用LangChain的消息修剪功能:

from langchain_core.messages import trim_messages, AIMessage, BaseMessage, HumanMessage, SystemMessage

messages = [
    HumanMessage(content="hi! I'm bob"),
    SystemMessage(content="you're a good assistant"),
    AIMessage(content="hi!"),
    HumanMessage(content="I like vanilla ice cream"),
    AIMessage(content="nice"),
    HumanMessage(content="whats 2 + 2"),
    AIMessage(content="4"),
    HumanMessage(content="thanks"),
    AIMessage(content="no problem!"),
    HumanMessage(content="having fun?"),
    AIMessage(content="yes!"),
]
trimmer = trim_messages(
   # messages,
    max_tokens=65,
    strategy="last",
    token_counter=model,
    include_system=True,
    allow_partial=False,
    start_on="human",
)
print(trimmer)
response = trimmer.invoke(messages)
print(response)


在我们的链中使用修剪功能:

# 在langchain的链中使用
from operator import itemgetter
from langchain_core.runnables import RunnablePassthrough

chain = (
    RunnablePassthrough.assign(messages=itemgetter("messages") | trimmer)
    | prompt
    | model
)
response = chain.invoke(
    {
        "messages": messages + [HumanMessage(content="what's my name?")],
        "language": "English",
    }
)
print(response.content)

将其包装在Message History中:

# 包装在Message History
with_message_history = RunnableWithMessageHistory(
    chain,
    get_session_history,
    input_messages_key="messages",
)

config = {"configurable": {"session_id": "abc20"}}

response = with_message_history.invoke(
    {
        "messages": messages + [HumanMessage(content="whats my name?")],
        "language": "English",
    },
    config=config,
)
print(response.content)

流式响应

为了改善用户体验,我们可以使用流式响应:

config = {"configurable": {"session_id": "abc15"}}
for r in with_message_history.stream(
    {
        "messages": [HumanMessage(content="hi! I'm todd. tell me a joke")],
        "language": "English",
    },
    config=config,
):
 print(r.content, end="|")

通过本文的讲解,你应该能够构建一个简单但功能强大的LLM聊天机器人。随着对LangChain的深入了解,你可以不断扩展和优化你的机器人,实现更多复杂功能。

相关推荐

盲盒小程序背后的技术揭秘:如何打造个性化购物体验

在2025年的今天,盲盒小程序作为一种新兴的购物方式,正以其独特的魅力和个性化体验吸引着越来越多的消费者。这种将线上购物与盲盒概念相结合的应用,不仅为消费者带来了未知的惊喜,还通过一系列技术手段实现了...

小程序·云开发已支持单日亿级调用量,接口可用率高达99.99%

2019-10-1914:1210月19日,由腾讯云与微信小程序团队联合举办的“小程序·云开发”技术峰会在北京召开。会上,微信小程序团队相关负责人表示“小程序·云开发”系统架构已经支持每天亿级别的...

程序员副业开启模式:8个GitHub上可以赚钱的小程序

前言开源项目作者:JackonYang今天推荐的这个项目是「list-of-wechat-mini-program-list」,开源微信小程序列表的列表、有赚钱能力的小程序开源代码。这个项目分为两部分...

深度科普:盲盒小程序开发的底层逻辑

在当下的数字化浪潮中,盲盒小程序以其独特的趣味性和互动性,吸引着众多消费者的目光。无论是热衷于收集玩偶的年轻人,还是享受拆盒惊喜的上班族,都对盲盒小程序情有独钟。那么,这种备受欢迎的盲盒小程序,其开发...

微信小程序的制作步骤

SaaS小程序制作平台,作为数字化转型时代下的创新产物,不仅将易用性置于设计的核心位置,让非技术背景的用户也能轻松上手,快速制作出功能丰富、界面精美的小程序,更在性能和稳定性方面投入了大量精力,以确保...

携程开源--小程序构建工具,三分钟搞定

前言今天推荐的这个项目是「wean」,一个小程序构建打包工具。在wean之前,大量小程序工具使用webpack进行打包,各种loader、plugin导致整个开发链路变长。wean旨在解...

校园小程序的搭建以及营收模式校园外卖程序校园跑腿校园圈子系统

校园小程序的架构设计主要包括云端架构和本地架构两部分。云端架构方面,采用Serverless架构可以降低技术门槛,通过阿里云、腾讯云等平台提供的云服务,可以实现弹性扩容和快速部署。例如,使用云数据库、...

盲盒小程序开发揭秘:技术架构与实现原理全解析

在2025年的今天,盲盒小程序作为一种结合了线上购物与趣味性的创新应用,正受到越来越多用户的喜爱。其背后的技术架构与实现原理,对于想要了解或涉足这一领域的人来说,无疑充满了神秘与吸引力。本文将为大家科...

月活百万的小程序架构设计:流量暴增秘籍

从小程序到"大"程序的蜕变之路当你的小程序用户量从几千跃升至百万级别时,原有的架构就像一件不合身的衣服,处处紧绷。这个阶段最常遇到的噩梦就是服务器崩溃、接口超时、数据丢失。想象一下,在...

认知智能如何与产业结合?专家学者共探理论框架与落地实践

当前,以大模型为代表的生成式人工智能等前沿技术加速迭代,如何将认知智能与产业结合,成为摆在各行各业面前的一个问题。论坛现场。主办方供图7月4日,2024世界人工智能大会暨人工智能全球治理高级别会议在...

现代中医理论框架

...

认知行为(CBT)中的ABC情绪理论

情绪ABC理论是由美国心理学家阿尔伯特·艾利斯(AlbertEllis1913-2007)创建的理论,A表示诱发性事件(Activatingevent),B表示个体针对此诱发性事件产生的一些信...

说说卡伦霍妮的理论框架,对你调整性格和人际关系,价值很大

01自在今天我主要想说下霍妮的理论框架。主要说三本书,第一本是《我们时代的神经症人格》,第二本是《我们内心的冲突》,第三本是《神经症与人的成长》。根据我的经验,三本书价值巨大,但并不是每个人都能读进去...

供应链管理-理论框架

一个最佳价值的供应链,应该是一个具有敏捷性、适应性和联盟功能(3A)的供应链,其基本要素包括战略资源、物流管理、关系管理以及信息系统,目标是实现速度、质量、成本、柔性的竞争优势。篇幅有...

微信WeUI设计规范文件下载及使用方法

来人人都是产品经理【起点学院】,BAT实战派产品总监手把手系统带你学产品、学运营。WeUI是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信Web开发量身设计,可以令用户的使用感知...

取消回复欢迎 发表评论: