当前位置: 首页 > web >正文

ADK[3]历史对话信息保存机制与构建多轮对话机器人

文章目录

  • 说明
  • ADK历史对话信息保存机制与构建多轮对话机器人
    • ADK历史对话保存机制
    • ADK会话容器与会话管理器
      • 会话容器Session
      • 会话生成器session_service

说明

  • 本文学自赋范社区公开课,仅供学习和交流使用,不用作任何商业用途!

ADK历史对话信息保存机制与构建多轮对话机器人

ADK历史对话保存机制

  • 注意,无需任何额外设置,ADK的历史对话信息就保存在session_service.sessions对象中:
{'test_app': {'user_1': {'session_001': Session(id='session_001', app_name='test_app', user_id='user_1', state={}, events=[Event(content=Content(parts=[Part(text='你好,我叫陈明,好久不见!'),],role='user'), grounding_metadata=None, partial=None, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=None, invocation_id='e-34a9f60a-accb-4c26-82c8-8f4eb8785a3e', author='user', actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='a4e6dfd9-44a3-49ff-96b6-2c59de1ee37e', timestamp=1754825541.112879), Event(content=Content(parts=[Part(text='陈明先生您好!很高兴认识您!虽然我们可能是初次对话,但很乐意为您提供帮助。请问今天有什么问题需要解答,或是有什么我可以为您做的吗?😊'),],role='model'), grounding_metadata=None, partial=False, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=GenerateContentResponseUsageMetadata(candidates_token_count=228,prompt_token_count=44,total_token_count=272), invocation_id='e-34a9f60a-accb-4c26-82c8-8f4eb8785a3e', author='simple_agent', actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='59ae6f2a-a266-4b2d-ab68-146029461bea', timestamp=1754825541.11385)], last_update_time=1754825541.11385)}}}
  • 无需任何额外操作,直接再进行新的对话,就会带入历史上下文进行对话,新的会话信息会继续存储在session_service.sessions中:
    query='很高兴认识你,你还记得我叫什么名字么?'
    USER_ID = "user_1"
    SESSION_ID = "session_001"
    await call_agent_async(query, runner, USER_ID, SESSION_ID)
    
    >>> User Query: 很高兴认识你,你还记得我叫什么名字么?[Event] 作者: simple_agent, 类型: Event, 最终: True, 内容: parts=[Part(text='当然记得啦!(开心地点头) 陈明先生~刚才您特意告诉我的名字怎么会忘记呢?(眨眨眼) 作为您的专属助手,记住用户信息是最基本的礼貌呀!✨'
    )] role='model'
    <<< Agent Response: 当然记得啦!(开心地点头) 陈明先生~刚才您特意告诉我的名字怎么会忘记呢?(眨眨眼) 作为您的专属助手,记住用户信息是最基本的礼貌呀!✨
    
session_service.sessions['test_app']
{'user_1': {'session_001': Session(id='session_001', app_name='test_app', user_id='user_1', state={}, events=[Event(content=Content(parts=[Part(text='你好,我叫陈明,好久不见!'),],role='user'), grounding_metadata=None, partial=None, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=None, invocation_id='e-d4a12215-9994-41ea-a0b2-f86dddefcc22', author='user', actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='3cc12d58-5de8-4ed8-b68e-9b9f08edb13b', timestamp=1754827957.285374), Event(content=Content(parts=[Part(text='陈明你好!😄 好久不见确实让人开心!虽然我们可能是初次相遇,但今天能再次“相遇”也很棒~最近在忙什么?有什么想聊的或需要帮忙的事吗?我随时在这儿呢! 🌟'),],role='model'), grounding_metadata=None, partial=False, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=GenerateContentResponseUsageMetadata(candidates_token_count=262,prompt_token_count=44,total_token_count=306), invocation_id='e-d4a12215-9994-41ea-a0b2-f86dddefcc22', author='simple_agent', actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='7e49812b-4d61-4bc5-b198-86d4d7097da0', timestamp=1754827957.286401), Event(content=Content(parts=[Part(text='很高兴认识你,你还记得我叫什么名字么?'),],role='user'), grounding_metadata=None, partial=None, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=None, invocation_id='e-88b63c38-7411-4f33-9e91-bba451e6c6e5', author='user', actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='3ca5515e-afd8-46d6-ad47-31565d32d347', timestamp=1754827971.530513), Event(content=Content(parts=[Part(text='当然记得啦!(开心地点头) 陈明先生~刚才您特意告诉我的名字怎么会忘记呢?(眨眨眼) 作为您的专属助手,记住用户信息是最基本的礼貌呀!✨'),],role='model'), grounding_metadata=None, partial=False, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=GenerateContentResponseUsageMetadata(candidates_token_count=204,prompt_token_count=109,total_token_count=313), invocation_id='e-88b63c38-7411-4f33-9e91-bba451e6c6e5', author='simple_agent', actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='f53a585c-2fa8-4857-b99a-7ade1db28c34', timestamp=1754827971.530513)], last_update_time=1754827971.530513)}}
  • 由此可见,ADK对话管理非常完整细致。只需调用await call_agent_async(query, runner, USER_ID, SESSION_ID),就是在执行多轮对话。

