基于AnalyticDB for PostgreSQL构建长记忆应用

更新时间:

大模型虽能记忆一定长度的对话,但受注意力机制限制可能会遗漏某些信息,导致生成内容质量下降。即使扩大大模型的上下文窗口长度,仍可能会遗漏关键信息,并且增加成本,降低模型效率。长记忆技术针对对话过程中的关键信息(主要为用户个性化信息,如用户特征、偏好等),进行提取并持久化存储,使AI应用在后续交互中引用相关记忆信息,从而提升对话质量与交互体验。

应用场景

  • 客服聊天机器人(Customer Support Chatbots):能够记住客户的偏好、历史记录和过往互动,以提供个性化支持。

  • 个人AI导师(Personal AI Tutors):构建能够追踪学生进度、适应学习模式并提供上下文相关帮助的教育助手。

  • 医疗健康应用(Healthcare Applications):开发能够维护患者病史并提供建议的个性化医疗助手。

  • 企业知识管理(Enterprise Knowledge Management):构建能够从组织内部互动中学习并维护机构知识的系统。

  • 个性化AI助手(Personalized AI Assistants):创建能够学习用户偏好并随着时间推移调整回应的智能助手。

前提条件

  • AnalyticDB for PostgreSQL7.0版实例,且内核版本满足以下任一条件:

    • 7.2版本且为7.2.1.4及以上。

    • 7.3.2.0及以上版本。

说明

您可以在控制台实例的基本信息页查看内核小版本。如不满足上述版本要求,需要您升级内核小版本

  • 获取API Key作为调用大模型的鉴权凭证。

  • 开通AnalyticDB for PostgreSQL实例所在VPC公网NAT网关,使实例能够访问大语言模型(LLM)服务。

产品架构

image
  • 核心组件

    • ADBPG LLM Memory Manager:置于AnalyticDB for PostgreSQLCoordinator节点上,面向用户提供大模型长记忆服务,其接受用户的查询请求,内部进行记忆检索,生成prompt,与用户query一起发送给LLM,并向用户返回最后的结果。同时根据当前对话的上下文自动更新或者新增记忆到向量数据库Vector Store或者图数据库Graph Store。

    • AI Service:提供LLMEmbedding服务。LLM支持用户查询、记忆抽取、记忆更新、冲突解决等功能。Embedding Model主要提供记忆向量化功能,用于记忆检索。

    • AnalyticDB for PostgreSQL提供记忆持久化能力记忆以向量、文本块、知识图谱的形式存储。

  • 主要特点

    • 记忆处理(Memory Processing):利用大语言模型(LLM)从对话中自动提取并存储重要信息,同时保持完整的上下文。

    • 记忆管理(Memory Management):持续更新存储的信息并解决其中的矛盾,以保持准确性。

    • 双存储架构(Dual Storage Architecture):结合向量数据库和图数据库存储信息。其中向量数据库用于记忆存储,图数据库用于关系追踪。

    • 智能检索(Smart Retrieval System):采用语义搜索和图查询,根据重要性和时效性查找相关记忆。

    • 多模态支持(Multimodal Support):支持从文本、图片等结构化和非结构化多模态数据中提取记忆。用户使用多模态数据加载记忆时,可直接提供数据 URL,但需确保使用的LLM具备多模态处理能力。LLM 会解析多模态数据并提取文本内容,随后长记忆模块将提取的文本进行记忆抽取,形成VectorGraph存储到AnalyticDB for PostgreSQL中,便于后续高效检索。

基础功能

记忆检索

image
  1. 查询处理

    • 使用LLM从用户的原始查询中提取关键信息。

    • 根据上下文和查询意图生成合适的过滤条件,加速检索的效率和准确度。如:分类信息、时间范围。

  2. 向量检索

    • 使用优化后的查询进行embedding,在向量数据库内执行语义搜索。

    • 根据与查询的相关性对结果进行排序。

    • 应用指定的过滤条件(用户、代理、元数据等)。

  3. 结果处理

    • 整合多个搜索条件返回的结果,并按照相关性、重要性、时间等因素进行排序。

    • 返回带有相关性评分的记忆条目。

    • 包含相关的元数据和时间戳,如:标签、分类等。

