> ## Documentation Index
> Fetch the complete documentation index at: https://felimet-hub.jmcores.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 04-1 CLAUDE.md 與記憶檔：用途、最佳化、長度、格式

> CLAUDE.md 是 context，不是 enforced configuration。本單元拆解四種放置位置、跨任務複利篩選標準、模組化拆檔、自動記憶分工，以及各家工具的專案級指令檔命名對照。

export const ToolCompare = ({lang = "zh", tools = [], dimensions = [], defaultSelected, notes = []}) => {
  const UI = lang === "en" ? {
    allTools: "All",
    recommend: "Recommended",
    noSupport: "N/A",
    minOneToolW: "Select at least one tool",
    mobileLabel: "Tool",
    dimensionLbl: "Dimension",
    notes: "Notes"
  } : {
    allTools: "全選",
    recommend: "推薦",
    noSupport: "無對應",
    minOneToolW: "至少選一個工具",
    mobileLabel: "工具",
    dimensionLbl: "維度",
    notes: "注意事項"
  };
  const ACCENT_L = "#bf7551";
  const ACCENT_D = "#cf8a68";
  const REC_BDR_L = "rgba(191,117,81,0.45)";
  const REC_BG_L = "rgba(191,117,81,0.06)";
  const REC_BDR_D = "rgba(207,138,104,0.45)";
  const REC_BG_D = "rgba(207,138,104,0.08)";
  const looksLikePath = val => typeof val === "string" && (/[/\\.*:]/).test(val);
  const safeTools = Array.isArray(tools) ? tools : [];
  const safeDimensions = Array.isArray(dimensions) ? dimensions : [];
  if (safeTools.length === 0 || safeDimensions.length === 0) return null;
  const allIds = safeTools.map(t => t.id);
  const initSelected = Array.isArray(defaultSelected) && defaultSelected.length > 0 ? defaultSelected.filter(id => allIds.includes(id)) : allIds;
  const [selectedIds, setSelectedIds] = useState(initSelected.length > 0 ? initSelected : allIds);
  const [expandedCell, setExpandedCell] = useState(null);
  const [mobileTool, setMobileTool] = useState(initSelected[0] || allIds[0]);
  const [isDark, setIsDark] = useState(false);
  useEffect(() => {
    const detect = () => setIsDark(document.documentElement.classList.contains("dark"));
    detect();
    const obs = new MutationObserver(detect);
    obs.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class"]
    });
    return () => obs.disconnect();
  }, []);
  const toggleTool = id => {
    setSelectedIds(prev => {
      const next = prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id];
      if (next.length === 0) return prev;
      if (expandedCell) {
        const [, cellToolId] = expandedCell.split(":");
        if (!next.includes(cellToolId)) setExpandedCell(null);
      }
      return next;
    });
  };
  const isAllSelected = selectedIds.length === allIds.length;
  const toggleAll = () => {
    if (isAllSelected) {
      setSelectedIds([allIds[0]]);
    } else {
      setSelectedIds(allIds);
    }
    setExpandedCell(null);
  };
  const visibleTools = safeTools.filter(t => selectedIds.includes(t.id));
  const cellKey = (dimId, toolId) => dimId + ":" + toolId;
  const toggleExpand = (dimId, toolId) => {
    const key = cellKey(dimId, toolId);
    setExpandedCell(prev => prev === key ? null : key);
  };
  const renderValue = cell => {
    if (cell.na) {
      return <span className="tc-na">{UI.noSupport}</span>;
    }
    const useMono = cell.mono === true || cell.mono !== false && looksLikePath(cell.value);
    return useMono ? <code className="tc-code">{cell.value}</code> : <span>{cell.value}</span>;
  };
  const css = `
  /* ── 根容器 ── */
  .tc-root {
    --tc-bg:           #FAF8F3;
    --tc-surface:      rgba(0,0,0,0.022);
    --tc-stripe:       rgba(0,0,0,0.028);
    --tc-border:       rgba(0,0,0,0.09);
    --tc-text:         #2b2722;
    --tc-dim:          #6f6a62;
    --tc-faint:        #8a8378;
    --tc-accent:       ${ACCENT_L};
    --tc-accent-bg:    ${REC_BG_L};
    --tc-accent-bdr:   ${REC_BDR_L};
    --tc-expand-bg:    rgba(0,0,0,0.016);
    --tc-code-bg:      rgba(0,0,0,0.055);
    --tc-na-color:     #9a9490;
    --tc-pill-on-bg:   rgba(191,117,81,0.10);
    --tc-pill-on-bdr:  rgba(191,117,81,0.35);
    --tc-pill-on-txt:  #a05c38;
    border: 1px solid var(--tc-border);
    border-radius: 14px;
    background: var(--tc-bg);
    color: var(--tc-text);
    overflow: hidden;
    font-size: 14px;
  }
  .dark .tc-root {
    --tc-bg:           #1b1a18;
    --tc-surface:      rgba(255,255,255,0.03);
    --tc-stripe:       rgba(255,255,255,0.025);
    --tc-border:       rgba(255,255,255,0.08);
    --tc-text:         #e7e3da;
    --tc-dim:          #a8a299;
    --tc-faint:        #706b64;
    --tc-accent:       ${ACCENT_D};
    --tc-accent-bg:    ${REC_BG_D};
    --tc-accent-bdr:   ${REC_BDR_D};
    --tc-expand-bg:    rgba(255,255,255,0.022);
    --tc-code-bg:      rgba(255,255,255,0.08);
    --tc-na-color:     #6e6b65;
    --tc-pill-on-bg:   rgba(207,138,104,0.12);
    --tc-pill-on-bdr:  rgba(207,138,104,0.35);
    --tc-pill-on-txt:  ${ACCENT_D};
  }

  /* ── 精簡篩選列 ── */
  .tc-filter-bar {
    display: flex;
    align-items: center;
    gap: 0;
    padding: 0 14px;
    border-bottom: 1px solid var(--tc-border);
    background: var(--tc-surface);
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    /* 單行、不折行，高度由內容決定（約 36px） */
    flex-wrap: nowrap;
    white-space: nowrap;
    min-height: 36px;
  }
  .tc-filter-bar::-webkit-scrollbar { display: none; }

  /* 分隔竿（All 後面） */
  .tc-filter-sep {
    flex-shrink: 0;
    width: 1px;
    height: 14px;
    background: var(--tc-border);
    margin: 0 10px 0 6px;
    align-self: center;
  }

  /* pill 基底 — 極輕量文字標籤 */
  .tc-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 5px 9px;
    border-radius: 5px;
    border: 1px solid transparent;
    background: transparent;
    color: var(--tc-faint);
    font: inherit;
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.01em;
    cursor: pointer;
    transition: color 0.12s, background 0.12s, border-color 0.12s;
    flex-shrink: 0;
    white-space: nowrap;
    /* 行高對齊 filter-bar */
    margin: 5px 1px;
  }
  .tc-pill:hover {
    color: var(--tc-text);
    background: rgba(0,0,0,0.04);
  }
  .dark .tc-pill:hover {
    background: rgba(255,255,255,0.05);
  }
  /* 選中態：細框 + 淡底 + 文字加深（非按鈕感，保持輕量） */
  .tc-pill-on {
    color: var(--tc-pill-on-txt);
    background: var(--tc-pill-on-bg);
    border-color: var(--tc-pill-on-bdr);
    font-weight: 600;
  }
  /* 全選 pill — 略小一點字型 */
  .tc-pill-all {
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    padding: 4px 8px;
    color: var(--tc-dim);
  }
  .tc-pill-all.tc-pill-on {
    color: var(--tc-pill-on-txt);
  }
  /* 選中小圓點 */
  .tc-pill-dot {
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--tc-accent);
    flex-shrink: 0;
  }

  /* ── 桌面表格 ── */
  .tc-table-wrap {
    overflow: hidden;
  }
  /* Mintlify 的 MDX 渲染器會自動把 <table> 包進 data-table-wrapper：
   * 加 -mx-[var(--page-padding)] 負邊距 + w-[calc(100%+padding*2)] 全寬 + py-[1em]，
   * 讓表格往外溢出，撐破 tc-root 的圓角容器（2026-06-12 線上實證跑版）。
   * 中和它：邊距歸零、寬度收回 100%、把橫向捲動容器設在這層（sticky 左欄靠它）。 */
  .tc-root [data-table-wrapper] {
    margin: 0 !important;
    width: 100% !important;
    max-width: 100% !important;
    padding: 0 !important;
    overflow-x: auto;
    contain: none !important;
  }
  .tc-root [data-table-wrapper] > div {
    padding: 0 !important;
    margin: 0 !important;
  }
  .tc-root [data-table-wrapper]::-webkit-scrollbar { height: 4px; }
  .tc-root [data-table-wrapper]::-webkit-scrollbar-thumb { background: var(--tc-border); border-radius: 2px; }
  .tc-table {
    width: 100%;
    border-collapse: collapse;
    margin: 0 !important;
  }

  /* 表頭 */
  .tc-thead th {
    padding: 9px 15px;
    text-align: left;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--tc-faint);
    border-bottom: 2px solid var(--tc-border);
    background: var(--tc-surface);
    white-space: nowrap;
  }
  /* 維度欄（sticky 左欄） */
  .tc-thead th:first-child,
  .tc-td-dim {
    position: sticky;
    left: 0;
    z-index: 1;
  }
  .tc-thead th:first-child {
    width: 160px;
    min-width: 130px;
    background: var(--tc-surface);
    border-right: 1px solid var(--tc-border);
    z-index: 2;
  }

  /* 維度標籤欄 */
  .tc-td-dim {
    padding: 13px 15px;
    font-size: 12.5px;
    font-weight: 700;
    color: var(--tc-dim);
    vertical-align: middle;
    white-space: nowrap;
    border-bottom: 1px solid var(--tc-border);
    border-right: 1px solid var(--tc-border);
    background: var(--tc-surface);
  }

  /* 斑馬紋：奇數維度列 */
  .tc-row-even .tc-td-dim,
  .tc-row-even .tc-td {
    background-color: var(--tc-stripe);
  }
  .tc-row-even .tc-td-dim {
    background: color-mix(in srgb, var(--tc-surface) 70%, var(--tc-stripe) 30%);
  }

  /* 資料儲存格 */
  .tc-td {
    padding: 0;
    border-bottom: 1px solid var(--tc-border);
    border-left: 1px solid var(--tc-border);
    vertical-align: top;
    min-width: 150px;
  }
  .tc-td-inner {
    display: flex;
    flex-direction: column;
  }

  /* 主值行（可點擊） */
  .tc-cell-btn {
    display: flex;
    align-items: flex-start;
    gap: 6px;
    width: 100%;
    text-align: left;
    background: transparent;
    border: none;
    padding: 13px 15px;
    color: inherit;
    font: inherit;
    font-size: 13px;
    line-height: 1.5;
    cursor: pointer;
    transition: background 0.11s;
    -webkit-tap-highlight-color: transparent;
  }
  .tc-cell-btn:hover {
    background: rgba(0,0,0,0.03);
  }
  .dark .tc-cell-btn:hover {
    background: rgba(255,255,255,0.03);
  }
  .tc-cell-btn-on {
    background: var(--tc-expand-bg);
  }

  /* 推薦標記：左 3px accent 邊框 + 淡底 */
  .tc-td-recommend {
    border-left: 3px solid var(--tc-accent-bdr);
    background: var(--tc-accent-bg);
  }
  .tc-td-recommend .tc-cell-btn:hover {
    background: rgba(191,117,81,0.05);
  }

  /* recommend 角標：超小 badge */
  .tc-rec-badge {
    flex-shrink: 0;
    margin-top: 1px;
    font-size: 9px;
    font-weight: 700;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--tc-accent);
    border: 1px solid var(--tc-accent-bdr);
    border-radius: 3px;
    padding: 1px 4px;
    white-space: nowrap;
    opacity: 0.85;
  }

  /* na 樣式 */
  .tc-na {
    font-style: italic;
    color: var(--tc-na-color);
    font-size: 12.5px;
    opacity: 0.7;
  }

  /* 等寬值 */
  .tc-code {
    font-family: "JetBrains Mono", "Fira Code", "Cascadia Code", monospace;
    font-size: 12px;
    background: var(--tc-code-bg);
    border-radius: 3px;
    padding: 1px 4px;
    word-break: break-all;
  }

  /* 展開詳情列 */
  .tc-detail-row td {
    padding: 0;
    border-bottom: 1px solid var(--tc-border);
  }
  .tc-detail-cell {
    padding: 10px 15px 12px;
    font-size: 12.5px;
    line-height: 1.65;
    color: var(--tc-dim);
    background: var(--tc-expand-bg);
    border-top: 1px dashed var(--tc-border);
    border-left: 1px solid var(--tc-border);
  }
  .tc-detail-cell:first-child {
    border-left: none;
    font-weight: 700;
    color: var(--tc-faint);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    vertical-align: top;
    padding-top: 12px;
    background: var(--tc-surface);
    white-space: nowrap;
    width: 160px;
  }
  .tc-detail-recommend {
    border-left: 3px solid var(--tc-accent-bdr) !important;
    background: var(--tc-accent-bg) !important;
  }

  /* 展開箭頭 */
  .tc-chevron {
    flex-shrink: 0;
    margin-top: 3px;
    opacity: 0.35;
    transition: transform 0.14s, opacity 0.14s;
  }
  .tc-chevron-open {
    transform: rotate(90deg);
    opacity: 0.65;
  }

  /* ── 注腳 ── */
  .tc-notes {
    border-top: 1px solid var(--tc-border);
    padding: 10px 16px 12px;
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  .tc-notes-label {
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--tc-faint);
    margin-bottom: 3px;
  }
  .tc-note-item {
    font-size: 12.5px;
    color: var(--tc-dim);
    line-height: 1.55;
    padding-left: 14px;
    position: relative;
  }
  .tc-note-item::before {
    content: "*";
    position: absolute;
    left: 2px;
    color: var(--tc-faint);
  }

  /* ── 手機模式 ─────────────────────────────────────────── */
  .tc-mobile { display: none; }
  @media (max-width: 700px) {
    .tc-filter-bar { display: none; }
    .tc-table-wrap  { display: none; }
    .tc-mobile      { display: block; }

    .tc-mob-tabs {
      display: flex;
      overflow-x: auto;
      border-bottom: 1px solid var(--tc-border);
      -webkit-overflow-scrolling: touch;
      scrollbar-width: none;
    }
    .tc-mob-tabs::-webkit-scrollbar { display: none; }
    .tc-mob-tab {
      flex: 1 0 auto;
      padding: 10px 16px;
      background: transparent;
      border: none;
      border-bottom: 2px solid transparent;
      color: var(--tc-dim);
      font: inherit;
      font-size: 13px;
      font-weight: 500;
      cursor: pointer;
      white-space: nowrap;
      transition: color 0.12s, border-color 0.12s;
    }
    .tc-mob-tab-on {
      color: var(--tc-accent);
      border-bottom-color: var(--tc-accent);
      font-weight: 700;
    }
    .tc-mob-cards {
      padding: 12px 0 4px;
    }
    .tc-mob-card {
      border-bottom: 1px solid var(--tc-border);
      padding: 12px 16px;
    }
    .tc-mob-card:last-child { border-bottom: none; }
    .tc-mob-dim {
      font-size: 11px;
      font-weight: 700;
      letter-spacing: 0.05em;
      text-transform: uppercase;
      color: var(--tc-faint);
      margin-bottom: 6px;
    }
    .tc-mob-val {
      font-size: 13.5px;
      line-height: 1.55;
    }
    .tc-mob-rec {
      display: inline-block;
      margin-top: 6px;
      font-size: 9.5px;
      font-weight: 700;
      letter-spacing: 0.05em;
      text-transform: uppercase;
      color: var(--tc-accent);
      border: 1px solid var(--tc-accent-bdr);
      border-radius: 3px;
      padding: 1px 5px;
    }
    .tc-mob-detail {
      margin-top: 7px;
      font-size: 12.5px;
      line-height: 1.65;
      color: var(--tc-dim);
    }
    .tc-notes { padding: 11px 16px 13px; }
  }
  `;
  const renderDesktopTable = () => <div className="tc-table-wrap">
      <table className="tc-table">
        <thead className="tc-thead">
          <tr>
            <th>{UI.dimensionLbl}</th>
            {visibleTools.map(tool => <th key={tool.id}>{tool.label}</th>)}
          </tr>
        </thead>
        <tbody>
          {}
          {safeDimensions.flatMap((dim, dimIdx) => {
    const isAnyExpanded = visibleTools.some(t => expandedCell === cellKey(dim.id, t.id));
    const stripeClass = dimIdx % 2 === 1 ? " tc-row-even" : "";
    const rows = [];
    rows.push(<tr key={dim.id} className={"tc-row" + stripeClass}>
                <td className="tc-td-dim">{dim.label}</td>
                {visibleTools.map(tool => {
      const cell = (dim.cells || ({}))[tool.id] || ({});
      const key = cellKey(dim.id, tool.id);
      const isOpen = expandedCell === key;
      const hasDetail = !!cell.detail;
      const isRec = !!cell.recommend;
      return <td key={tool.id} className={"tc-td" + (isRec ? " tc-td-recommend" : "")}>
                      <div className="tc-td-inner">
                        <button type="button" className={"tc-cell-btn" + (isOpen ? " tc-cell-btn-on" : "")} onClick={hasDetail ? () => toggleExpand(dim.id, tool.id) : undefined} style={hasDetail ? {} : {
        cursor: "default"
      }} aria-expanded={hasDetail ? String(isOpen) : undefined}>
                          <span style={{
        flex: "1 1 0",
        minWidth: 0
      }}>
                            {renderValue(cell)}
                          </span>
                          {isRec && <span className="tc-rec-badge">{UI.recommend}</span>}
                          {hasDetail && <svg className={"tc-chevron" + (isOpen ? " tc-chevron-open" : "")} width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
                              <polyline points="9 18 15 12 9 6" />
                            </svg>}
                        </button>
                      </div>
                    </td>;
    })}
              </tr>);
    if (isAnyExpanded) {
      const openToolId = visibleTools.find(t => expandedCell === cellKey(dim.id, t.id))?.id;
      const openCell = openToolId ? (dim.cells || ({}))[openToolId] || ({}) : {};
      if (openCell.detail) {
        const openTool = safeTools.find(t => t.id === openToolId);
        const isRec = !!openCell.recommend;
        rows.push(<tr key={dim.id + "-detail"} className="tc-detail-row">
                    <td className="tc-detail-cell">
                      {openTool ? openTool.label : ""}
                    </td>
                    <td colSpan={visibleTools.length} className={"tc-detail-cell" + (isRec ? " tc-detail-recommend" : "")}>
                      {openCell.detail}
                    </td>
                  </tr>);
      }
    }
    return rows;
  })}
        </tbody>
      </table>
    </div>;
  const renderMobile = () => {
    const activeTool = safeTools.find(t => t.id === mobileTool) || safeTools[0];
    return <div className="tc-mobile">
        <div className="tc-mob-tabs" role="tablist">
          {safeTools.map(tool => <button key={tool.id} type="button" role="tab" aria-selected={tool.id === mobileTool ? "true" : "false"} className={"tc-mob-tab" + (tool.id === mobileTool ? " tc-mob-tab-on" : "")} onClick={() => setMobileTool(tool.id)}>
              {tool.label}
            </button>)}
        </div>

        <div className="tc-mob-cards">
          {safeDimensions.map(dim => {
      const cell = (dim.cells || ({}))[activeTool.id] || ({});
      const isRec = !!cell.recommend;
      return <div key={dim.id} className="tc-mob-card">
                <div className="tc-mob-dim">{dim.label}</div>
                <div className="tc-mob-val">{renderValue(cell)}</div>
                {isRec && <div className="tc-mob-rec">{UI.recommend}</div>}
                {cell.detail && <div className="tc-mob-detail">{cell.detail}</div>}
              </div>;
    })}
        </div>
      </div>;
  };
  return <div className="tc-root">
      <style>{css}</style>

      {}
      <div className="tc-filter-bar">
        <button type="button" className={"tc-pill tc-pill-all" + (isAllSelected ? " tc-pill-on" : "")} onClick={toggleAll} aria-pressed={String(isAllSelected)}>
          {UI.allTools}
        </button>

        {}
        <span className="tc-filter-sep" aria-hidden="true" />

        {safeTools.map(tool => {
    const isOn = selectedIds.includes(tool.id);
    return <button key={tool.id} type="button" className={"tc-pill" + (isOn ? " tc-pill-on" : "")} onClick={() => toggleTool(tool.id)} aria-pressed={String(isOn)}>
              {isOn && <span className="tc-pill-dot" aria-hidden="true" />}
              {tool.label}
            </button>;
  })}
      </div>

      {}
      {visibleTools.length > 0 && renderDesktopTable()}

      {}
      {renderMobile()}

      {}
      {notes.length > 0 && <div className="tc-notes">
          <div className="tc-notes-label">{UI.notes}</div>
          {notes.map((note, i) => <div key={i} className="tc-note-item">{note}</div>)}
        </div>}
    </div>;
};