ADK会话容器与会话管理器

  • 谷歌ADK的企业级用户会话管理功能的实现,主要依托于InMemorySessionServiceSession两个类。
    from google.adk.sessions import InMemorySessionService, Session
    InMemorySessionService?
    

会话容器Session

  • 在首次创建会话管理器session_service的时候,曾经使用create命令初始化过一个会话容器。伴随对话的进行,多轮对话信息都保存在session_service.sessions中,而最开始创建的会话容器session还保留着最初始的状态。
    session
    
    Session(id='session_001', app_name='test_app', user_id='user_1', state={}, events=[], last_update_time=1745764835.901281)
    
  • 相比每次对话时都会带入的session_service.sessions对象,会话容器session更像是一种备份、或者充当保存点的角色,可以使用session_service.get_session内容创建一个包含当前对话全部信息的会话容器。
    session_all = session_service.get_session(app_name=APP_NAME,user_id=USER_ID,session_id=SESSION_ID
    )
    
id='session_001' app_name='test_app' user_id='user_1' state={} events=[Event(content=Content(parts=[Part(text='你好,我叫陈明,好久不见!'),],role='user'
), grounding_metadata=None, partial=None, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=None, invocation_id='e-d4a12215-9994-41ea-a0b2-f86dddefcc22', author='user', actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='3cc12d58-5de8-4ed8-b68e-9b9f08edb13b', timestamp=1754827957.285374), Event(content=Content(parts=[Part(text='陈明你好!😄 好久不见确实让人开心!虽然我们可能是初次相遇,但今天能再次“相遇”也很棒~最近在忙什么?有什么想聊的或需要帮忙的事吗?我随时在这儿呢! 🌟'),],role='model'
), grounding_metadata=None, partial=False, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=GenerateContentResponseUsageMetadata(candidates_token_count=262,prompt_token_count=44,total_token_count=306
), invocation_id='e-d4a12215-9994-41ea-a0b2-f86dddefcc22', author='simple_agent', actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='7e49812b-4d61-4bc5-b198-86d4d7097da0', timestamp=1754827957.286401), Event(content=Content(parts=[Part(text='很高兴认识你,你还记得我叫什么名字么?'),],role='user'
), grounding_metadata=None, partial=None, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=None, invocation_id='e-88b63c38-7411-4f33-9e91-bba451e6c6e5', author='user', actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='3ca5515e-afd8-46d6-ad47-31565d32d347', timestamp=1754827971.530513), Event(content=Content(parts=[Part(text='当然记得啦!(开心地点头) 陈明先生~刚才您特意告诉我的名字怎么会忘记呢?(眨眨眼) 作为您的专属助手,记住用户信息是最基本的礼貌呀!✨'),],role='model'
), grounding_metadata=None, partial=False, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=GenerateContentResponseUsageMetadata(candidates_token_count=204,prompt_token_count=109,total_token_count=313
), invocation_id='e-88b63c38-7411-4f33-9e91-bba451e6c6e5', author='simple_agent', actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='f53a585c-2fa8-4857-b99a-7ade1db28c34', timestamp=1754827971.530513)] last_update_time=1754827971.530513

  • 至此,有两个会话容器,其中session是个空的容器,而session_all是一个包含了好几轮对话信息的容器。
  • 而如果想要回到最初始的状态(清空全部历史消息),则可以使用如下方法恢复到session保留的记忆。
    session_service.sessions['test_app']['user_1']['session_001'] = session
    
  • 通过以上命令,会话生成器的历史对话和session就同步了。此时,再进行对话,不会有任何历史对话。而本次对话信息会继续留在session_service.sessions中。
    query = '你好,你还记得我叫什么名字么?'
    await call_agent_async(query, runner, USER_ID, SESSION_ID)
    session_service.sessions
    
    {'test_app': {'user_1': {'session_001': Session(id='session_001', app_name='test_app', user_id='user_1', state={}, events=[Event(content=Content(parts=[Part(text='你好,你还记得我叫什么名字么?'),],role='user'), grounding_metadata=None, partial=None, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=None, invocation_id='e-0eef13ef-c918-4ce0-bc65-ba31a9332ef4', author='user',actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='ee35976e-1d84-4302-9419-d4ce9a297603', timestamp=1754834647.681648), Event(content=Content(parts=[Part(text='您好!在之前的对话中,您还没有告诉我您的名字呢。如果您愿意的话,可以告诉我您的名字,这样我就能记住并称呼您啦!😊'),],role='model'), grounding_metadata=None, partial=False, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=GenerateContentResponseUsageMetadata(candidates_token_count=162,prompt_token_count=44,total_token_count=206), invocation_id='e-0eef13ef-c918-4ce0-bc65-ba31a9332ef4', author='simple_agent', actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='a26b24e9-f715-4909-a104-20621730dff4', timestamp=1754834647.682259)], last_update_time=1754834647.682259)}}}
    
  • 想要恢复此前session_all的会话内容,则可以使用如下方法:
    session_service.sessions['test_app']['user_1']['session_001'] = session_all
    
