基于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及以上版本。
-
产品架构
-
核心组件
-
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中,便于后续高效检索。
-
基础功能
记忆检索
-
查询处理
-
使用LLM从用户的原始查询中提取关键信息。
-
根据上下文和查询意图生成合适的过滤条件,加速检索的效率和准确度。如:分类信息、时间范围。
-
-
向量检索
-
使用优化后的查询进行embedding,在向量数据库内执行语义搜索。
-
根据与查询的相关性对结果进行排序。
-
应用指定的过滤条件(用户、代理、元数据等)。
-
-
结果处理
-
整合多个搜索条件返回的结果,并按照相关性、重要性、时间等因素进行排序。
-
返回带有相关性评分的记忆条目。
-
包含相关的元数据和时间戳,如:标签、分类等。
-
记忆更新
-
信息抽取
-
使用LLM,从对话的上下文中提取出相关记忆。
-
识别出重要的实体(entity),并抽取各个实体之间的关系(知识图谱)。
-
-
冲突解决
-
系统自动将新记忆信息与现有记忆数据进行对比。
-
识别并解决其中的冲突。
-
-
记忆存储
-
向量数据库存储实际的记忆内容。
-
图数据存储实体之间的关系。
-
每一轮对话迭代中,都会自动更新记忆的内容。
-
记忆类型与场景
-
记忆类型
对于很多复杂的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_key、user、password、dbname、port信息。其中,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 PostgreSQL和LangChain构建一个带有记忆功能的个人专属旅行Agent。该Agent可以记住用户的偏好和过往互动,为用户提供个性化的旅行建议、行程规划。
已申请AnalyticDB for PostgreSQL实例、完成公网NAT网关配置,并获取API Key,详情请参见前提条件。
-
允许运行Agent的机器访问AnalyticDB for PostgreSQL实例,详情请参见设置白名单。
-
在运行Agent的机器上,安装ADB PG MCP服务。
-
复制以下代码,并将下方
env及ChatOpenAI中的相关配置替换为实际值。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()) -
测试Agent。
在本测试中,当用户首次告知“我喜欢火锅”时,Agent将记忆此用户偏好;后续规划行程时,Agent自动召回此偏好,在行程中融入火锅元素。
-
第一轮对话
输入示例
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】,位于清迈,提供传统泰北风味火锅。 --- ### **个性化行程规划** 如果你计划一次围绕火锅展开的旅行,可以告诉我你的出发地点、时间安排以及预算范围,我将为你设计一份详细的行程单!例如: - **短期周末游**:从你所在的城市前往最近的火锅胜地(如重庆或成都)。 - **长假深度游**:结合多个目的地,探索不同风格的火锅文化。 --- 请告诉我更多细节,比如你想去的地方、出行时间和同伴情况,这样我可以进一步优化建议哦! -
第二轮对话输入示例
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. **行李打包建议**: - 带一双舒适的鞋子,因为需要较多步行。 - 上海冬天湿冷,记得带保暖衣物。 希望这个行程能让你在上海玩得开心,同时满足你对火锅的热爱!如果还有其他需求或者想要调整,请随时告诉我~
-