文档中心 / SDK 教程 / 进阶篇

项目记忆

多轮任务里,模型每次从零读仓库很慢,也容易重复踩坑。项目记忆让你在仓库维度沉淀「怎么写、别碰什么、为何这么定」——下次 run() 时,符合条件的条目会自动注入 system prompt,相当于给 Agent 一份持续更新的项目小抄。

本篇示例依赖第 01 篇的环境变量:CODY_MODEL=qwen3.5-plusCODY_MODEL_API_KEYCODY_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 一致的签名如下:categorycontent 为位置参数;confidencetags 等为关键字参数(另有 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自然语言描述,建议一句一意,便于淘汰旧条时仍可读。
confidence0.01.0;低于 0.3 的条目不会注入 system prompt。
tags字符串列表,便于你本地筛选或后续扩展过滤逻辑。

get_memory 返回值

await client.get_memory() 返回一个字典,键为四个分类名,值为该分类下的条目列表。每条记录至少包含:

实现里还可能包含 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() 收集摘要,脚本里把要点固化进 conventionsdecisions(实战中也可让模型输出 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 即可。下一篇「人机协同」将介绍如何在自动化流程中插入人工确认与审批。

← 上一篇 事件与可观测性