使用RunnableWithMessageHistory实现聊天记录

环境:openEuler、python 3.11.6、Azure openAi、langchain  0.3.3

背景:开发项目使用langchain框架,需要实现聊天记录记忆功能

时间:20241021

说明:官文已说,推荐langgraph,但此类依然长期使用

官方文档原文:

As of the v0.3 release of LangChain, we recommend that LangChain users take advantage of LangGraph persistence to incorporate memory into new LangChain applications.
If your code is already relying on RunnableWithMessageHistory or BaseChatMessageHistory, you do not need to make any changes. We do not plan on deprecating this functionality in the near future as it works for simple chat applications and any code that uses RunnableWithMessageHistory will continue to work as expected.

译文:
自 LangChain v0.3 版本开始,我们建议 LangChain 用户利用 LangGraph 的持久化功能将内存纳入新的 LangChain 应用程序中。
如果您现有的代码已经依赖于 `RunnableWithMessageHistory` 或 `BaseChatMessageHistory`,则无需进行任何更改。我们不打算在近期废弃这一功能,因为它适用于简单的聊天应用程序,任何使用 `RunnableWithMessageHistory` 的代码将继续按预期工作。

官方文档地址:RunnableWithMessageHistory — 🦜🔗 LangChain documentation

源码地址:尚无

1、环境搭建

# 因为openEuler默认是python 3.11.6,而我使用的默认python版本,这样使用没有问题,如果未使用默认版本python,请自己再研究
yum -y install g++ python3-dev


创建虚拟环境,并安装相关的包:

python3 -m venv venv             # 创建虚拟环境
 
source venv/bin/activate         # 激活虚拟环境
 
pip install -r requirements.txt  # 批量安装我提供的包    


模块的版本信息文件

aiohappyeyeballs==2.4.3
aiohttp==3.10.10
aiosignal==1.3.1
annotated-types==0.7.0
anyio==4.6.2.post1
attrs==24.2.0
certifi==2024.8.30
charset-normalizer==3.4.0
distro==1.9.0
frozenlist==1.4.1
greenlet==3.1.1
h11==0.14.0
httpcore==1.0.6
httpx==0.27.2
idna==3.10
jiter==0.6.1
jsonpatch==1.33
jsonpointer==3.0.0
langchain==0.3.4
langchain-core==0.3.12
langchain-openai==0.2.3
langchain-text-splitters==0.3.0
langsmith==0.1.136
multidict==6.1.0
numpy==1.26.4
openai==1.52.0
orjson==3.10.9
packaging==24.1
propcache==0.2.0
pydantic==2.9.2
pydantic_core==2.23.4
python-dotenv==1.0.1
PyYAML==6.0.2
regex==2024.9.11
requests==2.32.3
requests-toolbelt==1.0.0
sniffio==1.3.1
SQLAlchemy==2.0.36
tenacity==9.0.0
tiktoken==0.8.0
tqdm==4.66.5
typing_extensions==4.12.2
urllib3==2.2.3
yarl==1.15.5

2、案例展示

将记录添加到内存中

from typing import List
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.messages import BaseMessage, AIMessage
from pydantic import BaseModel, Field


# 清空或添加消息在store中
class InMemoryHistory(BaseChatMessageHistory, BaseModel):
    """In memory implementation of chat message history."""

    messages: List[BaseMessage] = Field(default_factory=list)

    def add_messages(self, messages: List[BaseMessage]) -> None:
        """Add a list of messages to the store"""
        self.messages.extend(messages)

    def clear(self) -> None:
        self.messages = []

# 定义存储聊天记录的全局变量
store = {}

# 通过id获取聊天记录
def get_by_session_id(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = InMemoryHistory()
    return store[session_id]

history = get_by_session_id("1")
history.add_message(AIMessage(content="hello"))
print(store)  # noqa: T201

实现效果:

(langvenv) [root@Laptop-latitude-7300 langchain_test]# python test/test.py 
{'1': InMemoryHistory(messages=[AIMessage(content='hello', additional_kwargs={}, response_metadata={})])}

显然,已将聊天的问题添加到store中

聊天记录存储,可自定义添加参数

from operator import itemgetter
from typing import List, Optional

from langchain_openai import AzureChatOpenAI

from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.documents import Document
from langchain_core.messages import BaseMessage, AIMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from pydantic import BaseModel, Field
from langchain_core.runnables import (
    RunnableLambda,
    ConfigurableFieldSpec,
    RunnablePassthrough,
)
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from dotenv import load_dotenv

# 将模型的相关数据加载到本地中
load_dotenv("config/.env")

# 创建提示词,需要两个参数:ability、question
prompt = ChatPromptTemplate.from_messages([
    ("system", "You're an assistant who's good at {ability}"),
    MessagesPlaceholder(variable_name="history"),
    ("human", "{question}"),
])

# 创建链
chain = prompt | AzureChatOpenAI(deployment_name="aicontent-validation")

# 清空或添加消息在store中
class InMemoryHistory(BaseChatMessageHistory, BaseModel):
    """In memory implementation of chat message history."""

    messages: List[BaseMessage] = Field(default_factory=list)

    def add_messages(self, messages: List[BaseMessage]) -> None:
        """Add a list of messages to the store"""
        self.messages.extend(messages)

    def clear(self) -> None:
        self.messages = []

# 设置全局变量,用于存储聊天记录
store = {}

# 通过id获取聊天记录
def get_by_session_id(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = InMemoryHistory()
    return store[session_id]

chain_with_history = RunnableWithMessageHistory(
    chain,
    # Uses the get_by_session_id function defined in the example
    # above.
    get_by_session_id,
    input_messages_key="question",
    history_messages_key="history",
)

first_res = chain_with_history.invoke(  # noqa: T201
    {"ability": "math", "question": "What does cosine mean?"},
    config={"configurable": {"session_id": "foo"}}
)
print(first_res)
# Uses the store defined in the example above.
print(store)  # noqa: T201

second_res = chain_with_history.invoke(  # noqa: T201
    {"ability": "math", "question": "What's its inverse"},
    config={"configurable": {"session_id": "foo"}}
)
print(second_res)

print(store)  # noqa: T201

实现效果:

(langvenv) [root@Laptop-latitude-7300 langchain_test]# python test/test.py 
content='Cosine is a trigonometric function used in geometry and calculus. Given a right triangle, the cosine of an angle is the ratio of the length of the adjacent side to the length of the hypotenuse. In the unit circle, the cosine of an angle is the x-coordinate of the point on the circle that corresponds to that angle. It is often abbreviated as "cos".' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 77, 'prompt_tokens': 25, 'total_tokens': 102, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4', 'system_fingerprint': None, 'prompt_filter_results': [{'prompt_index': 0, 'content_filter_results': {}}], 'finish_reason': 'stop', 'logprobs': None, 'content_filter_results': {'hate': {'filtered': False, 'severity': 'safe'}, 'self_harm': {'filtered': False, 'severity': 'safe'}, 'sexual': {'filtered': False, 'severity': 'safe'}, 'violence': {'filtered': False, 'severity': 'safe'}}} id='run-beb8b583-3d77-4d48-b80e-9f8d30d3b2ed-0' usage_metadata={'input_tokens': 25, 'output_tokens': 77, 'total_tokens': 102, 'input_token_details': {}, 'output_token_details': {}}
{'foo': InMemoryHistory(messages=[HumanMessage(content='What does cosine mean?', additional_kwargs={}, response_metadata={}), AIMessage(content='Cosine is a trigonometric function used in geometry and calculus. Given a right triangle, the cosine of an angle is the ratio of the length of the adjacent side to the length of the hypotenuse. In the unit circle, the cosine of an angle is the x-coordinate of the point on the circle that corresponds to that angle. It is often abbreviated as "cos".', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 77, 'prompt_tokens': 25, 'total_tokens': 102, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4', 'system_fingerprint': None, 'prompt_filter_results': [{'prompt_index': 0, 'content_filter_results': {}}], 'finish_reason': 'stop', 'logprobs': None, 'content_filter_results': {'hate': {'filtered': False, 'severity': 'safe'}, 'self_harm': {'filtered': False, 'severity': 'safe'}, 'sexual': {'filtered': False, 'severity': 'safe'}, 'violence': {'filtered': False, 'severity': 'safe'}}}, id='run-beb8b583-3d77-4d48-b80e-9f8d30d3b2ed-0', usage_metadata={'input_tokens': 25, 'output_tokens': 77, 'total_tokens': 102, 'input_token_details': {}, 'output_token_details': {}})])}
content='The inverse of the cosine function is called arccosine, or "cos^-1". If y = cos(x), then x = arccos(y). This function is used to find the angle that has a certain cosine value. For example, if you know the cosine of an angle is 0.5, you can use the arccosine function to find that the angle is 60 degrees (or approximately 1.047 radians).' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 92, 'prompt_tokens': 114, 'total_tokens': 206, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4', 'system_fingerprint': None, 'prompt_filter_results': [{'prompt_index': 0, 'content_filter_results': {}}], 'finish_reason': 'stop', 'logprobs': None, 'content_filter_results': {'hate': {'filtered': False, 'severity': 'safe'}, 'self_harm': {'filtered': False, 'severity': 'safe'}, 'sexual': {'filtered': False, 'severity': 'safe'}, 'violence': {'filtered': False, 'severity': 'safe'}}} id='run-cc5ffdb5-309d-43de-8949-da5d7164788d-0' usage_metadata={'input_tokens': 114, 'output_tokens': 92, 'total_tokens': 206, 'input_token_details': {}, 'output_token_details': {}}
{'foo': InMemoryHistory(messages=[HumanMessage(content='What does cosine mean?', additional_kwargs={}, response_metadata={}), AIMessage(content='Cosine is a trigonometric function used in geometry and calculus. Given a right triangle, the cosine of an angle is the ratio of the length of the adjacent side to the length of the hypotenuse. In the unit circle, the cosine of an angle is the x-coordinate of the point on the circle that corresponds to that angle. It is often abbreviated as "cos".', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 77, 'prompt_tokens': 25, 'total_tokens': 102, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4', 'system_fingerprint': None, 'prompt_filter_results': [{'prompt_index': 0, 'content_filter_results': {}}], 'finish_reason': 'stop', 'logprobs': None, 'content_filter_results': {'hate': {'filtered': False, 'severity': 'safe'}, 'self_harm': {'filtered': False, 'severity': 'safe'}, 'sexual': {'filtered': False, 'severity': 'safe'}, 'violence': {'filtered': False, 'severity': 'safe'}}}, id='run-beb8b583-3d77-4d48-b80e-9f8d30d3b2ed-0', usage_metadata={'input_tokens': 25, 'output_tokens': 77, 'total_tokens': 102, 'input_token_details': {}, 'output_token_details': {}}), HumanMessage(content="What's its inverse", additional_kwargs={}, response_metadata={}), AIMessage(content='The inverse of the cosine function is called arccosine, or "cos^-1". If y = cos(x), then x = arccos(y). This function is used to find the angle that has a certain cosine value. For example, if you know the cosine of an angle is 0.5, you can use the arccosine function to find that the angle is 60 degrees (or approximately 1.047 radians).', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 92, 'prompt_tokens': 114, 'total_tokens': 206, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4', 'system_fingerprint': None, 'prompt_filter_results': [{'prompt_index': 0, 'content_filter_results': {}}], 'finish_reason': 'stop', 'logprobs': None, 'content_filter_results': {'hate': {'filtered': False, 'severity': 'safe'}, 'self_harm': {'filtered': False, 'severity': 'safe'}, 'sexual': {'filtered': False, 'severity': 'safe'}, 'violence': {'filtered': False, 'severity': 'safe'}}}, id='run-cc5ffdb5-309d-43de-8949-da5d7164788d-0', usage_metadata={'input_tokens': 114, 'output_tokens': 92, 'total_tokens': 206, 'input_token_details': {}, 'output_token_details': {}})])}

返回值中有两个字典,这是存储的记录,可以分析得知,存储成功

第二个字典中存储了两个问答,第一个字典存储了一个问答。此处足以说明RunnableWithMessageHistory内部实现了第一个测试案例中的add_messages功能

会话使用两个id来精细化存储聊天信息

from typing import List
from langchain_openai import AzureChatOpenAI
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.messages import BaseMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from pydantic import BaseModel, Field
from langchain_core.runnables import ConfigurableFieldSpec
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables.history import RunnableWithMessageHistory
from dotenv import load_dotenv

# 将模型的相关数据加载到本地中
load_dotenv("config/.env")

# 创建提示词,需要两个参数:ability、question
prompt = ChatPromptTemplate.from_messages([
    ("system", "You're an assistant who's good at {ability}"),
    MessagesPlaceholder(variable_name="history"),
    ("human", "{question}"),
])

# 创建链
chain = prompt | AzureChatOpenAI(deployment_name="aicontent-validation")

# 清空或添加消息在store中
class InMemoryHistory(BaseChatMessageHistory, BaseModel):
    """In memory implementation of chat message history."""

    messages: List[BaseMessage] = Field(default_factory=list)

    def add_messages(self, messages: List[BaseMessage]) -> None:
        """Add a list of messages to the store"""
        self.messages.extend(messages)

    def clear(self) -> None:
        self.messages = []

# 设置全局变量,用于存储聊天记录
store = {}

# 通过user_id, conversation_id获取聊天信息
def get_session_history(user_id: str, conversation_id: str) -> BaseChatMessageHistory:
    if (user_id, conversation_id) not in store:
        store[(user_id, conversation_id)] = InMemoryHistory()
    return store[(user_id, conversation_id)]


with_message_history = RunnableWithMessageHistory(
    chain,
    get_session_history=get_session_history,
    input_messages_key="question",
    history_messages_key="history",
    history_factory_config=[
        ConfigurableFieldSpec(
            id="user_id",
            annotation=str,
            name="User ID",
            description="Unique identifier for the user.",
            default="",
            is_shared=True,
        ),
        ConfigurableFieldSpec(
            id="conversation_id",
            annotation=str,
            name="Conversation ID",
            description="Unique identifier for the conversation.",
            default="",
            is_shared=True,
        ),
    ],
)

with_message_history.invoke(
    {"ability": "math", "question": "What does cosine mean?"},
    config={"configurable": {"user_id": "123", "conversation_id": "1"}}
)

first_res = with_message_history.invoke(
    {"ability": "math", "question": "What does cosine mean?"},
    config={"configurable": {"user_id": "123", "conversation_id": "1"}}
)
print(first_res.content)
# Uses the store defined in the example above.
print(store)  # noqa: T201

second_res = with_message_history.invoke(  # noqa: T201
    {"ability": "math", "question": "What's its inverse"},
    config={"configurable": {"user_id": "123", "conversation_id": "1"}}
)
print(second_res.content)

print(store)  # noqa: T201

实现效果:

(langvenv) [root@Laptop-latitude-7300 langchain_test]# python test/test.py 
Cosine is a mathematical function that describes a specific relationship between the angles and sides of a right-angled triangle. If you have a right-angle triangle, the cosine of a given angle is the ratio of the length of the side adjacent to the angle to the length of the hypotenuse.

In terms of the unit circle (a circle with radius 1), the cosine of an angle is the x-coordinate of the point on the circle that corresponds to that angle.

Cosine is also a periodic function, meaning it repeats its values at regular intervals, and it's used extensively in mathematics and physics to model periodic phenomena, like the oscillation of a spring or the behavior of light and sound waves.
{('123', '1'): InMemoryHistory(messages=[HumanMessage(content='What does cosine mean?', additional_kwargs={}, response_metadata={}), AIMessage(content='Cosine is a fundamental concept in trigonometry that describes a specific relationship between the sides of a right-angled triangle. \n\nIf you have a right-angled triangle, the cosine (cos) of a given angle is the ratio of the length of the adjacent side to the length of the hypotenuse. \n\nIn the context of a unit circle (a circle with radius 1), cosine of an angle is the horizontal coordinate of the point on the circle that forms that angle from the positive horizontal axis.\n\nThe cosine function is also a periodic function often used in mathematics and physics to describe wave patterns, circular motion, and oscillations.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 129, 'prompt_tokens': 25, 'total_tokens': 154, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4', 'system_fingerprint': None, 'prompt_filter_results': [{'prompt_index': 0, 'content_filter_results': {}}], 'finish_reason': 'stop', 'logprobs': None, 'content_filter_results': {'hate': {'filtered': False, 'severity': 'safe'}, 'self_harm': {'filtered': False, 'severity': 'safe'}, 'sexual': {'filtered': False, 'severity': 'safe'}, 'violence': {'filtered': False, 'severity': 'safe'}}}, id='run-587f164e-5e94-40ba-b234-b0aff3901182-0', usage_metadata={'input_tokens': 25, 'output_tokens': 129, 'total_tokens': 154, 'input_token_details': {}, 'output_token_details': {}}), HumanMessage(content='What does cosine mean?', additional_kwargs={}, response_metadata={}), AIMessage(content="Cosine is a mathematical function that describes a specific relationship between the angles and sides of a right-angled triangle. If you have a right-angle triangle, the cosine of a given angle is the ratio of the length of the side adjacent to the angle to the length of the hypotenuse.\n\nIn terms of the unit circle (a circle with radius 1), the cosine of an angle is the x-coordinate of the point on the circle that corresponds to that angle.\n\nCosine is also a periodic function, meaning it repeats its values at regular intervals, and it's used extensively in mathematics and physics to model periodic phenomena, like the oscillation of a spring or the behavior of light and sound waves.", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 141, 'prompt_tokens': 167, 'total_tokens': 308, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4', 'system_fingerprint': None, 'prompt_filter_results': [{'prompt_index': 0, 'content_filter_results': {}}], 'finish_reason': 'stop', 'logprobs': None, 'content_filter_results': {'hate': {'filtered': False, 'severity': 'safe'}, 'self_harm': {'filtered': False, 'severity': 'safe'}, 'sexual': {'filtered': False, 'severity': 'safe'}, 'violence': {'filtered': False, 'severity': 'safe'}}}, id='run-404cf62c-19c0-40f4-9db3-4d9da6c66ffd-0', usage_metadata={'input_tokens': 167, 'output_tokens': 141, 'total_tokens': 308, 'input_token_details': {}, 'output_token_details': {}})])}
The inverse of the cosine function is called "arccosine" or "cosine inverse", and it's often written as "arccos" or "cos^-1". 

If the cosine of an angle is known, its arccosine or the inverse cosine can be used to determine the measure of the angle. For example, if cos(x) = y, then arccos(y) = x. 

It's important to note that the arccosine function will only return values in the range of 0 to π radians, or 0 to 180 degrees because of the way it is defined.
{('123', '1'): InMemoryHistory(messages=[HumanMessage(content='What does cosine mean?', additional_kwargs={}, response_metadata={}), AIMessage(content='Cosine is a fundamental concept in trigonometry that describes a specific relationship between the sides of a right-angled triangle. \n\nIf you have a right-angled triangle, the cosine (cos) of a given angle is the ratio of the length of the adjacent side to the length of the hypotenuse. \n\nIn the context of a unit circle (a circle with radius 1), cosine of an angle is the horizontal coordinate of the point on the circle that forms that angle from the positive horizontal axis.\n\nThe cosine function is also a periodic function often used in mathematics and physics to describe wave patterns, circular motion, and oscillations.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 129, 'prompt_tokens': 25, 'total_tokens': 154, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4', 'system_fingerprint': None, 'prompt_filter_results': [{'prompt_index': 0, 'content_filter_results': {}}], 'finish_reason': 'stop', 'logprobs': None, 'content_filter_results': {'hate': {'filtered': False, 'severity': 'safe'}, 'self_harm': {'filtered': False, 'severity': 'safe'}, 'sexual': {'filtered': False, 'severity': 'safe'}, 'violence': {'filtered': False, 'severity': 'safe'}}}, id='run-587f164e-5e94-40ba-b234-b0aff3901182-0', usage_metadata={'input_tokens': 25, 'output_tokens': 129, 'total_tokens': 154, 'input_token_details': {}, 'output_token_details': {}}), HumanMessage(content='What does cosine mean?', additional_kwargs={}, response_metadata={}), AIMessage(content="Cosine is a mathematical function that describes a specific relationship between the angles and sides of a right-angled triangle. If you have a right-angle triangle, the cosine of a given angle is the ratio of the length of the side adjacent to the angle to the length of the hypotenuse.\n\nIn terms of the unit circle (a circle with radius 1), the cosine of an angle is the x-coordinate of the point on the circle that corresponds to that angle.\n\nCosine is also a periodic function, meaning it repeats its values at regular intervals, and it's used extensively in mathematics and physics to model periodic phenomena, like the oscillation of a spring or the behavior of light and sound waves.", additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 141, 'prompt_tokens': 167, 'total_tokens': 308, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4', 'system_fingerprint': None, 'prompt_filter_results': [{'prompt_index': 0, 'content_filter_results': {}}], 'finish_reason': 'stop', 'logprobs': None, 'content_filter_results': {'hate': {'filtered': False, 'severity': 'safe'}, 'self_harm': {'filtered': False, 'severity': 'safe'}, 'sexual': {'filtered': False, 'severity': 'safe'}, 'violence': {'filtered': False, 'severity': 'safe'}}}, id='run-404cf62c-19c0-40f4-9db3-4d9da6c66ffd-0', usage_metadata={'input_tokens': 167, 'output_tokens': 141, 'total_tokens': 308, 'input_token_details': {}, 'output_token_details': {}}), HumanMessage(content="What's its inverse", additional_kwargs={}, response_metadata={}), AIMessage(content='The inverse of the cosine function is called "arccosine" or "cosine inverse", and it\'s often written as "arccos" or "cos^-1". \n\nIf the cosine of an angle is known, its arccosine or the inverse cosine can be used to determine the measure of the angle. For example, if cos(x) = y, then arccos(y) = x. \n\nIt\'s important to note that the arccosine function will only return values in the range of 0 to π radians, or 0 to 180 degrees because of the way it is defined.', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 128, 'prompt_tokens': 320, 'total_tokens': 448, 'completion_tokens_details': None, 'prompt_tokens_details': None}, 'model_name': 'gpt-4', 'system_fingerprint': None, 'prompt_filter_results': [{'prompt_index': 0, 'content_filter_results': {}}], 'finish_reason': 'stop', 'logprobs': None, 'content_filter_results': {'hate': {'filtered': False, 'severity': 'safe'}, 'self_harm': {'filtered': False, 'severity': 'safe'}, 'sexual': {'filtered': False, 'severity': 'safe'}, 'violence': {'filtered': False, 'severity': 'safe'}}}, id='run-edb01358-9652-44b5-b936-3f29c3b870e0-0', usage_metadata={'input_tokens': 320, 'output_tokens': 128, 'total_tokens': 448, 'input_token_details': {}, 'output_token_details': {}})])}

可以看到,效果是类似的

### 使用 DeepSeek API 实现多轮对话 为了实现基于 DeepSeek API 的多轮对话程序,可以结合 LangChain 工具库的功能。以下是详细的说明以及示例代码。 #### 1. 准备工作 在开始之前,需要完成以下准备工作: - 安装必要的依赖项 `langchain` 和 `deepseek`。 - 获取并配置 DeepSeek API 密钥。 - 设置环境变量以便于访问 API[^1]。 安装所需包可以通过以下命令完成: ```bash pip install langchain deepseek openai ``` #### 2. 多轮对话的核心逻辑 多轮对话的关键在于维护会话历史记录,并将其作为上下文传递给模型。LangChain 提供了专门用于管理聊天消息历史的类 `ChatMessageHistory`,这使得我们可以轻松地存储和检索用户的输入与模型的回答[^2]。 #### 3. 示例代码 下面是一个完整的 Python 脚本,展示了如何利用 DeepSeek-R1 模型构建一个多轮对话系统: ```python import os from langchain_community.chat_message_histories import ChatMessageHistory from langchain_core.messages import HumanMessage, AIMessage from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder from langchain_core.runnables import RunnableWithMessageHistory from langchain_openai import ChatOpenAI # 配置 DeepSeek API 参数 os.environ["DEEPSEEK_API_KEY"] = "your-deepseek-api-key" model = ChatOpenAI( model='deepseek-reasoner', temperature=0.7, max_tokens=256, base_url="https://api.deepseek.com/v1" ) # 初始化消息历史对象 history = ChatMessageHistory() def get_response(user_input): """获取模型响应""" history.add_user_message(user_input) # 添加用户的消息到历史中 prompt_template = ChatPromptTemplate.from_messages([ ("system", "You are a helpful assistant."), ("human", "{user_message}"), ("ai", "{response}") ]) runnable_model = RunnableWithMessageHistory(model=model, message_history=history) response = runnable_model.invoke(HumanMessage(content=user_input)) # 发送请求至模型 ai_message = AIMessage(content=str(response)) history.add_ai_message(ai_message.content) # 将 AI 响应加入历史记录 return ai_message.content if __name__ == "__main__": while True: user_input = input("User: ") if user_input.lower() in ["exit", "quit"]: break response = get_response(user_input) print(f"Assistant: {response}") ``` 上述脚本实现了基本的循环交互机制,在每次迭代过程中都会更新会话历史并将最新一轮的内容发送给 DeepSeek 模型进行推理[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值