全部產品
Search
文件中心

AnalyticDB:基於AnalyticDB for PostgreSQL構建長記憶應用

更新時間:Sep 09, 2025

大模型雖能記憶一定長度的對話,但受注意力機制限制可能會遺漏某些資訊,導致產生內容品質下降。即使擴大大模型的上下文視窗長度,仍可能會遺漏關鍵資訊,並且增加成本,降低模型效率。長記憶技術針對對話過程中的關鍵資訊(主要為使用者個人化資訊,如使用者特徵、偏好等),進行提取並持久化儲存,使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 Gateway,使執行個體能夠訪問大語言模型(LLM)服務。

產品架構

  • 核心組件

    • ADBPG LLM Memory Manager:置於AnalyticDB for PostgreSQLCoordinator節點上,面向使用者提供大模型長記憶服務,其接受使用者的查詢請求,內部進行記憶檢索,產生prompt,與使用者query一起發送給LLM,並向使用者返回最後的結果。同時根據目前的交談的上下文自動更新或者新增記憶到向量資料庫Vector Store或者圖資料庫Graph Store。

    • AI Service:提供LLM和Embedding服務。LLM支援使用者查詢、記憶抽取、記憶更新、衝突解決等功能。Embedding Model主要提供記憶向量化功能,用於記憶檢索。

    • AnalyticDB for PostgreSQL提供記憶持久化能力記憶以向量、文字區塊、知識圖譜的形式儲存。

  • 主要特點

    • 記憶處理(Memory Processing):利用大語言模型(LLM)從對話中自動提取並儲存重要訊息,同時保持完整的上下文。

    • 記憶管理(Memory Management):持續更新儲存的資訊並解決其中的矛盾,以保持準確性。

    • 雙儲存架構(Dual Storage Architecture):結合向量資料庫和圖資料庫儲存資訊。其中向量資料庫用於記憶儲存,圖資料庫用於關係追蹤。

    • 智能檢索(Smart Retrieval System):採用語義搜尋和圖查詢,根據重要性和時效性尋找相關記憶。

    • 多模態支援(Multimodal Support):支援從文本、圖片等結構化和非結構化多模態資料中提取記憶。使用者使用多模態資料載入記憶時,可直接提供資料 URL,但需確保使用的LLM具備多模態處理能力。LLM 會解析多模態資料並提取常值內容,隨後長記憶模組將提取的文本進行記憶抽取,形成Vector或Graph儲存到AnalyticDB for PostgreSQL中,便於後續高效檢索。

基礎功能

記憶檢索

  1. 查詢處理

    • 使用LLM從使用者的原始查詢中提取關鍵資訊。

    • 根據上下文和查詢意圖產生合適的過濾條件,加速檢索的效率和準確度。如:分類資訊、時間範圍。

  2. 向量檢索

    • 使用最佳化後的查詢進行embedding,在向量資料庫內執行語義搜尋。

    • 根據與查詢的相關性對結果進行排序。

    • 應用指定的過濾條件(使用者、代理、中繼資料等)。

  3. 結果處理

    • 整合多個搜尋條件返回的結果,並按照相關性、重要性、時間等因素進行排序。

    • 返回帶有相關性評分的記憶條目。

    • 包含相關的中繼資料和時間戳記,如:標籤、分類等。

記憶更新

  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 id與Session id檢索該User對應的Session記憶。

    Agent

    主要用於AI Agent的長記憶情境,Agent記憶主要關注程式記憶(例如子任務的執行動作與結果)。業務調用Agent記憶介面時,AnalyticDB for PostgreSQL會使用特定Prompt提取Agent與LLM的互動記錄,形成記憶儲存至Vector Store中。

    通過Agent id檢索該Agent的所有記憶,或結合Agent id與Session id檢索該Session的Agent記憶。

使用樣本

本樣本依賴以下環境。

  • 大語言模型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-intl.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-intl.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 PostgreSQL和LangChain構建一個帶有記憶功能的個人專屬旅行Agent。該Agent可以記住使用者的偏好和過往互動,為使用者提供個人化的旅行建議、行程規劃。

說明

已申請AnalyticDB for PostgreSQL執行個體、完成公網NAT Gateway配置,並擷取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-intl.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 LangChainchenwe
    llm = ChatOpenAI(
              # 若沒有配置環境變數,請將下行替換為:api_key="sk-xxx",
              api_key=os.getenv("DASHSCOPE_API_KEY"),
              base_url="https://dashscope-intl.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. **行李打包建議**:
         - 帶一雙舒適的鞋子,因為需要較多步行。
         - 上海冬天濕冷,記得帶保暖衣物。
      
      希望這個行程能讓你在上海玩得開心,同時滿足你對火鍋的熱愛!如果還有其他需求或者想要調整,請隨時告訴我~