记忆更新

image
  1. 信息抽取

    • 使用LLM,从对话的上下文中提取出相关记忆。

    • 识别出重要的实体(entity),并抽取各个实体之间的关系(知识图谱)。

  2. 冲突解决

    • 系统自动将新记忆信息与现有记忆数据进行对比。

    • 识别并解决其中的冲突。

    点击查看冲突解决策略

    当新信息与已有记忆条目在实体、关系或属性上存在矛盾时会触发冲突解决。目前AnalyticDB for PostgreSQL长记忆框架采用的冲突解决策略为时间戳优先

    • 实体匹配:通过命名实体识别和语义相似度比较,判断新旧信息是否指向同一实体。

    • 属性对比:检查同一实体的属性(如时间、数值、状态)是否冲突。

    • 关系验证:对比实体之间的关系(如“用户A是用户B的同事”vs“用户A是用户B的上级”)。

    时间戳优先

    • 逻辑:以最新时间戳的记忆信息为准。

    • 适用场景:用户在对话中有相关属性信息的更新(如修改地址、更正日期)。

    • 示例:

      • 原有记忆:“用户生日是1995年”(时间戳:2023-01-01)

      • 新信息:“用户生日是1996年”(时间戳:2023-10-05)

      • 结果:更新用户生日为1996年。

    置信度评分(Confidence Scoring)

    • 逻辑:根据信息来源的可信度评分决定优先级。

      • 可信度评分可能基于:

        • 用户身份(如管理员输入与普通用户输入)

        • 数据来源(如权威文档与非正式对话)

        • 信息的上下文完整性(如详细描述与简单提及)

    • 示例:

      • 原有记忆:“用户职业是教师”(来源:用户自我介绍,可信度0.7)

      • 新信息:“用户职业是工程师”(来源:第三方认证,可信度0.9)

      • 结果:更新为“工程师”,并记录冲突历史。

    上下文合并

    • 逻辑:将矛盾信息合并为更完整的描述,保留上下文差异。

    • 适用场景:信息可能同时成立(如时间范围不同)。

    • 示例:

      • 原有记忆:“用户喜欢咖啡”(时间戳:2022-05)

      • 新信息:“用户不喜欢咖啡”(时间戳:2023-11)

      • 结果:合并为“用户曾喜欢咖啡(2022-05),但现在不喜欢(2023-11)”。

  3. 记忆存储

    • 向量数据库存储实际的记忆内容。

    • 图数据存储实体之间的关系。

    • 每一轮对话迭代中,都会自动更新记忆的内容。

记忆类型与场景

  • 记忆类型

    对于很多复杂的AI应用,需要在不同的对话中,引用之前对话所产生的记忆片段。常见的记忆类型如下。

    记忆类型

    说明

    事实记忆(Factual Memory)

    存储关于用户、偏好以及领域特定信息的知识。

    情景记忆(Episodic Memory)

    过去的互动和经历。

    语义记忆(Semantic Memory)

    对概念及其关系的理解。

    程序记忆(Procedual Memory)

    关于技术、过程、或者某个任务如何实现的记忆,主要用于 AI Agent 场景。

  • 记忆场景

    具体使用记忆时,可以有如下三种场景。

    记忆场景

    说明

    检索方式

    Session

    短期记忆场景,只关心某个对话Session中所产生的记忆,不会引用其他Session的记忆。记忆持久存储,除非调用记忆删除接口将其删除。

    通过Session id加载或检索该Session的所有记忆。

    User

    适用于需要引用某个用户历史上所有的记忆,User的以及包含所有与该User相关的Session的记忆。主要存储事实、情景、语义三种记忆类型。

    通过User id检索该User的所有记忆,或结合User idSession id检索该User对应的Session记忆。

    Agent

    主要用于AI Agent的长记忆场景,Agent记忆主要关注程序记忆(例如子任务的执行动作与结果)。业务调用Agent记忆接口时,AnalyticDB for PostgreSQL会使用特定Prompt提取AgentLLM的交互历史记录,形成记忆存储至Vector Store中。

    通过Agent id检索该Agent的所有记忆,或结合Agent idSession id检索该SessionAgent记忆。