export const LearnerPrimer = ({items = [], lang = "zh"}) => {
  const t = lang === "en" ? {
    title: "Before this unit, be honest with yourself",
    sub: "If you can't answer these, that gap is exactly what this unit closes."
  } : {
    title: "讀這個單元前，先誠實面對",
    sub: "這幾題答不出來，正是這個單元要替你補的洞。"
  };
  const css = `
  .lp-root{--lp-bg:#FAF7F1;--lp-surface:rgba(191,117,81,0.05);--lp-border:rgba(0,0,0,0.09);--lp-edge:rgba(191,117,81,0.42);--lp-text:#2b2722;--lp-dim:#6f6a62;--lp-accent:#bf7551;border:1px solid var(--lp-border);border-left:3px solid var(--lp-edge);border-radius:13px;background:var(--lp-bg);color:var(--lp-text);overflow:hidden;margin:1.25rem 0;}
  .dark .lp-root{--lp-bg:#1b1a18;--lp-surface:rgba(207,138,104,0.07);--lp-border:rgba(255,255,255,0.08);--lp-edge:rgba(207,138,104,0.5);--lp-text:#e7e3da;--lp-dim:#a8a299;--lp-accent:#cf8a68;}
  .lp-head{display:flex;align-items:center;gap:9px;padding:13px 18px 11px;border-bottom:1px solid var(--lp-border);background:var(--lp-surface);}
  .lp-ic{color:var(--lp-accent);flex-shrink:0;}
  .lp-htx{display:flex;flex-direction:column;gap:1px;min-width:0;}
  .lp-title{font-size:14px;font-weight:650;line-height:1.3;letter-spacing:.01em;}
  .lp-sub{font-size:12px;color:var(--lp-dim);line-height:1.4;}
  .lp-list{list-style:none;margin:0;padding:10px 18px 14px;display:flex;flex-direction:column;gap:0;}
  .lp-item{display:flex;align-items:baseline;gap:11px;padding:7px 0;font-size:14px;line-height:1.6;border-top:1px solid var(--lp-border);}
  .lp-item:first-child{border-top:none;}
  .lp-mark{flex-shrink:0;color:var(--lp-accent);font-size:13px;font-weight:700;line-height:1.55;font-variant-numeric:tabular-nums;opacity:.85;}
  .lp-q{flex:1 1 0;min-width:0;color:var(--lp-text);}
  @media (max-width:620px){.lp-head{padding:12px 14px 10px;}.lp-list{padding:8px 14px 12px;}}
  `;
  return <div className="lp-root">
      <style>{css}</style>
      <div className="lp-head">
        <svg className="lp-ic" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="12" r="10" /><circle cx="12" cy="12" r="6" /><circle cx="12" cy="12" r="2" /></svg>
        <span className="lp-htx">
          <span className="lp-title">{t.title}</span>
          <span className="lp-sub">{t.sub}</span>
        </span>
      </div>
      <ul className="lp-list">
        {items.map((q, i) => <li className="lp-item" key={i}>
            <span className="lp-mark">{String(i + 1).padStart(2, "0")}</span>
            <span className="lp-q">{q}</span>
          </li>)}
      </ul>
    </div>;
};

