Install
openclaw skills install @po-et/lessons-learned-logopenclaw skills install @po-et/lessons-learned-log定位一句话:记录本身不值钱,开工前真的去查才值钱。 把每次出错、返工、被纠正变成一条下次能搜到、能照做的记录。适用于 AI 助手的长期协作,也适用于人自己的工作笔记。
出现下面任何一种,当场记一条,不等「有空再整理」:
不用记:纯手滑的错别字、一次性且不会再遇到的环境问题、总结不出可照做动作的事。
先查的时机:开始一项以前做过同类的任务之前;执行发送、删除、覆盖、付款这类不可撤销的动作之前;用户提到「上次那个问题」时。
一坑一条,以 ### 开头,字段各占一行,脚本按字段检索:
### 交付文件只写了相对路径,用户找不到
- 关键词:路径, 文件位置, 交付, 链接
- 触发场景:把报告、表格、网页结果交给用户时
- 现象:用户回复「report.html 在哪?打不开」
- 根因:默认用户和我在同一个目录,实际不在
- 正确做法:交付物一律写完整路径,如 /Users/xiaowang/周报/report.html
- 验证方式:交付前把路径粘到文件管理器地址栏,能直接打开
- 类别:被用户纠正(第 2 次)
- 最后验证:2026-09-19
- 状态:有效
写法要求:现象写可观察的事实(原话、报错原文);根因写「为什么会这样」,不写「粗心」;正确做法写成下次能照做的动作,带具体值;验证方式写怎么确认做对了;类别写被纠正、返工、报错或差点出事,括号里记第几次;状态只用「有效」「存疑」「已过时:原因」三种。
存放:纯文本 Markdown,放固定目录——个人用 ~/lessons/,项目用项目根目录下的 lessons/。按主题分文件,如 文件与路径.md、写作与格式.md、日程与时间.md;新主题先放 杂项.md,攒够 5 条再拆出去;单个文件超过约 30 条再拆。
把下面的脚本存成 lessons_search.py,只用 Python 标准库:
"""按关键词检索踩坑记录;加 --stale 90 列出 90 天没复核的条目。"""
import argparse, datetime, pathlib, re
def entries(root):
for f in sorted(pathlib.Path(root).expanduser().rglob("*.md")):
text = f.read_text(encoding="utf-8", errors="replace")
for block in re.split(r"(?m)^(?=### )", text):
if block.startswith("### "):
yield f.name, block.strip()
def field(block, name):
m = re.search(r"(?m)^- %s[::]\s*(.*)$" % name, block)
return m.group(1).strip() if m else ""
ap = argparse.ArgumentParser()
ap.add_argument("root")
ap.add_argument("words", nargs="*")
ap.add_argument("--stale", type=int, help="只列最后验证早于 N 天的条目")
ap.add_argument("--all", action="store_true", help="连「已过时」的一起列")
a = ap.parse_args()
hits = []
for fname, block in entries(a.root):
if "已过时" in field(block, "状态") and not a.all:
continue
if a.stale is not None:
d = re.search(r"\d{4}-\d{2}-\d{2}", field(block, "最后验证"))
age = (datetime.date.today() - datetime.date.fromisoformat(d.group())).days if d else 9999
if age <= a.stale:
continue
key = (block.splitlines()[0] + field(block, "关键词") + field(block, "触发场景")).lower()
score = sum(block.lower().count(w.lower()) + 2 * key.count(w.lower()) for w in a.words)
if score or not a.words:
hits.append((score, fname, block))
for score, fname, block in sorted(hits, key=lambda h: -h[0]):
print(f"[{score}] {fname} | {block.splitlines()[0][4:]} | {field(block, '状态')} {field(block, '最后验证')}")
print(f" 正确做法:{field(block, '正确做法')}")
print(f" 验证方式:{field(block, '验证方式')}")
print(f"共 {len(hits)} 条" if hits else "没有相关记录")
开工前:
python3 lessons_search.py ~/lessons 路径 交付 周报。方括号里是得分,命中标题、关键词、触发场景的会额外加分。出错后:
每月一次,或每新增 20 条做一次:
python3 lessons_search.py ~/lessons --stale 90,列出 90 天没复核的条目;--all 才显示;