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

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.dtcms.com/a/324877.html

相关文章:

  • scanpy单细胞转录组python教程(四):单样本数据分析之降维聚类及细胞注释
  • 【Canvas与戳记】黑底金Z字
  • 正确使用SQL Server中的Hint(10)— 常用Hint(2)
  • Spring WebSocket安全认证与权限控制解析
  • 研究揭示 Apple Intelligence 数据处理中可能存在隐私漏洞
  • 【redis初阶】------List 列表类型
  • 通过脚本修改MATLAB的数据字典
  • 【15】OpenCV C++实战篇——fitEllipse椭圆拟合、 Ellipse()画椭圆
  • 【人工智能99问】BERT的原理什么?(23/99)
  • Elasticsearch 保姆级入门篇
  • SpringBoot查询方式全解析
  • 在Mac上搭建本地AI工作流:Dify与DeepSeek的完美结合
  • 数字图像处理2——图像增强
  • AI(1)-神经网络(正向传播与反向传播)
  • 【RL第七篇】PPO训练策略,如何使PPO训练稳定?
  • unity中如何让原人物动画兼容新人物的动画
  • 异步问题的概念和消除问题技巧
  • Graph-R1:一种用于结构化多轮推理的智能图谱检索框架,并结合端到端强化学习
  • 【面板数据】全国及各省份技术市场成交额数据-dta+xlsx格式(2001-2023年)
  • nginx+lua+redis案例
  • 《Webpack与Vite热模块替换机制深度剖析与策略抉择》
  • 消息生态系统全景解析:技术架构、核心组件与应用场景
  • 【Python练习】085. 编写一个函数,实现简单的DNS服务器功能
  • LeeCode 46. 全排列
  • 【树\思维】P1395 会议
  • 33.搜索旋转排序数组
  • Agno智能体框架简单使用
  • docker等基础工具使用
  • 从策略梯度到 PPO
  • java中的继承