<LearnerPrimer
  lang="zh"
  items={[
"CLAUDE.md 是 context，不是 enforced configuration",
"你寫了三百行，模型多半只記三行",
"「跨任務複利」不是口號，是篩選器",
"機密寫進 CLAUDE.md 進版控，下次 commit 就是外洩",
"你寫的是祈使句還是描述句，遵從度差好幾倍",
"不可信內容進自動記憶，三週後你才發現它在帶風向",
"自動記憶是 agent 自己寫給未來自己的事實筆記",
]}
/>

<Info>
  **這個單元解決什麼問題**

  `CLAUDE.md` 是每個 session 起手自動注入的常駐指令，是你給 agent 的「常識」。寫太長吃 context、寫太空沒約束力。本單元拆解它的載入時機、覆寫層級、最佳長度與模組化結構，並把指令型 `CLAUDE.md` 與事實型自動記憶的分工講清楚，最後對照各家工具的專案級指令檔命名。
</Info>

## 學習目標

* [ ] 說出 `CLAUDE.md` 的四種放置位置（managed / user / project / local）與其載入優先序。
* [ ] 用「跨任務複利」篩選標準判斷哪些內容該進 `CLAUDE.md`、哪些不該。
* [ ] 用 `@path` 匯入語法與 `.claude/rules/` 路徑範圍把規則模組化，避免單一巨型檔案。
* [ ] 分清 `CLAUDE.md`（指令型）與自動記憶（事實型）的差異，並識別記憶污染的風險與處置。
* [ ] 對應 OpenAI Codex、Google Antigravity、GitHub Copilot、Cursor 等工具的專案級指令檔名。

