技术教程 · 阅读约 9 分钟

Vibe Coding 不崩的秘诀:用 AI 自动生成"项目记忆",让 Claude 永远记得你的架构决策

Vibe Coding 不崩的秘诀:用 AI 自动生成"项目记忆",让 Claude 永远记得你的架构决策

你有没有遇到过这种情况:

项目跑了两个月,某天你让 AI 帮你加个新功能,它给你写出来的代码风格和你之前的完全不一样,甚至绕开了你三周前专门为这个场景设计的工具函数。

这不是 AI 变笨了,是它根本不知道你的项目"长什么样"。

每次新开对话,模型的记忆清零,它看到的只是你粘贴进去的那几百行代码。它不知道你为什么选 Prisma 不选 Drizzle,不知道那个奇怪的 utils/retry.ts 是有意设计的,更不知道你的错误处理约定。

Vibe coding 项目后期崩溃,80% 的原因不是 AI 不行,是上下文管理没做好。


解决方案:给项目写一份"AI 可读的记忆"

核心思路很简单:用脚本扫描你的项目,自动生成一份结构化的 CONTEXT.md,每次和 AI 对话时把它塞进 system prompt。AI 就有了"项目长期记忆"。

下面这套脚本我在实际项目里用了快半年,效果稳定。


第一步:自动扫描项目,生成结构摘要


import os

import json

from pathlib import Path

from openai import OpenAI



# 用无量 API,国内直连,比官方便宜 60%+

client = OpenAI(

    api_key="your_api_key_here",

    base_url="https://api2everything.xyz/v1"

)



def collect_project_files(root: str, extensions: list[str], max_files: int = 40) -> dict:

    """收集项目关键文件内容,过滤掉 node_modules / dist 等噪音"""

    result = {}

    skip_dirs = {".git", "node_modules", "dist", "__pycache__", ".next", "build", "venv"}



    for path in Path(root).rglob("*"):

        if any(part in skip_dirs for part in path.parts):

            continue

        if path.suffix in extensions and path.is_file():

            try:

                content = path.read_text(encoding="utf-8", errors="ignore")

                # 超长文件只取前 120 行,避免撑爆 token

                lines = content.splitlines()[:120]

                result[str(path.relative_to(root))] = "\n".join(lines)

            except Exception:

                continue

        if len(result) >= max_files:

            break



    return result



def generate_project_context(project_root: str = ".") -> str:

    """让 Claude 读懂你的项目,生成一份给 AI 看的记忆文件"""



    files = collect_project_files(

        project_root,

        extensions=[".ts", ".tsx", ".py", ".js", ".json", ".md", ".prisma"]

    )



    # 构建给模型看的文件树

    file_tree = "\n".join(f"- {f}" for f in files.keys())

    file_contents = "\n\n".join(

        f"### {fname}\n```\n{content}\n```"

        for fname, content in list(files.items())[:25]  # 取前 25 个最重要的

    )



    prompt = f"""你是一个资深架构师,正在阅读一个真实项目的代码。



项目文件列表:

{file_tree}



部分关键文件内容:

{file_contents}



请生成一份简洁的「项目上下文记忆」,格式如下:



## 技术栈

(列出主要依赖和版本)



## 目录结构约定

(说明各目录的职责)



## 核心设计决策

(列出 3-5 个关键的架构或代码约定,例如错误处理方式、状态管理方案、API 调用约定)



## 常用工具函数

(列出已有的 utils / hooks / helpers,避免 AI 重复造轮子)



## AI 协作注意事项

(生成新代码时必须遵守的规范)



要求:

- 不超过 600 字

- 每条都要具体,能直接指导 AI 写代码

- 不要废话"""



    response = client.chat.completions.create(

        model="claude-sonnet-4-5",  # 或 gpt-4.1,看你的预算

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

        max_tokens=1200,

        temperature=0.3

    )



    return response.choices[0].message.content



if __name__ == "__main__":

    print("正在分析项目结构...")

    context = generate_project_context(".")



    # 保存到项目根目录

    output_path = Path("CONTEXT.md")

    output_path.write_text(f"# 项目 AI 记忆\n\n> 此文件由脚本自动生成,每次大改动后重新运行\n\n{context}", encoding="utf-8")



    print(f"✅ 已生成 CONTEXT.md({len(context)} 字符)")

    print("\n--- 预览 ---")

    print(context[:500])


第二步:把"记忆"注入到每次对话

生成了 CONTEXT.md 之后,关键是每次和 AI 对话都要带上它。下面是一个简单的封装:


def ask_with_context(user_question: str, context_file: str = "CONTEXT.md") -> str:

    """带项目记忆的 AI 对话"""



    context = ""

    if Path(context_file).exists():

        context = Path(context_file).read_text(encoding="utf-8")



    system_prompt = f"""你是这个项目的资深开发者,对项目架构了如指掌。



{context}



---

回答问题时:

1. 优先复用项目里已有的工具函数和约定

2. 新代码的风格要和现有代码保持一致

3. 如果你不确定某个细节,直接说,不要瞎猜"""



    response = client.chat.completions.create(

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

        messages=[

            {"role": "system", "content": system_prompt},

            {"role": "user", "content": user_question}

        ],

        max_tokens=2000,

        temperature=0.2

    )



    return response.choices[0].message.content



# 使用示例

answer = ask_with_context("帮我给 /api/user 路由加一个限流中间件")

print(answer)


第三步:建立"决策日志",让记忆不断累积

光有代码扫描还不够。有些关键决策是在对话里做出来的,不会留在代码里。建议在项目里加一个 DECISIONS.md,每次做了重要的技术选型就手动记一条:


## 2025-07-14 选择 Zustand 而不是 Redux

原因:项目规模不大,Redux 的 boilerplate 太重。Zustand 的 store 都放在 src/store/ 下,

禁止在组件里直接 mutate。



## 2025-07-10 API 错误处理约定

所有 API 调用都通过 src/utils/request.ts 的 safeRequest 封装,

它会统一处理 401 跳转和错误 toast,不要在组件里单独 catch。

把这个文件也加进 collect_project_files 的扫描范围,AI 就能知道你"踩过哪些坑、做过哪些妥协"。


实际效果

按这套流程跑下来,我的项目在第三个月加新功能时,AI 第一次给出的代码和已有风格吻合度明显提升,返工次数大幅减少。

真正让 vibe coding 稳定的不是模型有多聪明,是你给它的上下文有多准确。


关于 API 费用

上面的脚本每次运行大概消耗 5000-8000 token,用 Claude Sonnet 4.5 的话成本极低。我直接用的无量API(api2everything.xyz),国内直连不需要任何代理,300+ 模型统一接入,比官方便宜 60% 以上,改一行 base_url 就能用,注册还送 ¥1 余额。跑这类日常工具脚本完全够用。


有什么具体项目结构想适配的,或者脚本跑起来遇到问题,评论区聊。觉得有用的话点个赞,我后面会继续写 AI 辅助开发的实战系列。