{'test_app': {'user_1': {'session_001': Session(id='session_001', app_name='test_app', user_id='user_1', state={}, events=[Event(content=Content(parts=[Part(text='你好,我叫陈明,好久不见!'),],role='user'), grounding_metadata=None, partial=None, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=None, invocation_id='e-d4a12215-9994-41ea-a0b2-f86dddefcc22', author='user', actions=EventActions(skip_summarization=None, state_delta={},artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='3cc12d58-5de8-4ed8-b68e-9b9f08edb13b', timestamp=1754827957.285374), Event(content=Content(parts=[Part(text='陈明你好!😄 好久不见确实让人开心!虽然我们可能是初次相遇,但今天能再次“相遇”也很棒~最近在忙什么?有什么想聊的或需要帮忙的事吗?我随时在这儿呢! 🌟'),],role='model'), grounding_metadata=None, partial=False, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=GenerateContentResponseUsageMetadata(candidates_token_count=262,prompt_token_count=44,total_token_count=306), invocation_id='e-d4a12215-9994-41ea-a0b2-f86dddefcc22', author='simple_agent', actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}),long_running_tool_ids=None, branch=None, id='7e49812b-4d61-4bc5-b198-86d4d7097da0', timestamp=1754827957.286401), Event(content=Content(parts=[Part(text='很高兴认识你,你还记得我叫什么名字么?'),],role='user'), grounding_metadata=None, partial=None, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=None, invocation_id='e-88b63c38-7411-4f33-9e91-bba451e6c6e5', author='user', actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='3ca5515e-afd8-46d6-ad47-31565d32d347', timestamp=1754827971.530513), Event(content=Content(parts=[Part(text='当然记得啦!(开心地点头) 陈明先生~刚才您特意告诉我的名字怎么会忘记呢?(眨眨眼) 作为您的专属助手,记住用户信息是最基本的礼貌呀!✨'),],role='model'), grounding_metadata=None, partial=False, turn_complete=None, error_code=None, error_message=None, interrupted=None, custom_metadata=None, usage_metadata=GenerateContentResponseUsageMetadata(candidates_token_count=204,prompt_token_count=109,total_token_count=313), invocation_id='e-88b63c38-7411-4f33-9e91-bba451e6c6e5', author='simple_agent', actions=EventActions(skip_summarization=None, state_delta={}, artifact_delta={}, transfer_to_agent=None, escalate=None, requested_auth_configs={}), long_running_tool_ids=None, branch=None, id='f53a585c-2fa8-4857-b99a-7ade1db28c34', timestamp=1754827971.530513)], last_update_time=1754827971.530513)}}}