***

## 1. `CLAUDE.md` 是什麼、何時載入

`CLAUDE.md` 是放在磁碟上的純文字 Markdown 檔。Claude Code 在每個 session 開頭讀進來，作為使用者訊息注入到對話脈絡中。讀進來之後，它就跟你說的每一句話一起佔用 context window 的 token 預算。

兩個關鍵事實先記起來：

* 它是 **context**，不是 enforced configuration。Claude 會「試著遵守」，但遇到衝突或遺漏時沒有硬保證。硬保證機制見第 8 節 Hook 的保證執行差異。
* 它是 **每次 session 都全量注入** 的常駐訊息，不像 Skill 是按需載入（見 [04-4 Skill](/code-agent/customization/skills)）。所以寫每一行都要算 token 帳。

<Tip>
  **用 `/init` 起步最快**

  在一個新專案目錄裡跑 `/init`，Claude Code 會自動掃你的 codebase、產生一份起手 `CLAUDE.md`（建構指令、測試流程、專案慣例）。它讀的是「可以被機械推斷的事」，你再依領域知識補上「它推斷不出但每次都要交代」的規則。
</Tip>

## 2. 放置位置與覆寫層級

Claude Code 在啟動時會依下列順序尋找並載入 `CLAUDE.md`（截至 2026-06，依官方記憶章節 \[1]）：

| 範疇             | 位置                                                                                                                                               | 用途                         | 誰會看到                |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------- | ------------------- |
| Managed policy | macOS `/Library/Application Support/ClaudeCode/CLAUDE.md`、Linux/WSL `/etc/claude-code/CLAUDE.md`、Windows `C:\Program Files\ClaudeCode\CLAUDE.md` | 組織級強制規範（資安、編碼標準、合規）        | 全組織機器               |
| 使用者級           | `~/.claude/CLAUDE.md`                                                                                                                            | 個人跨專案偏好（縮排、工具捷徑、語言）        | 只有你                 |
| 專案級            | `./CLAUDE.md` 或 `./.claude/CLAUDE.md`                                                                                                            | 團隊共用的專案慣例                  | 透過版控共享給團隊           |
| 本地覆寫           | `./CLAUDE.local.md`                                                                                                                              | 個人在本專案的私有設定（沙盒 URL、本機測試資料） | 只有你，加進 `.gitignore` |

<Warning>
  **載入順序不是「覆寫」**

  多個檔案是**串接**進 context，不是後者覆蓋前者。從 root 往工作目錄的順序串接，本地檔最後讀。`CLAUDE.md` 與 `CLAUDE.local.md` 在同一層時，本地檔附加在後。意思是：寫在某個資料夾下的 `CLAUDE.md`，會被任何在它子目錄啟動的 session 一起讀進來。
</Warning>

Managed policy 是組織發布、不可被個人關閉的；個人與專案層的 `CLAUDE.md` 則可用 `claudeMdExcludes` 排除特定檔案（任何設定層皆可設，陣列跨層合併），這在大型 monorepo 裡避免「別的團隊的 `CLAUDE.md` 污染你」很實用；但 Managed policy 的 `CLAUDE.md` 無法被排除 \[1]。

## 3. 該寫什麼、不該寫什麼：跨任務複利原則

篩選標準只有一個：**一條規則如果下次 session 還會用得到，就寫進來；只用一次的就別寫。** 用這個標準可以快速過濾掉 80% 的候選內容。

適合放進 `CLAUDE.md` 的：

* **角色與語言**：第二人稱、回應語言、術語表。
* **編碼風格**：縮排、命名、引號風格、模組拆分慣例。
* **建構與測試指令**：`make test`、`uv run pytest`、`pnpm lint` 這類。
* **專案結構與邊界**：「API 處理器在 `src/api/handlers/`」「不要動 `dist/`」。
* **禁則**：「不要改 `migrations/` 既有檔案」「不要 commit 任何 `.env`」。
* **常用工作流**：「修完 bug 先跑 `make lint` 再 commit」。

不該放進來的：

* 一次性任務細節（「幫我把 PR #1234 接上 main」）。
* 頻繁變動的版本號、套件名單（這些會過期，且應由 lockfile 管）。
* 機密（API key、密碼、token）。`CLAUDE.md` 進版控，機密應在 `.env` 與 `.gitignore` 處理。
* 冗長背景（超過一頁的專案沿革、設計理念）。背景應在對話脈絡裡傳入，而不是常駐。
* 屬於另一條主軸的內容：多步程序、跨檔重構 SOP、發版流程，拆成 Skill（見 [04-4 Skill](/code-agent/customization/skills)）。

<Note>
  **寫「祈使句」而不是「描述」**

  `CLAUDE.md` 對模型來說是「該遵守的事」，不是「專案介紹」。同樣的內容，祈使句版本比描述句版本效果好數倍。

  不要：「我們的測試使用 pytest 框架，跑在 Python 3.11+ 環境，主要用 fixture 與 parametrize...」（描述）

  寫成：「跑測試用 `uv run pytest`，單一測試檔案用 `uv run pytest path/to/test_x.py -k name`」（祈使）

  祈使句讓模型更容易抽取出「該做什麼」。
</Note>

## 4. 長度與 token 預算

Anthropic 官方對 `CLAUDE.md` 的長度建議是 **每個檔案 200 行以內** \[1]。不是硬限制，但有兩個理由：

1. **adherence 會掉**。檔案越長，模型在多輪對話後記住並遵循的規則比例越低；越簡短越一致。
2. **每次 session 都在燒 token**。`CLAUDE.md` 載入後就不會從 context 移除（除非你手動 `/compact` 並重新觸發載入），寫得越長，後續每次互動都付同樣成本。

如果一條規則**只在某個子目錄或副檔名**才需要，把它拆到 `.claude/rules/<topic>.md` 並用 `paths` frontmatter 限定（見 [04-2 rules](/code-agent/customization/rules)）；這樣它不會在所有 session 全量載入，只在 Claude 觸及對應檔案時才讀。

<Note>
  **真實成本：200 行 vs 800 行的差異**

  假設 `CLAUDE.md` 約 200 行、平均每行 25 token，單次 session 起手就吃掉 5,000 token 靜態開銷。同一份內容膨脹到 800 行，變成 20,000 token；在 200k 脈絡視窗下，800 行版本永遠先少掉約 7.5% 的對話空間。Claude Opus 4.5 單次輸入成本高，800 行版本一年下來可多付數百美元；這還不包含 adherence 下降帶來的回頭修正成本。
</Note>

### 結構化分段

把段落用 Markdown 標題明確分組，並避免大段散文。模型會掃結構，把同一主題的規則集中放在一個 `##` 標題下，比把規則散落在三段散文裡更穩定。

<Note>
  **區塊註解會被剝除**

  官方在載入 `CLAUDE.md` 前會把 `<!-- ... -->` 形式的 HTML 區塊註解移除 \[1]。意思是：你可以留給人類維護者的註解（例如「這段來自 2026-04 的 linting 討論」），它不會佔 token。code block 內的註解不會被剝。直接用 Read 工具開啟 `CLAUDE.md` 時，註解仍然可見，被移除的只是注入給模型的那份。
</Note>

## 5. 模組化：避免單一巨檔

兩種正交工具可以幫你拆檔。

### 5.1 用 `@path` 匯入

`CLAUDE.md` 內可以用 `@path/to/import` 語法匯入其他檔案 \[1]：

```text theme={null}
# CLAUDE.md
See @README for project overview and @package.json for available npm commands.

# Coding standards
- Python style: @docs/python-style.md
- API design: @docs/api-conventions.md
```

規則：

* 相對路徑以**含 `@` 的檔案**為基準，不是當前工作目錄。
* 匯入可遞迴，最深 4 層。
* 匯入的檔案**在 session 啟動時也一起全量載入**，所以 `@` 匯入是組織結構用，不是省 token 用。要省 token 請用 `.claude/rules/` 的 path-scoped 機制。
* 第一次使用外部匯入時，Claude Code 會跳信任核取對話框；按拒絕後該專案就停用匯入 \[1]。

<Tip>
  **跨工作流共享個人偏好**

  如果你有多個 git worktree，把個人跨 worktree 共用的偏好放在 `~/.claude/my-project-instructions.md`，然後在每個 worktree 的 `CLAUDE.md` 用 `@~/.claude/my-project-instructions.md` 引用，省去重複編輯。
</Tip>

### 5.2 拆到 `.claude/rules/`

當某條規則**只在特定副檔名或子目錄**才需要，把整個規則拆到 `.claude/rules/<topic>.md` 並用 `paths` frontmatter 限定觸達範圍（見 [04-2 rules](/code-agent/customization/rules)）。`.claude/rules/` 內的檔案**不寫 `paths` 時**與 `CLAUDE.md` 等價，都會在 session 啟動時全量載入；寫了 `paths` 之後只在 Claude 觸及符合 glob 的檔案時才載入。

<Tabs>
  <Tab title="拆分前（單檔膨脹，320 行）">
    ```markdown theme={null}
    # 角色與語言（20 行）
    # 建構與測試（30 行）
    # Python 編碼風格（120 行）
    # API 設計規範（80 行）
    # 前端 React 規範（70 行）
    ```

    每次 session 啟動，這 320 行全量注入。
  </Tab>

  <Tab title="拆分後（只載必要）">
    ```text theme={null}
    CLAUDE.md            # 50 行：角色、語言、建構、測試、全域禁則
    .claude/rules/
      python-style.md    # 120 行，paths: ["**/*.py"]
      api-design.md      # 80 行，paths: ["src/api/**"]
      react-style.md     # 70 行，paths: ["src/components/**/*.{ts,tsx}"]
    ```

    每次 session 啟動只花 50 行的成本；改 Python 檔時多載 120 行、改 API 時多載 80 行。「只在相關時載入」是把 token 用在刀口上的關鍵。
  </Tab>
</Tabs>

## 6. 自動記憶：事實型記憶

`CLAUDE.md` 是你寫給 Claude 的**指令**。自動記憶是 Claude 自己寫給未來自己的**事實筆記** \[1]。兩者並用：

|     | `CLAUDE.md`   | 自動記憶                                                           |
| --- | ------------- | -------------------------------------------------------------- |
| 誰寫  | 你             | Claude 自己                                                      |
| 內容  | 指令、規則、慣例      | 觀察到的事實：建構指令、除錯心得、發現的偏好                                         |
| 範疇  | 專案、使用者、組織     | 依 git repo（同一 repo 的所有 worktree 與子目錄共享；不在 git repo 內時以專案根目錄為鍵） |
| 載入  | 每次 session 全量 | 每次 session 載入 `MEMORY.md` 前 200 行或 25KB（取先達），topic 檔按需         |
| 適用於 | 編碼標準、工作流、專案結構 | 建構指令、除錯觀察、Claude 從對話裡學到的偏好                                     |

儲存位置：`~/.claude/projects/<project>/memory/`，裡面有 `MEMORY.md` 索引檔與多個 topic 檔（`debugging.md`、`api-conventions.md` 等）\[1]。這是**機器本地**的，不跨機器、不同步雲端，跨 worktree 但同 repo 會共享。

啟用條件：Claude Code v2.1.59 以上 \[1]。預設開啟；用 `/memory` 命令或在 `settings.json` 設 `autoMemoryEnabled: false` 關閉；用環境變數 `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1` 也可關。要改上述預設儲存位置，用 `settings.json` 的 `autoMemoryDirectory`（吃絕對路徑或 `~/` 前綴；設在專案或 local 層需先通過 workspace 信任對話才生效）\[1]。

<Warning>
  **自動記憶是雙刃**

  Claude 會依「未來對話是否還用得到」決定要不要寫。它寫進去的東西你可能不想要（例如把某次你口頭實驗的怪招當成偏好記下來）。`/memory` 命令可以瀏覽、開啟、編輯、刪除記憶檔。把它當成你自己寫的筆記：定期 review 一次。
</Warning>

## 7. 記憶污染：自動記憶的供應鏈風險