使用示例

本示例依赖以下环境。

  • 大语言模型LLM:通义千问qwen3-32b。

  • 文本向量模型Embedding Model:text-embedding-v3(支持text-embedding-v4)。text-embedding-v3,text-embedding-v2模型的升级版本,主打高性能、低成本,支持50+种语言、超长文本。

  • 存储:AnalyticDB for PostgreSQLVector Store。

环境配置

  • 接口

    adbpg_llm_memory.config(config json):配置LLM、embedder、vector store等信息。

  • 示例

    说明
    • 该配置为会话(Session)级别,添加、获取记忆的相关SQL操作需要与该配置在同一个Session中执行。如果您通过DMS连接AnalyticDB for PostgreSQL实例,测试本文示例时,建议与后续SQL在同一SQL Console页签下一并执行。

    • 测试时请替换以下配置中的api_keyuserpassworddbnameport信息。其中,port值需执行SELECT port FROM gp_segment_configuration WHERE content=-1 AND role='p';获取。

    select adbpg_llm_memory.config(
        $$
        {
        "llm": {
            "provider": "qwen",
            "config": {
                "model": "qwen3-32b",
                "qwen_base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
                "api_key": "sk-xxxxxxx"
            }
        },
        "embedder": {
            "provider": "openai",
            "config": {
                "model": "text-embedding-v3",
                "embedding_dims": "256",
                "api_key": "sk-xxxxxx",
                "openai_base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1"
            }
        },
        "vector_store": {
          "provider": "adbpg",
          "config": {
                "user": "username",
                "password": "password",
                "dbname": "testdb",
                "hnsw": "True",
                "embedding_model_dims": "256",
                "port": 3029
              }
          }
    }
        $$
    );
  • 执行结果

    {'message': 'Configuration set successfully'}

添加新记忆

  • 接口

    adbpg_llm_memory.add(messages json, user_id text, run_id text, agent_id text, metadata json, memory_type text, prompt text)

    • messages:需要添加的记忆信息。

    • user_id:记忆信息所属的用户ID。

    • run_id:记忆信息所属的会话ID。

    • agent_id:记忆信息所属的Agent。

    • metadata:目前支持在metadata里面设置记忆的过期时间。

    • memory_type:记忆类型,默认为 null。如果是Agent相关的记忆,需要指定为'procedural_memory'

    • prompt:抽取记忆的 prompt,默认为null,一般情况下可满足使用需求。 支持自定义,建议 prompt 指定最后的输出格式为Output: {{"facts" : [xxx]}}

  • 示例

    SELECT adbpg_llm_memory.add($$
    [
        {"role": "user", "content": "嗨, 我是张三。 我喜欢徒步,不喜欢剧烈的运动,"},
        {"role": "assistant", "content": "你好,张三!徒步是个很棒的爱好,我会记住你的喜好。如果你有任何徒步路线规划、装备推荐或沿途风景的问题,欢迎随时交流。"}
    ]
    $$, 'test_u', null, null, $${"expiration_date": "2025-08-01"}$$, null, null);
  • 执行结果

    {
    	'results': [{
    				'id': 'e6d241f9-634f-43e4-925c-0ed70974****',
    				'memory': 'Name is 张三',
    				'event': 'ADD'
    			}, {
    				'id': '9efbb099-a20b-483e-99ef-3cc1e85e****',
    				'memory': 'Likes hiking',
    				'event': 'ADD'
    			}, {
    				'id': '6fc474d5-1e77-48ec-a5f2-8cb9ec50****',
    				'memory': 'Dislikes intense exercise ', 
                                    'event': 'ADD '
                            }
                ]
    }

