本文最后更新于 2026-05-23,文章内容可能已经过时。

用 Claude API 从零搭一个记住你习惯的私人 AI 助手

你有没有算过,你这辈子跟 AI 说了多少次"我不喜欢用'首先其次最后'"?

我数了一下,大概是 47 次。每次让 Claude 或 ChatGPT 帮我写东西,都要在开头贴一段"说明书":我是做产品的、偏好简洁直接的语气、段落不要超过三行、禁止用任何排比句……说完这段话,AI 才算真正"认识了我"。

然后对话窗口一关,下次又是陌生人。

这不是 AI 的问题,是所有 AI 产品的架构通病——每个对话都是独立的,没有跨会话的记忆。ChatGPT 的 Memory 功能是个例外,但它是黑箱,你不知道它记了什么、怎么用的。

今天这篇文章要做的事很简单:用不到 100 行 Python,给 Claude 装上一个透明可控的记忆系统,让它真正记住你是谁、你喜欢什么、你的工作习惯是什么。

不需要懂机器学习,不需要搭数据库,只需要一个 Claude API Key 和一点点耐心。

为什么 AI 总是"失忆"?

先花两分钟搞清楚原理,后面动手会顺很多。

大语言模型的工作方式是这样的:你给它一段文字(叫做 context),它预测下一个词。它没有持久化存储,每次对话的"记忆"完全依赖你传给它的 context 内容。

这意味着,如果你想让 AI 记住你的偏好,本质上就是一件事:在每次对话开始时,把你的偏好信息塞进 context 里。

具体有三种实现路径:

| 方案 | 优点 | 缺点 | 适用场景 | | System Prompt 注入 | 最简单,零依赖 | 只能存少量结构化信息 | 个人使用,偏好记忆 | | 外部文件存储 | 可持久化,可编辑 | 需要手动维护 | 本文选择方案 | | 向量数据库检索 | 可存海量内容,语义检索 | 搭建成本高 | 企业级/内容记忆场景 |

本文选择 "结构化 JSON 文件 + 动态 System Prompt 拼接" 这条路。理由很实在:零额外依赖、完全透明可控、你随时可以打开 JSON 文件直接编辑自己的画像。

💡 Claude 的 context window 上限是 200K tokens,相当于一本 30 万字的中文小说。对于存储个人偏好画像这种场景,完全绰绰有余——一份写得很详细的用户画像,也不过几千个 token。

数据流长这样:

用户输入

读取本地 profile.json(用户画像)

将画像拼接进 System Prompt

发送给 Claude API

Claude 生成回复

判断:这次对话有没有透露新的偏好信息?

有 → 更新 profile.json → 写回本地

没有 → 直接结束

整个系统的核心就是这个循环。接下来我们一步步把它实现出来。

动手实操:30 分钟搭出来

第一步:获取 Claude API 密钥 + 环境配置

💡 国内用户获取 Claude API 的最快路径

>