会话生成器session_service

  • 会话生成器session_service的核心作用是伴随着会话进程,时刻保存会话信息。而实际上会话生成器还有更多的会话生命周期管理的功能。
    session_service?
    
    Type:        InMemorySessionService
    String form: <google.adk.sessions.in_memory_session_service.InMemorySessionService object at 0x000001AFB8C9A790>
    File:        c:\programdata\anaconda3\envs\jupyter_env\lib\site-packages\google\adk\sessions\in_memory_session_service.py
    Docstring:   An in-memory implementation of the session service.
    
  • ADK的会话生成器有三种,其一是InMemorySessionService类。
    from google.adk.sessions import InMemorySessionService
    
  • 该类实例化的会话生成器,是基于内存的会话生成与保存,使用更加轻量便捷,但并不能持久化保存,一旦环境重启(或进程终止),历史会话就会消失。
  • 因此ADK还提供了另外两种能够持久化保存会话信息的方法,分别是使用数据库(PostgreSQL、MySQL、SQLite)进行保存的库DatabaseSessionService和在谷歌云平台Vertex AI上进行存储的VertexAiSessionService
    from google.adk.sessions import DatabaseSessionService
    
    from google.adk.sessions import VertexAiSessionService
    

  • 若采用持久化的会话生成器,则每次生成的会话内容(包括events流)则都会自动存储在指定数据库中。整个过程要求新进行数据库安装下载配置,并创建响应的存储表。以DatabaseSessionService+MySQL为例,基本执行流程如下:

  • 第一步:设计数据库表结构:根据 ADK 的要求,我们需要在 MySQL 中创建四张表:sessionseventsapp_statesuser_states

  • 第二步:安装和配置 ADK:紧接着在 Python 环境中安装 Google ADK和安装支持 MySQL 的扩展。

    pip install google-adk
    
    pip install pymysql
    
  • 第三步:配置 DatabaseSessionService:在 Python 代码中,配置 DatabaseSessionService

    from google.adk.sessions import DatabaseSessionService
    mysql_url = "mysql+pymysql://username:password@localhost/adk_sessions"
    session_service = DatabaseSessionService(db_url=mysql_url)
    
  • 第四步:创建会话并添加事件:在创建会话时,您可以初始化会话状态并添加事件:

    from google.adk.sessions import Session
    from google.adk.events import UserMessage, AgentResponsesession = session_service.create_session(app_name="MySQL_test",user_id="user_1",session_id="session_1",state={"history": []}
    )
    
http://www.xdnf.cn/news/17622.html

相关文章:

  • 单片机捷径
  • nginx下lua的实现机制、Lua错误处理、面向对象
  • Unity 遮挡显示效果 Shader
  • 异步问题的概念和消除问题技巧
  • 机器学习 DBScan
  • Java语言简介
  • 《算法导论》第 17 章 - 摊还分析
  • 【Docker进阶实战】从多容器编排到集群部署
  • 谷歌DeepMind发布Genie 3:通用型世界模型,可生成前所未有多样化的交互式虚拟环境
  • 【PyTorch】单目标检测项目部署
  • BGP知识点总结
  • MACBOOK M1安装达梦8数据库
  • 机器学习实战·第三章 分类(1)
  • 组合期权:对角价差
  • Python描述符进阶:自定义文档与属性删除的艺术
  • 2025年全国青少年信息素养大赛Scratch编程践挑战赛-小高组-初赛-模拟题
  • P3232 [HNOI2013] 游走,solution
  • redis 全局命令、数据结构和内部编码、单线程架构
  • 深入理解C语言一维数组的本质:数组名、指针常量与访问细节
  • 250810-OpenWebUI集成Dify应用
  • uboot使用指南
  • 分布微服务电商订单系统Rust编码开发[下]
  • MySQL的逻辑架构和SQL执行的流程:
  • Stream流应用
  • MPLS特性之PHP(Penultimate Hop Popping)
  • afsim2.9_使用QtCreator和VSCode编译
  • 【杂谈】-智能代理+可观察性:构建下一代复杂系统监控体系
  • 《解锁 C++ 起源与核心:命名空间用法 + 版本演进全知道》
  • AUTOSAR进阶图解==>AUTOSAR_ASWS_TransformerGeneral
  • 关于linux操作系统下的文件操作方法: