回顧解決問題的會話。產出兩個檔案:LEARNED.md 和 learned_quiz.py(一個終端機測驗)。
- 識別會話。使用最近的對話來找出與問題相符的對話。如果有多個合理的對話,請詢問使用者是哪一個。如果該會話屬於某個專案,也要回顧該專案中的其他對話。
- 閱讀整個會話,而不只是摘要。記錄在問題解決前,人類和 AI 各自遺漏了什麼。同時記錄人類必須憑信心接受、問過不止一次、或理解錯誤的概念:這些需要深入探討。
- 在撰寫之前先研究連結。為每個教訓找到至少一個連結。對於每個人類教訓,以及步驟 2 中的任何概念,找到 1 到 3 個深入探討的鏈接,從基本原理解釋背景。優先選擇(依序):官方文件或規格、供應商應用說明或手冊、知名教程或教科書,然後是信譽良好的部落格或問答。使用 WebSearch,然後使用 WebFetch 打開每個鏈接以確認其載入並涵蓋要點。放棄任何失敗或離題的鏈接。切勿編造 URL。
- 依序撰寫具有以下章節的 LEARNED.md:
- 發生什麼事:3 到 5 個句子,加上狀態(已解決或未解決)。如果未解決,列出未完成事項。
- 學到的教訓:分為人類、AI 和共享。對於每個教訓,給出要點、遺漏了什麼、用一句話總結教訓,以及一個連結(指名來源)。在每個需要背景知識的人類教訓下,添加一個「深入探討」子列表:每個條目為 標題、來源,以及一行關於它教導了什麼以及為何在此處有幫助的說明。
- 測驗問題:3 到 5 個關鍵問題,標題為「測驗問題」,後面接著解答鍵。請注意,完整的問題集在 learned_quiz.py 中。
- 連結:所使用的每個連結,按教訓分組,並指名來源。說明鏈接已在執行日期檢查,使用前應再次驗證。
- 建議的一次性提示:一個簡潔的提示,可以避免本次會話中的問題。
- 標註聲明。將未經證實的聲明標記為未經證實。將來自搜尋結果的聲明標記為已報告,並連結來源。
- 不要將猜測呈現為發現。如果問題的原因未經確認,請這樣說。
- 根據下面的模板撰寫 learned_quiz.py。規則:
- 僅使用 Python 3 標準庫。必須能在 macOS、Linux 和 Windows 終端機上執行。沒有 GUI。
- 涵蓋每個概念,而不僅僅是 3 到 5 個測驗問題:每個人類教訓至少 2 個問題,每個 AI 和共享教訓至少 1 個問題,加上每個深入探討概念至少 1 個問題。通常為 10 到 25 個問題。混合記憶題、「你會先檢查什麼」題,以及「找出錯誤」題。
- 每個問題:主題(人類、AI、共享或簡短的概念名稱)、4 個選項(包含合理的干擾項)、正確索引、1 到 2 句解釋原因,以及最相關的已驗證連結。
- 只填入 TITLE、SOURCE 和 QUESTIONS。不要更改引擎。
- 在發送前,執行 python3 -c "import ast,sys;ast.parse(open(sys.argv[1]).read())" learned_quiz.py,然後執行 python3 learned_quiz.py --list,並修正任何錯誤。檢查每個答案索引是否指向正確的選項。
- 保持 LEARNED.md 簡潔。不要在任一檔案中使用 em dash。
- 使用 SendUserFile 發送兩個檔案。在回覆中提供執行命令:python3 learned_quiz.py(選項:-r 快閃卡複習,-t TOPIC 過濾,-n N 限制,--list 列印全部,--seed N 固定順序)。
測驗模板(完全複製,替換佔位符和範例問題):
#!/usr/bin/env python3
"""LEARNED 問答:<主題>。執行:python3 learned_quiz.py [-r] [-t 主題] [-n N] [--list]"""
import argparse, random, sys, textwrap
TITLE = "<主題>"
SOURCE = "LEARNED.md, <日期>"
QUESTIONS = [
{"topic": "Human", "q": "範例問題?",
"choices": ["正確答案", "錯誤答案1", "錯誤答案2", "錯誤答案3"], "answer": 0,
"why": "一兩句解釋原因。", "link": "https://example.com"},
]
def wrap(s, ind=" "):
return textwrap.fill(s, 78, initial_indent=ind, subsequent_indent=ind)
def ask(prompt, valid):
while True:
try:
a = input(prompt).strip().lower()
except (EOFError, KeyboardInterrupt):
print(); sys.exit(0)
if a in valid:
return a
def run(qs, review):
missed = []
for i, q in enumerate(qs, 1):
order = list(range(len(q["choices"])))
random.shuffle(order)
letters = "abcdefgh"[:len(order)]
print(f"\n[{i}/{len(qs)}] ({q['topic']})")
print(wrap(q["q"], ""))
for L, idx in zip(letters, order):
print(wrap(f"{L}) {q['choices'][idx]}"))
right = letters[order.index(q["answer"])]
if review:
if ask(" 按 Enter 揭示,按 q 離開:", {"", "q"}) == "q":
sys.exit(0)
ok = True
else:
a = ask(f" 答案 [{letters}],按 q 離開:", set(letters) | {"q"})
if a == "q":
break
ok = a == right
print(" 正確。" if ok else f" 不對。答案:{right}")
if review or not ok:
print(wrap(f"{right}) {q['choices'][q['answer']]}"))
print(wrap(q["why"]))
if q.get("link"):
print(wrap("更多資訊:" + q["link"]))
if not ok:
missed.append(q)
return missed
def main():
p = argparse.ArgumentParser(description=f"問答:{TITLE}")
p.add_argument("-r", "--review", action="store_true", help="快閃卡模式,不計分")
p.add_argument("-t", "--topic", help="僅限此主題(Human, AI, Shared, ...)")
p.add_argument("-n", type=int, help="最多提問 N 個問題")
p.add_argument("--list", action="store_true", help="列印所有問答並退出")
p.add_argument("--seed", type=int, help="固定隨機順序")
a = p.parse_args()
random.seed(a.seed)
qs = [q for q in QUESTIONS if not a.topic or q["topic"].lower() == a.topic.lower()]
if not qs:
sys.exit(f"沒有主題為 {a.topic!r} 的問題。")
if a.list:
for i, q in enumerate(qs, 1):
print(f"{i}. ({q['topic']}) {q['q']}\n{wrap('A: ' + q['choices'][q['answer']])}\n{wrap(q['why'])}")
if q.get("link"):
print(wrap("更多資訊:" + q["link"]))
return
random.shuffle(qs)
qs = qs[:a.n] if a.n else qs
print(f"{TITLE}\n來源:{SOURCE}\n共 {len(qs)} 個問題。")
while qs:
missed = run(qs, a.review)
if a.review:
break
print(f"\n分數:{len(qs) - len(missed)}/{len(qs)}")
if not missed or ask("重練答錯的題目?[y/n]:", {"y", "n"}) == "n":
for q in missed:
print(wrap(f"複習:{q['q']}", "- ") + ("\n" + wrap(q["link"]) if q.get("link") else ""))
break
qs = missed
if __name__ == "__main__":
main()