news 2026/6/11 9:22:39

18.4 动态更新数据库中长期记忆

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
18.4 动态更新数据库中长期记忆

以下是修改后的代码,实现了根据用户输入动态更新数据库中长期记忆的功能。核心逻辑:读取已有画像 → 从用户消息中提取新爱好 → 如果不同则更新数据库。

importosimportsysimportasyncioimportrefromdotenvimportload_dotenvfromlangchain_openaiimportChatOpenAIfromlanggraph.graphimportStateGraph,MessagesState,STARTfromlanggraph.checkpoint.memoryimportInMemorySaverfromlanggraph.store.postgresimportAsyncPostgresStore# 解决 Windows 上 psycopg 与 ProactorEventLoop 不兼容的问题ifsys.platform=='win32':asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())load_dotenv()# ========== 1. 数据库配置 ==========DB_URI="postgresql://postgres:root@localhost:5432/langgraph_db"# ========== 2. 初始化 LLM ==========llm=ChatOpenAI(model="qwen-plus",temperature=0.7,api_key=os.getenv("DASHSCOPE_API_KEY"),base_url=os.getenv("DASHSCOPE_BASE_URL"),model_kwargs={"extra_body":{"enable_thinking":False}})checkpointer=InMemorySaver()defcall_agent(state:MessagesState):response=llm.invoke(state["messages"])return{"messages":[response]}defextract_hobby_from_text(text:str)->str|None:"""从用户消息中提取爱好关键词(简单规则)"""patterns=[r"喜欢(养)?(猫|狗|鸟|鱼|乌龟|兔子|摄影|画画|唱歌|跳舞|游泳|跑步|读书)",r"爱好是(.{2,6})",r"现在喜欢(养)?(.{2,6})",]forpatterninpatterns:match=re.search(pattern,text)ifmatch:# 提取捕获组中的关键词hobby=match.group(2)iflen(match.groups())>=2elsematch.group(1)ifhobby:returnhobby.strip()returnNoneasyncdefmain():asyncwithAsyncPostgresStore.from_conn_string(DB_URI)asstore:awaitstore.setup()print("✅ PostgreSQL 长期存储已连接")builder=StateGraph(MessagesState)builder.add_node("call_agent",call_agent)builder.add_edge(START,"call_agent")graph=builder.compile(checkpointer=checkpointer,store=store)user_id="user_001"config={"configurable":{"thread_id":f"{user_id}_thread"}}namespace=("profiles",user_id)# 1. 读取已有记忆existing=awaitstore.aget(namespace,"user_info")ifnotexisting:default_profile={"name":"张明","hobby":"摄影","preferences":{"language":"zh-CN","style":"detailed"}}awaitstore.aput(namespace,"user_info",default_profile)print("💾 首次写入默认用户画像")profile=default_profileelse:profile=existing.valueprint(f"📋 读取现有画像:{profile}")# 2. 模拟用户输入(可从控制台输入或硬编码)user_input=input("\n请输入您的消息: ")# 例如:"我现在喜欢养猫"print(f"用户:{user_input}")# 3. 提取新爱好并比较new_hobby=extract_hobby_from_text(user_input)ifnew_hobbyandnew_hobby!=profile.get("hobby"):print(f"🔄 检测到爱好变化:{profile['hobby']}{new_hobby}")profile["hobby"]=new_hobbyawaitstore.aput(namespace,"user_info",profile)print("💾 用户画像已更新到 PostgreSQL")# 重新读取以获取最新(仅用于后续显示)existing=awaitstore.aget(namespace,"user_info")profile=existing.value# 4. 构造带记忆的对话context=f"用户偏好:{profile}。请基于此回答。"messages=[("system",context),("user",user_input)]# 5. 执行图foreventingraph.stream({"messages":messages},config=config,stream_mode="values"):event["messages"][-1].pretty_print()if__name__=="__main__":asyncio.run(main())

主要修改点说明

  1. 添加爱好提取函数extract_hobby_from_text
    使用简单的正则表达式从用户消息中提取“喜欢xxx”或“爱好是xxx”的内容。你可以根据实际场景扩展规则。

  2. 交互式输入
    将硬编码的用户消息改为input(),方便测试不同输入。

  3. 动态更新逻辑

    • 读取现有画像 → 从新消息中提取爱好 → 如果不同则调用store.aput覆盖数据库。
    • 更新后重新读取profile,确保后续对话使用最新画像。
  4. 保持回复使用最新记忆
    构造系统提示时使用更新后的profile,让 LLM 基于最新爱好回答。

测试效果

  • 首次运行:存储默认hobby: "摄影"
  • 第二次运行,输入"我现在喜欢养猫"
    • 程序提取出新爱好"猫",发现与"摄影"不同。
    • 执行UPDATE store SET value = ...,数据库中的hobby变为"养猫"
    • 对话中的系统提示变为"用户偏好:{... 'hobby': '养猫' ...}"
  • 第三次运行,输入"我喜欢拍风景照片"(未提及爱好变化),不会更新数据库,但模型回答仍会基于"养猫"给出个性化回复(如果上下文合理)。

如何进一步优化

  • 使用 LLM 判断意图:可调用一次轻量模型来判断用户是否表达了偏好改变,而不依赖正则。
  • 支持多字段更新:不仅爱好,还可更新姓名、偏好风格等。
  • 增加确认机制:更新前询问用户“确认将爱好从XX改为YY吗?”

这样,你就拥有了一个能够动态演化的长期记忆系统,数据库中的信息会随着对话而自动更新。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/11 9:22:36

深度学习在数字病理学固定类型预测中的应用与优化

1. 数字病理学中的固定类型预测挑战在病理实验室的日常工作中,组织切片的固定处理是影响后续诊断质量的关键环节。病理技术人员需要将组织样本通过两种主要方法进行固定:福尔马林固定石蜡包埋(FFPE)和冰冻切片(FS)。这两种方法在组织处理时间、操作流程和…

作者头像 李华
网站建设 2026/6/11 9:22:31

变分联合嵌入(VJE)原理与实现详解

1. 变分联合嵌入(VJE)的核心思想解析变分联合嵌入(VJE)是一种基于变分推断的表示学习方法,它通过构建一个概率生成模型来学习数据的低维表示。与传统确定性方法不同,VJE显式地建模了表示空间中的不确定性,为每个数据点学习一个分布而非单个点…

作者头像 李华
网站建设 2026/6/11 9:22:27

Arch Linux笔记本显卡驱动全攻略:从Intel/NVIDIA/AMD到虚拟机与性能调优

1. 显卡驱动基础:为什么需要完整安装? 刚接触Arch Linux的笔记本用户经常会疑惑:为什么装个显卡驱动要安装这么多包?这得从现代显卡的功能模块说起。一块显卡在Linux系统中需要处理至少五种核心功能:2D显示输出&#x…

作者头像 李华