[langchian]使用langchain构建一个chatbot
https://python.langchain.com/docs/tutorials/chatbot/
很明显,到这一部分难度上来了。
pip install langchain-core langgraph
当我们调用大模型的时候,如果没有进行额外的操作,大模型是没有记忆状态的。在langchain中可以说两次llm.invoke()是独立的。
为了让大模型了解上下文,我们需要把对话的历史传递个大模型。
from langchain.chat_models import init_chat_model
from langchain_core.messages import HumanMessagefrom dotenv import load_dotenv
load_dotenv()model = init_chat_model("deepseek-chat")
result = model.invoke([HumanMessage(content="Hi! I'm Bob")])
print(result)result2 = model.invoke([HumanMessage(content="What's my name?")])
print(result2)result3 = 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(result3)
Message 持久化
persistence这词我还没记住
为了实现message persistence,引入了langgraph的概念,langgraph到底是什么我们后面再了解,这里先简单使用下。
from langchain.chat_models import init_chat_model
from langchain_core.messages import HumanMessage,AIMessagefrom langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import START, MessagesState, StateGraphfrom dotenv import load_dotenv
load_dotenv()model = init_chat_model("deepseek-chat")# Define a new graph
workflow = StateGraph(state_schema=MessagesState)# Define the function that calls the model
def call_model(state: MessagesState):response = model.invoke(state["messages"])return {"messages": response}# Define the (single) node in the graph
workflow.add_edge(START, "model")
workflow.add_node("model", call_model)# Add memory
memory = MemorySaver()
app = workflow.compile(checkpointer=memory)config = {"configurable": {"thread_id": "abc123"}}query = "Hi! I'm Bob."input_messages = [HumanMessage(query)]
output = app.invoke({"messages": input_messages}, config)
output["messages"][-1].pretty_print() # output contains all messages in statequery = "What's my name?"input_messages = [HumanMessage(query)]
output = app.invoke({"messages": input_messages}, config)
output["messages"][-1].pretty_print()
Managing Conversation History
One important concept to understand when building chatbots is how to manage conversation history. If left unmanaged, the list of messages will grow unbounded and potentially overflow the context window of the LLM. Therefore, it is important to add a step that limits the size of the messages you are passing in.
from langchain_core.messages import trim_messages
对messages进行裁剪。
由于大多数语言模型对输入的 token 数量有限制,当对话历史过长时,需要进行裁剪(trim)以避免超出限制。采取合适的trim_messages 策略就是用来适当地裁剪消息,保留最关键的信息,同时移除不必要或较旧的内容。
看到这里我才发现,即使是一个看起来很小的功能,就是消息裁剪的功能,里面的细节也是多了去了。
比如用户说,请帮我记住我的地址是上海,那么当发生裁剪时,这条消息是最不应该被裁剪的。这就是一条user case,如何实现这个user case呢?
首先messages要入库,至于这个库是内存还是数据库不重要,重要的是messages要先存起来,然后再来说我们要怎么处理它。
全栈工程师的涌现,之前也有全栈工程师,但是数量极其有限,自从大模型出来之后,全栈变得容易了。