外部內容進到 agent 後被寫進自動記憶，下個 session 載入時它就影響行為，這就是**記憶污染**。具體攻擊面見 [03-3 安全、隱私與供應鏈風險](/code-agent/judgment/security-privacy-supply-chain)，這裡只點與本單元有關的處置：

* **不可信內容的工作流結束後**清除或輪替 `~/.claude/projects/<project>/memory/` 的內容。
* **定期 review 自動記憶**：跑 `/memory` 開啟資料夾，至少掃一眼 `MEMORY.md` 與各 topic 檔。
* **機密不該進自動記憶**：Claude 可能把你貼過的 API key、token 寫進去。`MEMORY.md` 是純文字本機檔，沒有加密；備份或同步時它就一起走。

## 8. 與 Hook 的分工：`CLAUDE.md` 是「請你遵守」，Hook 是「強制執行」

`CLAUDE.md` 是 context，被模型在生成回應時參考；遇到「不要 commit `.env`」這種禁則，模型可能在長鏈任務裡漏掉。**Hook 才是硬保證**（見 [04-6 Hooks](/code-agent/customization/hooks)）：

* `CLAUDE.md`：「不要 commit `.env` 檔案」，模型多半會記得，但偶爾會漏。
* Hook（PreToolUse on Bash）：`Bash(git commit *)` 觸發時，shell 端檢查 staged 檔案含 `.env` 就 exit code 2 中斷，任何時候都擋下。

判準：需要模型「記得」就寫 `CLAUDE.md`；需要「不論如何都擋下來」就寫 Hook。

## 9. 工具對照：各家專案級指令檔

`AGENTS.md` 已成為多家工具原生支援的跨工具共通專案規則檔，由 Linux Foundation 下的 Agentic AI Foundation 維護，截至 2026-06 已被 60,000+ 開源專案採用（採用面與治理主張的來源是 \[4]，非 Anthropic 官方文件）。Claude Code 原生讀的是 `CLAUDE.md`，但可以 `@AGENTS.md` 匯入進來 \[1]。

<Note>
  **官方說法：Claude 讀 `CLAUDE.md`，不讀 `AGENTS.md`**

  Anthropic 官方記憶章節的原文是：「Claude Code 讀取 `CLAUDE.md`，而不是 `AGENTS.md`。如果您的儲存庫已經為其他編碼代理使用 `AGENTS.md`，請建立一個 `CLAUDE.md` 來匯入它，以便兩個工具讀取相同的指令而不重複。」來源：Claude Code 記憶章節 AGENTS.md 段（官方）（截至 2026-06）\[1]。

  官方給的最小作法：`CLAUDE.md` 第一行 `@AGENTS.md` 匯入，下面再接 Claude 專屬指令；若不需要 Claude 專屬內容，`ln -s AGENTS.md CLAUDE.md` 符號連結也行。Windows 建符號連結需系統管理員權限或開發者模式，所以官方建議在 Windows 上改用 `@AGENTS.md` 匯入。
</Note>

<ToolCompare
  lang="zh"
  tools={[
{ id: "claude", label: "Claude Code" },
{ id: "codex",  label: "OpenAI Codex" },
{ id: "gemini", label: "Google Gemini CLI" },
{ id: "copilot",label: "GitHub Copilot" },
{ id: "cursor", label: "Cursor" },
]}
  dimensions={[
{
  id: "user-instr",
  label: "使用者級指令",
  cells: {
    claude:  { value: "~/.claude/CLAUDE.md",                       recommend: true },
    codex:   { value: "~/.codex/AGENTS.md" },
    gemini:  { value: "~/.gemini/GEMINI.md、~/.gemini/AGENTS.md" },
    copilot: { value: "~/.copilot/copilot-instructions.md" },
    cursor:  { value: "User Rules（GUI）", detail: "Cursor 使用者級規則透過 GUI 設定，無對應設定檔路徑。" },
  },
},
{
  id: "proj-instr",
  label: "專案級指令",
  cells: {
    claude:  { value: "./CLAUDE.md、.claude/CLAUDE.md",            recommend: true },
    codex:   { value: "./AGENTS.md" },
    gemini:  { value: "./GEMINI.md、./AGENTS.md、.agent/rules/" },
    copilot: { value: ".github/copilot-instructions.md、.github/instructions/*.instructions.md、AGENTS.md" },
    cursor:  { value: ".cursor/rules/*.mdc", detail: "副檔名必須是 .mdc，.md 無效。frontmatter 欄位為 description / globs / alwaysApply。" },
  },
},
{
  id: "local-override",
  label: "本地覆寫",
  cells: {
    claude:  { value: "./CLAUDE.local.md",                         recommend: true, detail: "加進 .gitignore，個人本機沙盒設定的標準位置。" },
    codex:   { value: "CLI flags", detail: "Codex 以 CLI 選項覆寫設定，無對等本地檔層。" },
    gemini:  { value: "以工作區為準" },
    copilot: { value: "以個人層為主" },
    cursor:  { value: "無對等本地層", na: false },
  },
},
{
  id: "modular",
  label: "模組化分檔",
  cells: {
    claude:  { value: ".claude/rules/*.md（path-scoped）",          recommend: true, detail: "paths frontmatter 限定 glob，只在相關檔案時載入，是省 token 的核心機制。" },
    codex:   { value: "AGENTS.md、AGENTS.override.md" },
    gemini:  { value: "多檔 .agent/rules/ 與 GEMINI.md" },
    copilot: { value: ".instructions.md 多檔 + applyTo glob" },
    cursor:  { value: ".mdc 多檔分檔", detail: "alwaysApply: true 無條件載入；globs 設定時自動載入；只有 description 時由模型語意判斷；都不寫只能 @-mention 手動引用。" },
  },
},
{
  id: "cross-tool",
  label: "跨工具共通層",
  cells: {
    claude:  { value: "讀 CLAUDE.md；@AGENTS.md 匯入可用",          detail: "官方建議：CLAUDE.md 第一行 @AGENTS.md，下面再接 Claude 專屬指令。" },
    codex:   { value: "AGENTS.md 原生" },
    gemini:  { value: "AGENTS.md 原生" },
    copilot: { value: "AGENTS.md 原生" },
    cursor:  { value: "AGENTS.md 原生" },
  },
},
{
  id: "auto-memory",
  label: "自動記憶",
  cells: {
    claude:  { value: "~/.claude/projects/<repo>/memory/（v2.1.59+）", recommend: true, detail: "Claude 自己寫的事實筆記，依 git repo 共享。/memory 命令可瀏覽、編輯、刪除。" },
    codex:   { value: "以 AGENTS.md 為常駐指令，無專屬事實型記憶" },
    gemini:  { value: "Memory（帳號側）", detail: "Google Gemini 的記憶儲存在帳號端，非本機 git repo 對應。" },
    copilot: { na: true },
    cursor:  { na: true },
  },
},
{
  id: "enforcement",
  label: "強制執行保證",
  cells: {
    claude:  { value: "Hook（PreToolUse / PostToolUse）",            recommend: true, detail: "Hook 是硬保證：exit code 2 中斷工具呼叫，任何時候都擋下，不依賴模型記住規則。" },
    codex:   { value: "Codex hooks" },
    gemini:  { value: "Antigravity workflow" },
    copilot: { value: "Copilot hooks（preview）" },
    cursor:  { value: "無同等機制" },
  },
},
]}
  notes={[
"Claude Code 讀 CLAUDE.md，不讀 AGENTS.md，除非用 @AGENTS.md 匯入。",
"Google Gemini CLI 目前無 gemini mcp add 的正式 CLI，建議直接編輯 settings.json（截至 2026-06）。",
"Cursor 為第三方 IDE（Anysphere），本 Playbook 僅短提一欄。",
]}
/>

