项目记忆
多轮任务里,模型每次从零读仓库很慢,也容易重复踩坑。项目记忆让你在仓库维度沉淀「怎么写、别碰什么、为何这么定」——下次 run() 时,符合条件的条目会自动注入 system prompt,相当于给 Agent 一份持续更新的项目小抄。
本篇示例依赖第 01 篇的环境变量:CODY_MODEL=qwen3.5-plus、CODY_MODEL_API_KEY、CODY_MODEL_BASE_URL=https://coding.dashscope.aliyuncs.com/v1。客户端使用 AsyncCodyClient(workdir="..."),不显式传 model。
完整示例:写入、读取与清除
下面脚本演示四条不同分类的 add_memory、用 get_memory 按类遍历,以及可选的 clear_memory。先跑通一遍,后面各节再拆开说明字段与存储规则。
import asyncio from cody import AsyncCodyClient async def main(): async with AsyncCodyClient(workdir=".") as client: # 写入四类记忆(至少覆盖三种分类) await client.add_memory( category="conventions", content="Python 使用 ruff,行宽 100;公开函数必须有类型注解。", confidence=0.9, tags=["lint", "style"], ) await client.add_memory( category="patterns", content="异步测试使用 pytest.mark.asyncio;文件操作用 tmp_path。", confidence=0.85, tags=["pytest", "async"], ) await client.add_memory( category="issues", content="sub_agent 模块顶部不能直接导入 _execute,需延迟导入避免循环依赖。", confidence=0.95, tags=["gotcha"], ) await client.add_memory( category="decisions", content="新工具先在 core 实现,经 SDK 暴露,再在 CLI/Web 引用——禁止 core 反向依赖上层。", confidence=0.9, tags=["architecture"], ) # 读取:按分类拿到列表 memory = await client.get_memory() # 结构: {"conventions": [...], "patterns": [...], "issues": [...], "decisions": [...]} # 每条含 content / confidence / tags / created_at 等字段 for cat in ("conventions", "patterns", "issues", "decisions"): items = memory.get(cat) or [] print(f"=== {cat} ({len(items)} 条) ===") for row in items: print(row["content"], "|", row["confidence"], row["tags"]) # 清空当前 workdir 下的全部项目记忆(按需取消注释) # await client.clear_memory() asyncio.run(main())
四类记忆分别是什么
写入时必须使用下面四个 category 字符串之一。可以把它理解成「书架上的四个格子」,方便模型与人类检索。
| 分类 | 适合放什么 | 示例一句话 |
|---|---|---|
conventions | 格式、命名、Lint、文档风格等团队约定 | 「行宽 100,import 顺序交给 ruff」 |
patterns | 可复用的实现套路、测试写法、目录习惯 | tmp_path 做文件测试、异步用 pytest.mark.asyncio |
issues | 已知坑、易错 API、历史事故 | 某模块不能顶层 import,否则会循环依赖 |
decisions | 架构或流程上的 ADR 式结论 | 新功能路径:core → SDK → Web/CLI |
add_memory 参数
与 SDK 一致的签名如下:category、content 为位置参数;confidence、tags 等为关键字参数(另有 source_task_id / source_task_title 可选,用于标注来源任务)。
await client.add_memory( category="conventions", # "conventions" | "patterns" | "issues" | "decisions" content="规范内容描述", confidence=0.9, # 0.0–1.0;过低不会注入 prompt(见下文) tags=["lint", "style"], )
| 参数 | 说明 |
|---|---|
category | 四类之一,见上表。 |
content | 自然语言描述,建议一句一意,便于淘汰旧条时仍可读。 |
confidence | 0.0–1.0;低于 0.3 的条目不会注入 system prompt。 |
tags | 字符串列表,便于你本地筛选或后续扩展过滤逻辑。 |
get_memory 返回值
await client.get_memory() 返回一个字典,键为四个分类名,值为该分类下的条目列表。每条记录至少包含:
content(str)confidence(float)tags(list)created_at(str)
实现里还可能包含 id 等字段,遍历时代码用 row.get("id") 即可。
memory = await client.get_memory() # {"conventions": [...], "patterns": [...], "issues": [...], "decisions": [...]} for cat, rows in memory.items(): for row in rows: print(cat, row["content"], row["confidence"], row["tags"], row["created_at"])
存储与注入规则:文件落在 ~/.cody/memory/<md5(workdir)>/,按 workdir 隔离不同仓库。每次 run() 时,框架会把符合条件的记忆自动拼进 system prompt。每个分类最多保留 50 条,超出时淘汰最旧的条目。置信度小于 0.3 的条目不会注入 prompt(仍会写入存储,除非你自行清理)。
clear_memory
clear_memory 会删除当前 workdir 在本地存储中的全部四类记忆,且无内置「撤销」。执行前请确认已备份或确实需要重置。
需要换仓、重置实验或误写入大量噪声时,可一次性清空当前客户端对应 workdir 下的全部项目记忆:
await client.clear_memory()
清除后下一次 run() 将不再携带此前的记忆注入,直到你再次 add_memory。
场景:新人入职,用模型总结规范并写入记忆
可以让 qwen3.5-plus 先阅读 CONTRIBUTING.md / CLAUDE.md(通过对话说明路径),再把结论拆成多条 add_memory。下面是一种极简编排:一次 run() 收集摘要,脚本里把要点固化进 conventions 与 decisions(实战中也可让模型输出 JSON 再解析)。
import asyncio from cody import AsyncCodyClient async def onboard(): async with AsyncCodyClient(workdir=".") as client: r = await client.run( "阅读 CONTRIBUTING.md 与 CLAUDE.md,用三条要点概括代码风格与提交流程,不要改文件。" ) print("模型摘要:\n", r.output) # 将已确认的规范写入记忆,供后续所有任务复用 await client.add_memory( category="conventions", content="贡献指南要求:ruff + mypy,提交信息用英文祈使句。", confidence=0.85, tags=["onboarding", "docs"], ) await client.add_memory( category="decisions", content="文档与代码同步更新;合并前必须跑通测试与 lint。", confidence=0.8, tags=["onboarding", "process"], ) asyncio.run(onboard())
若只想记录「不确定的猜测」,可把 confidence 设为 0.2 等:仍会占用存储与条数配额,但不会污染后续 run() 的 system prompt。
小结
你现在已经会把项目知识拆成 conventions / patterns / issues / decisions,用 add_memory 写入、get_memory 读出,并了解存储目录、run() 自动注入、每类 50 条上限与低置信度过滤;需要重置时调用 clear_memory 即可。下一篇「人机协同」将介绍如何在自动化流程中插入人工确认与审批。