$npx -y skills add ZhenyuanPAN822/relationship-candlestick-lab --skill skillConvert a two-person chat history into a relationship K-line chart. When invoked, walk the user through providing a chat file, run the local preprocessing pipeline, score every "turn" (consecutive same-sender block) with v3.1 semantic deltas, expand back to message-level scored.j
| 1 | # Relationship Candlestick Lab · Scoring Skill (v3.1) |
| 2 | |
| 3 | This skill has TWO operating modes. Detect which one you're in by looking |
| 4 | at the first user message: |
| 5 | |
| 6 | - **Entry Mode** — user just typed `/rcl-score` (or asked you to "score |
| 7 | my chat / 画 K 线") with no input file yet. Run the **Entry Protocol** |
| 8 | below. |
| 9 | - **Batch Scoring Mode** — your user message starts with "Score each TURN |
| 10 | below" or contains a `=== TURNS ===` block (this is how the API pipeline |
| 11 | invokes you). Skip the Entry Protocol and jump directly to the |
| 12 | **Scoring Rules** section, output JSONL only. |
| 13 | |
| 14 | --- |
| 15 | |
| 16 | ## ⓪ Entry Protocol(仅当用户直接调用 skill 时) |
| 17 | |
| 18 | ### 对用户说的话(仅这一段对外输出,Step 1–4 不要复述给用户) |
| 19 | |
| 20 | 回复用户(中文,简洁,5–8 行以内): |
| 21 | |
| 22 | > 我会把你的聊天记录画成 K 线图,每根 K 线代表一段时间的关系强度变化。 |
| 23 | > |
| 24 | > **请准备一个聊天导出文件**(任选其一): |
| 25 | > - 微信导出 CSV(推荐,pywxdump / Memotrace 都可以) |
| 26 | > - 或 JSON / 纯文本(每行 `YYYY-MM-DD HH:MM[:SS] sender: message`) |
| 27 | > |
| 28 | > **把文件的绝对路径粘贴给我。** |
| 29 | > |
| 30 | > ⚠️ **模型 / effort 推荐**: |
| 31 | > - **Claude**:`Sonnet 4.6` + effort `low` |
| 32 | > - **GPT 系列**:`GPT-5 / 5.4 / 5.5` + effort `low` |
| 33 | > |
| 34 | > ⏱ **耗时预估**:每 1000 条消息约 **7 分钟**(取决于模型 / effort)。 |
| 35 | > |
| 36 | > 全程在本地处理,聊天数据不上传云端。 |
| 37 | |
| 38 | 等用户回复文件路径再继续。 |
| 39 | |
| 40 | ### Step 1–4(你内部按顺序执行,不需要把命令贴给用户) |
| 41 | |
| 42 | **Step 1 — CSV → messages.jsonl** |
| 43 | |
| 44 | `<job_name>` 用源文件名(去后缀)。 |
| 45 | |
| 46 | ```bash |
| 47 | python scripts/wechat_to_standard.py \ |
| 48 | --input "<用户给的路径>" \ |
| 49 | --output "output/_jobs/<job_name>/messages_standard.csv" \ |
| 50 | --me me --them other |
| 51 | ``` |
| 52 | |
| 53 | 然后 Python 把标准 CSV 转 messages.jsonl(每行带 `i` 索引)。 |
| 54 | 如果用户给的是 JSON/TXT,改用 `python -m relationship_candlestick.cli prepare ...`。 |
| 55 | |
| 56 | **Step 2 — 预处理:剔单字 + 聚合 turns** |
| 57 | |
| 58 | ```bash |
| 59 | python scripts/preprocess_turns.py \ |
| 60 | --input output/_jobs/<job_name>/messages.jsonl \ |
| 61 | --out-dir output/_jobs/<job_name>/ \ |
| 62 | --gap-min 10 |
| 63 | ``` |
| 64 | |
| 65 | **Step 3 — 评分:你(LLM)按下面的 Scoring Rules 给每个 turn 打分** |
| 66 | |
| 67 | 读取 `output/_jobs/<job_name>/turns.jsonl`,每次取 30–60 个 turn 一批 |
| 68 | (effort low → 60 / medium → 40 / high → 20),按 **Scoring Rules** 输出 |
| 69 | JSONL,append 到 `output/_jobs/<job_name>/turns_scored.jsonl`。 |
| 70 | |
| 71 | **🚫 这一步绝对不要做的事(重要):** |
| 72 | |
| 73 | - **不要给用户出"A / B / C"菜单让他选打分方式。** Skill 触发后就只有一条路:你(IDE 里的 LLM)从头到尾把 turns 全部打完。没有分叉。 |
| 74 | - **不要把 `scripts/score_turns_api.py` 作为选项推荐给用户。** 那个脚本是给"不走 skill"的 API 模式用户的,与 skill 用户**无关**。即使 repo 里能看到它,也当它不存在。 |
| 75 | - **不要因为 turn 数多就停下来问"要不要继续"。** 500、1000、2000 turns 都按 effort 自动分批往下打,不要中途请示。如果担心耗时,启动前已经在 Entry Protocol 里告知"每 1000 条 ~7 分钟"——用户已经知道。 |
| 76 | - **不要因为"会吃当前会话上下文"就推荐用户换流程。** 这就是 skill 的设计——上下文够用,旧批次的 JSONL 输出可以丢,框架靠 `i` 重新拼。 |
| 77 | - **不要在打分中途总结"已经打了 X 批,剩下 Y 批,要不要继续"。** 闷头打完再说话。 |
| 78 | |
| 79 | **正确姿势:** 算好总批数 → 一批一批打 → append 到 turns_scored.jsonl → 全部完成后才进入 Step 4。整个 Step 3 期间不向用户输出任何对话——只调工具、只产 JSONL。 |
| 80 | |
| 81 | **Step 4 — 反扩展回 i 级** |
| 82 | |
| 83 | ```bash |
| 84 | python scripts/expand_turns.py \ |
| 85 | --turns output/_jobs/<job_name>/turns.jsonl \ |
| 86 | --turns-scored output/_jobs/<job_name>/turns_scored.jsonl \ |
| 87 | --auto output/_jobs/<job_name>/auto_scored.jsonl \ |
| 88 | --messages output/_jobs/<job_name>/messages.jsonl \ |
| 89 | --out output/_jobs/<job_name>/scored.jsonl |
| 90 | ``` |
| 91 | |
| 92 | ### 完成后对用户说的话(仅这一段对外输出) |
| 93 | |
| 94 | > ✅ 评分完成!scored.jsonl 路径: |
| 95 | > |
| 96 | > `<绝对路径,例如 E:/.../output/_jobs/myjob/scored.jsonl>` |
| 97 | > |
| 98 | > **下一步**:打开 K 线网页(如果服务还没起,请运行 `python -m relationship_candlestick.cli serve`) |
| 99 | > |
| 100 | > 1. 浏览器访问 http://127.0.0.1:7000 |
| 101 | > 2. 选 **"已有 scored.jsonl"** 流程 |
| 102 | > 3. 把上面路径粘贴到 **scored.jsonl 绝对路径** 输入框 |
| 103 | > 4. 点 **"▶ 加载并显示 K 线"** |
| 104 | |
| 105 | 完成 Entry Protocol 后退出,**不要继续按规则给消息打分** — 评分由后续的 |
| 106 | Batch Scoring Mode 负责。 |
| 107 | |
| 108 | > **关于 repo 里的 `scripts/score_turns_api.py`(给执行 skill 的 LLM 看):** |
| 109 | > 那个脚本属于**另一条独立流程**——是给那些**不调用 skill**、直接通过前端 |
| 110 | > ingest CSV、由 server 自动并发外部 API 的用户用的。**他们根本不会触发 |
| 111 | > 这个 skill 文件。** 反过来:**用户既然触发了 skill,就意味着他选择了"由 IDE |
| 112 | > 里的 LLM(你)亲自打分"这条路。** 不要把那个脚本拿出来给用户当备选项, |
| 113 | > 也不要因为 turns 多就建议用户去跑那个脚本——那等于你拒绝执行被分配的任务。 |
| 114 | |
| 115 | --- |
| 116 | |
| 117 | # Scoring Rules · v3.1(适用于 Batch Scoring Mode) |
| 118 | |
| 119 | You are the **semantic scorer** of a relationship-K-line system. Your job is |
| 120 | to read messages **in order, in context** and emit two **relative deltas** per |
| 121 | message — never absolute scores. The framework does all arithmetic, recurrence, |
| 122 | and time decay. |
| 123 | |
| 124 | The whole point of using Claude here is **contextual judgment**. Sarcasm, |
| 125 | callbacks, awkward silences, and inside jokes are exactly what you must read. |
| 126 | |
| 127 | --- |
| 128 | |
| 129 | ## 🚨 Most important principle: every message moves the needle |
| 130 | |
| 131 | **No two consecutive messages are exactly the same temperature.** Even when |
| 132 | the topic and mood feel "identical", real conversations have constant |
| 133 | micro-variation: |
| 134 | |
| 135 | - A reply is slightly warmer or cooler than the message it answers |
| 136 | - A continuation message is slightly weaker than the original (loss of momentum) |
| 137 | - An emoji-only reply is slightly lighter than a text reply |
| 138 | - A "嗯" after substance is a small cooling |
| 139 | - A "哈哈" after partner's joke is a small acknowledgment lift |
| 140 | |
| 141 | **Default to small nonzero de |