直接访问 [api.884819.xyz](https://api.884819.xyz) 注册,无需解决网络问题,支持调用 Claude 全系列模型(包括 claude-opus-4claude-sonnet-4-5),本文所有代码均在该平台测试通过。新用户注册即送体验 token,跑完本教程的额度完全够用。

拿到 API Key 之后,安装依赖:

pip install anthropic

就这一个包,没有其他依赖。

第二步:建立你的用户画像 JSON

在项目目录下创建 profile.json,这是整个系统的"记忆核心":

{

"name": "Alex",

"profession": "产品经理",

"writing_style": {

"tone": "简洁直接,不废话",

"paragraph_length": "每段不超过3行",

"forbidden_phrases": ["首先", "其次", "最后", "综上所述", "不难看出"],

"preferred_format": "短句为主,必要时用列表"

},

"language_preference": "中文,偶尔用英文术语",

"work_context": {

"industry": "互联网,To B SaaS",

"common_tasks": ["写周报", "整理会议纪要", "分析竞品", "写PRD"],

"team_size": "10人左右的产品团队"

},

"personal_preferences": {

"likes": ["数据驱动的分析", "有结论的建议", "类比举例"],

"dislikes": ["套话", "模糊的建议", "过度正面的语气"]

},

"last_updated": "2025-01-01"

}

这个 JSON 就是你的"AI 身份证"。字段可以按需增减,关键是把你真正在乎的偏好写进去。

第三步:动态拼接 System Prompt

# prompt_builder.py

import json

from datetime import date

def load_profile(path="profile.json") -> dict:

"""加载用户画像,文件不存在时返回空画像"""

try:

with open(path, "r", encoding="utf-8") as f:

return json.load(f)

except FileNotFoundError:

return {}

def build_system_prompt(profile: dict) -> str:

"""将用户画像转换为 System Prompt"""

if not profile:

return "你是一个通用 AI 助手。"

# 核心:把结构化数据转成自然语言指令

prompt = f"""你是 {profile.get('name', '用户')} 的私人 AI 助手。

【关于用户】

  • 职业:{profile.get('profession', '未知')}
  • 工作背景:{profile.get('work_context', {}).get('industry', '未知')}
  • 常用语言:{profile.get('language_preference', '中文')}

【写作风格要求】(每次回复都必须遵守)

  • 语气:{profile.get('writing_style', {}).get('tone', '正常')}
  • 段落长度:{profile.get('writing_style', {}).get('paragraph_length', '适中')}
  • 禁止使用的词汇:{', '.join(profile.get('writing_style', {}).get('forbidden_phrases', []))}
  • 格式偏好:{profile.get('writing_style', {}).get('preferred_format', '正常')}

【用户偏好】

  • 喜欢:{', '.join(profile.get('personal_preferences', {}).get('likes', []))}
  • 不喜欢:{', '.join(profile.get('personal_preferences', {}).get('dislikes', []))}

请始终以符合上述偏好的方式回答,不需要在回复中提及这些设定。"""

return prompt

这段代码只做一件事:把 JSON 里的结构化数据,翻译成 Claude 能理解的自然语言指令。

第四步:主对话循环

# main.py

import json

import anthropic

from datetime import date

from prompt_builder import load_profile, build_system_prompt

client = anthropic.Anthropic(

api_key="你的API密钥",

base_url="https://api.884819.xyz" # 使用8848AI平台

)

def save_profile(profile: dict, path="profile.json"):

"""将更新后的画像写回文件"""

profile["last_updated"] = str(date.today())

with open(path, "w", encoding="utf-8") as f:

json.dump(profile, f, ensure_ascii=False, indent=2)

def check_and_update_profile(user_input: str, profile: dict) -> dict:

"""

让 Claude 判断用户输入是否包含新的偏好信息

如果有,返回更新后的画像;否则返回原画像

"""

update_prompt = f"""分析以下用户输入,判断是否包含用户偏好、习惯或背景信息的更新。

用户输入:"{user_input}"

当前用户画像:

{json.dumps(profile, ensure_ascii=False, indent=2)}

如果用户输入包含新的偏好信息(比如"我不喜欢..."、"以后帮我..."、"我是做...的"等),

请返回更新后的完整 JSON 画像。

如果没有新信息,只返回字符串 "NO_UPDATE"。

只返回 JSON 或 "NO_UPDATE",不要有其他内容。"""

response = client.messages.create(

model="claude-sonnet-4-5",

max_tokens=1000,

messages=[{"role": "user", "content": update_prompt}]

)

result = response.content[0].text.strip()

if result == "NO_UPDATE":

return profile

try:

updated_profile = json.loads(result)

print("✅ 检测到偏好更新,已自动保存到画像")

return updated_profile

except json.JSONDecodeError:

return profile # 解析失败时保留原画像

def chat():

"""主对话循环"""

profile = load_profile()

conversation_history = []

name = profile.get('name', '你')

print(f"你好,{name}!我已加载你的个人画像,开始对话吧。输入 'quit' 退出。\n")

while True:

user_input = input("你:").strip()

if user_input.lower() == 'quit':

print("再见!你的偏好已自动保存。")

break

if not user_input:

continue

# 每次对话前重新加载画像(支持实时更新)

profile = load_profile()

system_prompt = build_system_prompt(profile)

# 将用户输入加入对话历史

conversation_history.append({

"role": "user",

"content": user_input

})

# 发送请求

response = client.messages.create(

model="claude-sonnet-4-5",

max_tokens=2000,

system=system_prompt,

messages=conversation_history

)

assistant_reply = response.content[0].text

conversation_history.append({

"role": "assistant",

"content": assistant_reply

})

print(f"\nClaude:{assistant_reply}\n")

# 异步判断是否需要更新画像

updated_profile = check_and_update_profile(user_input, profile)

if updated_profile != profile:

save_profile(updated_profile)

if __name__ == "__main__":

chat()

运行这段代码,当 Claude 第一次用你偏好的语气、叫着你的名字回答你时——那个感觉,真的有点不一样。

进阶玩法:让记忆更聪明

基础版已经能用了,但还有三个方向可以继续打磨。

1. 按场景分类记忆

一个人在工作和生活中的语气需求完全不同。可以在 profile.json 里加一个 modes 字段:

{

"modes": {

"work": {

"tone": "专业简洁",

"forbidden_phrases": ["哈哈", "感觉", "好像"]

},

"life": {

"tone": "轻松随意",

"forbidden_phrases": ["综上所述", "数据显示"]

}

},

"current_mode": "work"

}

build_system_prompt 里根据 current_mode 动态选择对应的风格配置,对话中输入 /work/life 切换模式。

2. 记忆的"遗忘机制"

画像积累久了会越来越乱,互相矛盾的偏好会让 AI 无所适从。可以加一个定期清理函数:

def clean_profile(profile: dict) -> dict:

"""让 Claude 整理并精简画像,去除冗余和矛盾项"""

clean_prompt = f"""以下是用户的 AI 助手画像,请帮我整理:

1. 合并重复或相似的条目

2. 删除互相矛盾的设定(保留更新的那条)

3. 精简措辞,保持简洁

原始画像:

{json.dumps(profile, ensure_ascii=False, indent=2)}

返回整理后的完整 JSON,不要有其他内容。"""

# ... 调用 API 并解析返回结果

建议每隔 30 次对话自动触发一次,或者在 profile.json 里记录 conversation_count 来追踪。

3. 对话摘要压缩

conversation_history 积累很长时,可以定期让 Claude 把历史对话压缩成摘要,避免 context 过长:

def compress_history(history: list) -> list:

"""将超过20轮的对话历史压缩为摘要"""

if len(history) <= 20:

return history

# 保留最近10轮,把更早的压缩成摘要

old_history = history[:-10]

recent_history = history[-10:]

# 让 Claude 总结旧对话

summary = summarize_conversation(old_history)

return [{"role": "user", "content": f"[对话摘要] {summary}"},

{"role": "assistant", "content": "好的,我已了解之前的对话背景。"}] + recent_history

踩坑记录:这三个报错你大概率会遇到

报错 1:AuthenticationError

anthropic.AuthenticationError: Error code: 401 - {'type': 'error', 'error': {'type': 'authentication_error', 'message': 'invalid x-api-key'}}
原因:API Key 填错了,或者忘记设置 base_url解决:检查 Key 是否完整复制(注意不要有空格),并确认 base_url 指向正确的平台地址。

报错 2:JSON 解析失败

json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
原因check_and_update_profile 函数里,Claude 有时会在 JSON 前后加上 markdown 代码块标记( `json ` ),导致直接 json.loads() 失败。 解决:在解析前清理一下:
result = result.strip()

if result.startswith("

"):

result = result.split("``")[1]

if result.startswith("json"):

result = result[4:]

result = result.strip()


报错 3:画像更新死循环

现象:每次对话都触发画像更新,哪怕你只是说了句"好的"。 原因
check_and_update_profile 的判断提示词写得太宽泛,Claude 过于积极地"发现"新偏好。 解决:在提示词里加一条约束:

只有当用户明确表达偏好(使用"我喜欢/不喜欢/以后/帮我记住"等明确意图词)时才更新。

日常对话、问答、闲聊一律返回 "NO_UPDATE"。

``

这套方案的边界在哪里

说实话,这个方案是有局限的。

JSON 文件适合存储结构化的偏好信息:语气风格、职业背景、禁忌词汇……这些东西几百个字段就能描述清楚。

但如果你想让 AI 记住的是非结构化的内容——你写过的所有文章、读过的所有资料、过去一年的会议记录——JSON 就力不从心了。你不可能把一年的文档都塞进 System Prompt,context window 再大也有上限,而且每次都全量传输,成本和延迟都不可接受。

这套方案今天能解决 80% 的个人使用场景。剩下那 20%,需要另一套武器。

文中所有代码可在 [api.884819.xyz](https://api.884819.xyz) 申请密钥后直接运行,新用户注册后有免费额度可以完整跑完本教程。

下一篇预告 👇

>

本文的记忆方案用 JSON 文件存储,适合记住几十条偏好。
但如果你想让 AI 记住的不是几条习惯,而是你过去一年写过的所有文档、读过的所有文章——
JSON 就不够用了。

>

下一篇我们会把这套系统升级:接入向量数据库,让 Claude 拥有真正的长期语义记忆,实现"你随口一提,它就能翻出三个月前你说过的那句话"。

>

关注我,不要错过。
本文由8848AI原创,转载请注明出处。关注8848AI,带你从零开始学AI。

#AI教程 #Claude #Python #AI助手 #Prompt技巧 #8848AI #人工智能 #开发者工具