获取某个用户或Agent的所有记忆

  • 接口

    adbpg_llm_memory.get_all(user_id text, run_id text, agent_id text):以json格式返回用户所有记忆。

  • 示例

    select adbpg_llm_memory.get_all('test_u', null, null);
  • 执行结果

    {
    	'results': [{
    		'id': '1cf1e872-5f78-41d0-b1ab-370eee82****',
    		'memory': 'Name is 张三',
    		'hash': 'd6f327d1ea38b8387927810bdcd3****',
    		'metadata': {
    			'expiration_date': '2025-08-01'
    		},
    		'created_at': '2025-06-25T15:45:58.687949+08:00',
    		'updated_at': None,
    		'user_id': 'test_u'
    	}, {
    		'id': '5806ab99-9764-4f31-bbda-29b77e8b****',
    		'memory': 'Likes hiking',
    		'hash': '5f8275169192f1a1a4564149c3d1****',
    		'metadata': {
    			'expiration_date': '2025-08-01'
    		},
    		'created_at': '2025-06-25T15:45:58.700653+08:00',
    		'updated_at': None,
    		'user_id': 'test_u'
    	}, {
    		'id': '55babe14-2605-40fa-9b32-e5ccefc3****',
    		'memory': 'Dislikes intense exercise',
    		'hash': '18fa10d79b6d2b0ec7f271817095****',
    		'metadata': {
    			'expiration_date': '2025-08-01'
    		},
    		'created_at': '2025-06-25T15:45:58.704473+08:00',
    		'updated_at': None,
    		'user_id': 'test_u'
    	}]
    }

获取给定query相关的记忆

  • 接口

    adbpg_llm_memory.search(query text, user_id text, run_id text, agent_id text, filter json)

    • query:用户输入的prompt。

    • filter:搜索时需要添加的过滤条件。

  • 示例

    select adbpg_llm_memory.search('给我推荐这周末的运动项目和相关地点?', 'test_u', null, null, null);
  • 执行结果

    {
    	'results': [{
    		'id': '5806ab99-9764-4f31-bbda-29b77e8b****',
    		'memory': 'Likes hiking',
    		'hash': '5f8275169192f1a1a4564149c3d1****',
    		'metadata': {
    			'expiration_date': '2025-08-01'
    		},
    		'score': 0.4617832899093628,
    		'created_at': '2025-06-25T15:45:58.700653+08:00',
    		'updated_at': None,
    		'user_id': 'test_u'
    	}, {
    		'id': '55babe14-2605-40fa-9b32-e5ccefc3****',
    		'memory': 'Dislikes intense exercise',
    		'hash': '18fa10d79b6d2b0ec7f271817095****',
    		'metadata': {
    			'expiration_date': '2025-08-01'
    		},
    		'score': 0.48010164499282837,
    		'created_at': '2025-06-25T15:45:58.704473+08:00',
    		'updated_at': None,
    		'user_id': 'test_u'
    	}, {
    		'id': '1cf1e872-5f78-41d0-b1ab-370eee82****',
    		'memory': 'Name is 张三',
    		'hash': 'd6f327d1ea38b8387927810bdcd3****',
    		'metadata': {
    			'expiration_date': '2025-08-01'
    		},
    		'score': 0.6027468977721387,
    		'created_at': '2025-06-25T15:45:58.687949+08:00',
    		'updated_at': None,
    		'user_id': 'test_u'
    	}]
    }

删除某个用户或Agent的所有记忆

  • 接口

    adbpg_llm_memory.delete_all(user_id text, run_id text, agent_id text)

  • 示例

    select adbpg_llm_memory.delete_all('test_u', null, null);
  • 执行结果

    {'message': 'All relevant memories deleted'}

构建带有记忆的个人专属旅行Agent

本章节将介绍如何结合AnalyticDB for PostgreSQLLangChain构建一个带有记忆功能的个人专属旅行Agent。该Agent可以记住用户的偏好和过往互动,为用户提供个性化的旅行建议、行程规划。

说明