<Note>
  **命名澄清**

  本表「主範本」欄採官方現用命名。Claude Code 對應的常駐指令檔是 `CLAUDE.md`（不是 `AGENTS.md`）；但若專案已有 `AGENTS.md`，可用 `@AGENTS.md` 匯入讓 Claude 也讀它。Google Antigravity 讀 `GEMINI.md` 與 `AGENTS.md`，兩者的優先序各來源說法不一，詳見 [02-6 其他工具對照](/code-agent/configuration/other-tools-comparison)。Cursor 為第三方 IDE（Anysphere），本 Playbook 僅短提一欄。
</Note>

## 10. 自我檢核動手做

<Steps>
  <Step title="刪減">
    把現有 `CLAUDE.md`（如果有）的每一條用「跨任務複利」標準過濾，刪掉只對一次性任務有用的。比較刪前刪後行數。
  </Step>

  <Step title="拆分">
    把 Python 或前端編碼風格（若超過 30 行）抽到 `.claude/rules/<lang>-style.md`，加 `paths` frontmatter 限定。
  </Step>

  <Step title="本機層">
    把個人本機才需要的設定（沙盒 URL、測試資料位置）搬到 `CLAUDE.local.md` 並加進 `.gitignore`。
  </Step>

  <Step title="驗證">
    在同一個工作目錄用 `claude` 啟動，跑 `/memory` 檢查所有該載入的檔案都在清單上。
  </Step>

  <Step title="trust 對話框">
    第一次用 `@path` 匯入外部檔案時，會跳信任核取。決定好策略：要全專案信任、還是要個別檔案放行。
  </Step>
</Steps>

## 11. 常見誤區

<Warning>
  **反模式清單**

  * **照抄別人的 `CLAUDE.md`**：別人的慣例反映別人的工作流。照抄會引入你不需要的約束，甚至安全風險（見 [03-3 安全、隱私與供應鏈風險](/code-agent/judgment/security-privacy-supply-chain)）。先看骨架，再依自己的工作流改寫。
  * **`CLAUDE.md` 越寫越長，層層疊加自相矛盾**：模型在衝突時會**任選其一**，你可能不知道。多檔疊加後定期 review、刪掉過期規則。
  * **把「保證執行」寫成祈使句**：需要 hook 強制的事寫在 `CLAUDE.md`，模型可能漏；需要確定性保證的場合見 [04-6 Hooks](/code-agent/customization/hooks)。
  * **把 `.env` 寫進 `CLAUDE.md`**：它進版控，機密就不機密了。機密放 `.env` 與 `.gitignore`。
  * **跨工具照抄單一一個檔名**：Claude 不讀 `AGENTS.md`（除非你 `@` 匯入），GitHub Copilot 不讀 `CLAUDE.md`。跨工具時，請用 `AGENTS.md` 作為共通底盤，工具特定設定各自加掛。
</Warning>

## 自我檢核

<Check>
  **通過本單元的標準**

  1. 你能在 1 分鐘內說出 `CLAUDE.md` 的四種放置位置、載入順序，以及哪一種可以關閉、哪一種不行嗎？
  2. 你能對自己 `CLAUDE.md` 裡的每一條，說出「刪掉會有什麼後果」嗎？說得出的留，說不出的刪。
  3. 你能說出「這條該進 `CLAUDE.md`、`.claude/rules/`、Skill 還是 Hook」的判準嗎？
  4. 你知道自動記憶存哪、怎麼看、怎麼清嗎？
</Check>

## 來源與延伸閱讀

事實主張依官方文件，快變動項標註截至 2026-05。

<div className="references">
  * \[1] Anthropic, "How Claude remembers your project," code.claude.com, 2026. \[Online]. Available: [https://code.claude.com/docs/en/memory](https://code.claude.com/docs/en/memory) （截至 2026-06）

  * \[2] Anthropic, "Extend Claude with skills," code.claude.com, 2026. \[Online]. Available: [https://code.claude.com/docs/en/skills](https://code.claude.com/docs/en/skills) （截至 2026-06；含 Skill 與指令機制整合說明）

  * \[3] Cursor, "Rules," cursor.com, 2026. \[Online]. Available: [https://cursor.com/docs/context/rules](https://cursor.com/docs/context/rules) （截至 2026-06；`.mdc` 與 `globs` frontmatter 機制）

  * \[4] Agentic AI Foundation (Linux Foundation), "AGENTS.md, a simple, open format for guiding coding agents," 2026. \[Online]. Available: [https://agents.md/](https://agents.md/) （截至 2026-06；60,000+ 開源專案採用、支援工具完整清單見該頁）
</div>

* 設定層級模型見 [02-1 設定的層級模型](/code-agent/configuration/config-layer-model)。
* Hook 強制執行見 [04-6 Hooks](/code-agent/customization/hooks)。
* 規則檔 path-scoped 機制見 [04-2 rules](/code-agent/customization/rules)。
* Skill（按需載入的程序）見 [04-4 Skill](/code-agent/customization/skills)。
* 自動記憶的供應鏈風險見 [03-3 安全、隱私與供應鏈風險](/code-agent/judgment/security-privacy-supply-chain)。