已申请AnalyticDB for PostgreSQL实例、完成公网NAT网关配置,并获取API Key,详情请参见前提条件

  1. 允许运行Agent的机器访问AnalyticDB for PostgreSQL实例,详情请参见设置白名单

  2. 在运行Agent的机器上,安装ADB PG MCP服务

  3. 复制以下代码,并将下方envChatOpenAI中的相关配置替换为实际值。

    import asyncio
    import ast
    import os
    
    from mcp import ClientSession, StdioServerParameters
    from mcp.client.stdio import stdio_client
    
    import os
    from typing import List, Dict
    from langchain_openai import ChatOpenAI
    from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
    from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
    
    # Create server parameters for stdio connection
    server_params = StdioServerParameters(
        command="uv",  # Using uv to run the server
        args=["run", "adbpg-mcp-server"],  # Server with completion support
        env={"ADBPG_HOST": "gp-bp17t9r5bfg822****.gpdb.rds.aliyuncs.com",
            "ADBPG_PORT": "5432",
            "ADBPG_USER": "test_user",
            "ADBPG_PASSWORD": "testPassword",
            "ADBPG_DATABASE": "postgres",
            "LLMEMORY_API_KEY": "sk-xxx",
            "LLMEMORY_BASE_URL": "https://dashscope.aliyuncs.com/compatible-mode/v1",
            "LLMEMORY_LLM_MODEL": "qwen-max-latest",
            "LLMEMORY_EMBEDDING_MODEL": "text-embedding-v4"},
    )
    
    prompt = ChatPromptTemplate.from_messages([
        SystemMessage(content="""你是一个个人专属的旅行AI Agent, 请根据提供的上下文提供个性化的服务,并记住用户的偏好和过往互动。
        请提供旅行建议、行程规划,并解答关于目的地的问题。
        如果缺乏具体信息,可以根据常见旅行知识提供一般性建议。"""),
        MessagesPlaceholder(variable_name="context"),
        HumanMessage(content="{input}")
    ])
    
    # Initialize LangChain
    llm = ChatOpenAI(
              # 若没有配置环境变量,请将下行替换为:api_key="sk-xxx",
              api_key=os.getenv("DASHSCOPE_API_KEY"),
              base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
              model="qwen-max-latest")
    mcp_session = None
    
    async def retrieve_mem_context(query: str, user_id: str) -> List[Dict]:
        """Retrieve relevant context from adbpg LLM memory"""
        result = await mcp_session.call_tool(
                       name="adbpg_llm_memory_search",
                       arguments={
                           "query": query,
                           "user_id": user_id})
        result_str = result.content[0].text
        memories = ast.literal_eval(result_str)
        serialized_memories = ' '.join([mem["memory"] for mem in memories.get('results', [])])
        print(f"Memories: {serialized_memories}")
        context = [
            {
                "role": "system",
                "content": f"Relevant information: {serialized_memories}"
            },
            {
                "role": "user",
                "content": query
            }
        ]
        return context
    
    async def generate_response(input: str, context: List[Dict]) -> str:
        """Generate a response using the language model"""
        chain = prompt | llm
        response = chain.invoke({
            "context": context,
            "input": input
        })
        return response.content
    
    async def save_interaction(user_id: str, user_input: str, assistant_response: str):
        """Save the interaction to adbpg LLM memory"""
        interaction = [
            {
              "role": "user",
              "content": user_input
            },
            {
                "role": "assistant",
                "content": assistant_response
            }
        ]
        result = await mcp_session.call_tool(
            name="adbpg_llm_memory_add",
            arguments={
                "messages": interaction,
                "user_id": user_id
            }
        )
        print(f"Saving memories: {result}")
    
    async def run_chat(user_input: str, user_id: str) -> str:
        # Retrieve memory context
        context = await retrieve_mem_context(user_input, user_id)
    
        # Generate response
        response = await generate_response(user_input, context)
    
        # Save interaction
        await save_interaction(user_id, user_input, response)
    
        return response
    
    
    async def init_mcp():
        """Run the completion client example."""
        async with stdio_client(server_params) as (read, write):
            async with ClientSession(read, write) as session:
                await session.initialize()
                tools = await session.list_tools()
                global mcp_session
                mcp_session = session
                print(f"Available tools: {[tool.name for tool in tools.tools]}")
    
                print("欢迎!我是您的专属旅行助手!今天,您想让我帮您规划哪些旅行计划呢?")
                user_id = "张三"
    
                while True:
                    user_input = input("You: ")
                    if user_input.lower() in ['quit', 'exit', 'bye']:
                        print("感谢您的使用,祝您旅途愉快!")
                        break
    
                    response = await run_chat(user_input, user_id)
                    print(f"旅行助手: {response}")
    
    if __name__ == "__main__":
        asyncio.run(init_mcp())
  4. 测试Agent。

    在本测试中,当用户首次告知“我喜欢火锅”时,Agent将记忆此用户偏好;后续规划行程时,Agent自动召回此偏好,在行程中融入火锅元素。

    1. 第一轮对话

      输入示例

      You: 我喜欢火锅

      返回示例

      2025-08-19 15:09:32,730 - mcp.server.lowlevel.server - DEBUG - Received message: <mcp.shared.session.RequestResponder object at 0x1035bd1d0>
      2025-08-19 15:09:32,730 - mcp.server.lowlevel.server - INFO - Processing request of type CallToolRequest
      2025-08-19 15:09:32,730 - mcp.server.lowlevel.server - DEBUG - Dispatching request of type CallToolRequest
      2025-08-19 15:09:32,734 - adbpg-mcp-server - INFO - Database config: host=gp-bp17t9r5bfg822****.gpdb.rds.aliyuncs.com, port=5432, user=test_user, dbname=postgres
      2025-08-19 15:09:32,734 - adbpg-mcp-server - INFO - Database config: host=gp-bp17t9r5bfg822****.gpdb.rds.aliyuncs.com, port=5432, user=test_user, dbname=postgres
      2025-08-19 15:09:33,145 - mcp.server.lowlevel.server - DEBUG - Response sent
      Memories: 喜欢火锅
      2025-08-19 15:10:32,353 - mcp.server.lowlevel.server - DEBUG - Received message: <mcp.shared.session.RequestResponder object at 0x103584b00>
      2025-08-19 15:10:32,354 - mcp.server.lowlevel.server - INFO - Processing request of type CallToolRequest
      2025-08-19 15:10:32,354 - mcp.server.lowlevel.server - DEBUG - Dispatching request of type CallToolRequest
      2025-08-19 15:10:32,359 - adbpg-mcp-server - INFO - Database config: host=gp-bp17t9r5bfg822****.gpdb.rds.aliyuncs.com, port=5432, user=test_user, dbname=postgres
      2025-08-19 15:10:32,359 - adbpg-mcp-server - INFO - Database config: host=gp-bp17t9r5bfg822****.gpdb.rds.aliyuncs.com, port=5432, user=test_user, dbname=postgres
      2025-08-19 15:10:36,532 - mcp.server.lowlevel.server - DEBUG - Response sent
      Saving memories: meta=None content=[TextContent(type='text', text="{'results': []}", annotations=None, meta=None)] structuredContent=None isError=False
      旅行助手: 太棒了!火锅是非常美味的美食选择。既然你喜欢火锅,我可以为你推荐一些以火锅闻名的旅行目的地,或者帮你规划一趟充满火锅体验的旅程。
      
      以下是一些适合火锅爱好者的旅行建议:
      
      ---
      
      ### **国内火锅之旅推荐**
      1. **重庆**  
         - 作为中国火锅的发源地之一,重庆的麻辣火锅以其浓郁的牛油底料和丰富的配菜闻名。  
         - 必去火锅店:  
           - 【珮姐老火锅】:地道重庆风味,招牌毛肚必点!  
           - 【秦妈火锅】:连锁品牌,但口味正宗且环境舒适。  
         - 推荐体验:在洪崖洞附近的火锅店边欣赏夜景边吃火锅。
      
      2. **成都**  
         - 成都的火锅偏重香辣,同时也有很多鸳鸯锅选项,适合不太能吃辣的人。  
         - 必去火锅店:  
           - 【蜀九香】:以精致的菜品和服务著称。  
           - 【小龙坎老火锅】:人气超高,经常需要排队。  
         - 推荐活动:吃完火锅后可以逛宽窄巷子或春熙路,感受成都慢生活。
      
      3. **北京**  
         - 北京的涮羊肉火锅是北方火锅的代表,汤底清淡,注重食材本身的味道。  
         - 必去火锅店:  
           - 【东来顺】:老字号,羊肉鲜嫩可口。  
           - 【海底捞】:服务一流,适合家庭聚餐。  
      
      4. **云南腾冲**  
         - 腾冲的特色是“火山热海”,这里的野生菌火锅非常有名,尤其是松茸、牛肝菌等新鲜山珍。  
         - 推荐搭配:尝试用当地特有的酸辣蘸水调味。
      
      ---
      
      ### **国外火锅之旅推荐**
      1. **日本(寿喜烧/しゃぶしゃぶ)**  
         - 寿喜烧和涮涮锅(Shabu-Shabu)是日本经典的火锅形式,以薄切牛肉和蔬菜为主,搭配生鸡蛋液食用。  
         - 推荐城市:东京、大阪。  
         - 必去餐厅:  
           - 【叙叙苑】(东京):高级寿喜烧体验。  
           - 【一兰拉面旁的小型日式火锅店】:更接地气的选择。
      
      2. **韩国(部队锅/韩式火锅)**  
         - 韩国的部队锅、泡菜锅和海鲜锅都很受欢迎,味道浓郁且分量十足。  
         - 推荐城市:首尔、釜山。  
         - 必去餐厅:明洞或弘大的街头小吃店,性价比高。
      
      3. **泰国(泰式椰奶火锅)**  
         - 泰国的火锅通常使用椰奶汤底,加入柠檬草、香茅等调料,口感清爽又独特。  
         - 推荐城市:曼谷、清迈。  
         - 必去餐厅:【Mae Varee】,位于清迈,提供传统泰北风味火锅。
      
      ---
      
      ### **个性化行程规划**
      如果你计划一次围绕火锅展开的旅行,可以告诉我你的出发地点、时间安排以及预算范围,我将为你设计一份详细的行程单!例如:
      - **短期周末游**:从你所在的城市前往最近的火锅胜地(如重庆或成都)。  
      - **长假深度游**:结合多个目的地,探索不同风格的火锅文化。
      
      ---
      
      请告诉我更多细节,比如你想去的地方、出行时间和同伴情况,这样我可以进一步优化建议哦!
    2. 第二轮对话输入示例

      You: 规划去上海的旅行计划

      返回示例

      2025-08-21 16:22:33,470 - mcp.server.lowlevel.server - DEBUG - Received message: <mcp.shared.session.RequestResponder object at 0x104016250>
      2025-08-21 16:22:33,470 - mcp.server.lowlevel.server - INFO - Processing request of type CallToolRequest
      2025-08-21 16:22:33,470 - mcp.server.lowlevel.server - DEBUG - Dispatching request of type CallToolRequest
      2025-08-21 16:22:33,474 - adbpg-mcp-server - INFO - Database config: host=gp-bp17t9r5bfg822****.gpdb.rds.aliyuncs.com, port=5432, user=test_user, dbname=postgres
      2025-08-21 16:22:33,474 - adbpg-mcp-server - INFO - Database config: host=gp-bp17t9r5bfg822****..gpdb.rds.aliyuncs.com, port=5432, user=test_user, dbname=postgres
      2025-08-21 16:22:33,730 - mcp.server.lowlevel.server - DEBUG - Response sent
      Memories: 喜欢火锅
      2025-08-21 16:23:34,555 - mcp.server.lowlevel.server - DEBUG - Received message: <mcp.shared.session.RequestResponder object at 0x1040156a0>
      2025-08-21 16:23:34,556 - mcp.server.lowlevel.server - INFO - Processing request of type CallToolRequest
      2025-08-21 16:23:34,556 - mcp.server.lowlevel.server - DEBUG - Dispatching request of type CallToolRequest
      2025-08-21 16:23:34,561 - adbpg-mcp-server - INFO - Database config: host=gp-bp17t9r5bfg822****.gpdb.rds.aliyuncs.com, port=5432, user=test_user, dbname=postgres
      2025-08-21 16:23:34,562 - adbpg-mcp-server - INFO - Database config: host=gp-bp17t9r5bfg822****.gpdb.rds.aliyuncs.com, port=5432, user=test_user, dbname=postgres
      2025-08-21 16:23:39,645 - mcp.server.lowlevel.server - DEBUG - Response sent
      Saving memories: meta=None content=[TextContent(type='text', text="{'results': [{'id': '901de85d-3f8f-49f8-9381-30a7f1d23044', 'memory': '规划去上海的旅行计划', 'event': 'ADD'}]}", annotations=None, meta=None)] structuredContent=None isError=False
      旅行助手: 好的!既然你喜欢火锅,那我为你规划一个融合了美食、文化和景点的上海旅行计划,重点突出火锅体验和其他经典活动。以下是为期3天的行程建议:
      
      ---
      
      ### **第一天:抵达上海 & 美食初体验**
      **上午:抵达上海**
      - 根据你的航班或火车时间,抵达后先入住酒店(推荐选择市中心区域如南京东路、外滩或徐家汇附近)。
      - 放松休息,调整状态。
      
      **中午:午餐 - 本帮菜初体验**
      - 推荐餐厅:【老正兴】或【绿波廊】
      - 品尝上海特色菜肴,比如红烧肉、蟹粉小笼包等,感受地道的本帮风味。
      
      **下午:外滩漫步 & 南京路步行街**
      - 外滩:欣赏黄浦江两岸的风景,感受上海的历史与现代交融。
      - 南京路步行街:逛一逛繁华的购物街区,顺便买些小吃,比如鲜肉月饼或糖炒栗子。
      
      **晚上:火锅晚餐**
      - 推荐餐厅:【海底捞(南京东路店)】或【小龙坎老火锅】
      - 海底捞以服务著称,适合享受贴心的用餐体验;小龙坎则更偏向正宗川味火锅。
      - 必点菜品:麻辣锅底、毛肚、黄喉、虾滑、手工牛肉丸。
      
      ---
      
      ### **第二天:文化探索 & 美食之旅**
      **上午:豫园与城隍庙**
      - 豫园:典型的江南园林,景色精致,适合拍照打卡。
      - 城隍庙周边小吃:南翔小笼包、蟹壳黄、酒酿圆子等,可以尝试一些轻食。
      
      **中午:简单午餐**
      - 在城隍庙附近选择一家小店,试试生煎包或葱油拌面。
      
      **下午:田子坊 & 徐汇滨江艺术区**
      - 田子坊:充满创意的小巷,有很多手工艺品店和咖啡馆,非常适合闲逛。
      - 徐汇滨江艺术区:如果你喜欢现代艺术,可以参观西岸美术馆或龙美术馆。
      
      **晚上:高端火锅体验**
      - 推荐餐厅:【湊湊火锅·茶憩】或【谭鸭血老火锅】
      - 湊湊结合了台式火锅和奶茶饮品,环境优雅;谭鸭血则以其独特的鸭血和卤味拼盘闻名。
      - 必点菜品:花胶鸡汤锅底、海鲜拼盘、手打虾滑。
      
      ---
      
      ### **第三天:魔都全景 & 返程**
      **上午:上海中心大厦(上海之巅观光厅)**
      - 登上中国第一高楼——上海中心大厦,在546米高的观光厅俯瞰整个城市。
      
      **中午:静安寺商圈午餐**
      - 推荐餐厅:【鼎泰丰】或【新旺茶餐厅】
      - 尝试一些清淡的菜品,为接下来的火锅做准备。
      
      **下午:迪士尼小镇或朱家角古镇**
      - 如果你喜欢轻松的氛围,可以选择去迪士尼小镇逛街、喝咖啡,不需要入园游玩。
      - 如果偏爱古色古香的地方,可以前往朱家角古镇,乘船游览水乡风光。
      
      **晚上:告别火锅盛宴**
      - 推荐餐厅:【蜀大侠火锅】或【佩姐老火锅】
      - 蜀大侠的装修风格极具江湖气息,佩姐则主打重庆老味道。
      - 必点菜品:九宫格锅底、肥牛卷、贡菜、苕粉。
      
      ---
      
      ### **其他实用信息**
      1. **交通方式**:
         - 地铁是最便捷的方式,覆盖全市主要景点。
         - 使用“Metro大都会”App扫码乘车非常方便。
      2. **季节注意事项**:
         - 春秋季节天气宜人,适合户外活动。
         - 冬季较冷,但火锅更加温暖人心!
      3. **行李打包建议**:
         - 带一双舒适的鞋子,因为需要较多步行。
         - 上海冬天湿冷,记得带保暖衣物。
      
      希望这个行程能让你在上海玩得开心,同时满足你对火锅的热爱!如果还有其他需求或者想要调整,请随时告诉我~