sync: HP_BOWEI 2026-10-15

This commit is contained in:
Myfro9
2026-10-15 01:59:40 +08:00
parent 771acd4171
commit a0a3445bfd
21 changed files with 3042 additions and 16 deletions
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
# 核实 claude-brain 运行中每个子 agent 实际使用的模型。
# 原理:Claude Code 把每个 subagent 的转录写在
# ~/.claude/projects/<项目slug>/<会话ID>/subagents/agent-<id>.jsonl
# 每条模型回复都带 "model":"claude-xxx" 字段;逐文件统计即可知道实际生效的模型,
# 以及是否中途切换过(一个文件里出现多种模型即为切换)。
#
# 用法:
# check_models.sh # 扫描当前项目目录下最近 24h 内活跃的会话
# check_models.sh <会话ID> # 只看指定会话
# check_models.sh --hours 6 # 改时间窗
# 项目 slug 由当前工作目录推导(E:\a\b -> E--a-b),与 Claude Code 规则一致。
hours=24
session=""
while [ $# -gt 0 ]; do
case "$1" in
--hours) hours="$2"; shift 2 ;;
*) session="$1"; shift ;;
esac
done
cwd="$(pwd -W 2>/dev/null || pwd)"
# Claude Code 的 slug 规则:盘符冒号、路径分隔符、下划线都变成 '-'(E:\a_b\c -> E--a-b-c)
slug="$(printf '%s' "$cwd" | sed -e 's#[:/\\_]#-#g')"
proj="$HOME/.claude/projects/$slug"
if [ ! -d "$proj" ]; then
echo "找不到项目转录目录: $proj" >&2
echo "请在 claude-brain 运行时所在的工程根目录执行本脚本。" >&2
exit 1
fi
mins=$((hours * 60))
if [ -n "$session" ]; then
files=$(find "$proj/$session/subagents" -name 'agent-*.jsonl' 2>/dev/null)
else
files=$(find "$proj" -path '*/subagents/agent-*.jsonl' -mmin "-$mins" 2>/dev/null)
fi
if [ -z "$files" ]; then
echo "没有找到子 agent 转录(窗口 ${hours}h,目录 $proj)。"
exit 0
fi
printf '%-28s %-10s %s\n' "agent" "回复数" "实际模型(出现次数)"
for f in $files; do
id=$(basename "$f" .jsonl | sed 's/^agent-//')
stats=$(grep -o '"model":"claude-[a-z0-9-]*"' "$f" | sed 's/"model":"//;s/"$//' | sort | uniq -c | awk '{printf "%s x%s ", $2, $1}')
n=$(grep -c '"model":"claude-' "$f")
flag=""
kinds=$(printf '%s' "$stats" | grep -o 'claude-[a-z0-9-]*' | sort -u | wc -l)
[ "$kinds" -gt 1 ] && flag=" <-- 中途切换过模型"
printf '%-28s %-10s %s%s\n' "$id" "$n" "$stats" "$flag"
done
+89
View File
@@ -0,0 +1,89 @@
#!/usr/bin/env python3
"""把大脑决策文件 Rnn-brain.md 里的 `### Tk` 各节原样抽成 Rnn-Tk-task.md。
用法:
python split_tasks.py <运行目录>/R04-brain.md
规则(与 SKILL.md / templates.md 一致):
- 只抽取 "## 任务" 与 "## 向用户提问" 之间的 `### Tk` 节,正文一字不改。
- 模型取该节 "- 模型:" 行;写了 fable 则改回 opus(Fable 只属于大脑),并在 stdout 提示。
- 报告路径优先取该节 "- 报告格式:" 行里反引号中的路径(大脑常自己指定文件名);
大脑用 `...\\` 省略了目录前缀时,用运行目录补全;没写则用默认 Rnn-Tk-report.md。
- 末尾追加 worker 报告格式模板。
输出: 每个任务一行 "Tk <model> <task-file> <report-path>",供调度员直接派 worker。
"""
import re
import sys
from pathlib import Path
REPORT_TEMPLATE = '''
---
## 报告格式
写到 `{report}`,结构如下:
```
# {rnd}-{tk} 报告
- 结论: 完成 | 部分完成 | 失败 | 受阻
- 模型: {model}
## 做了什么
<按步骤列出>
## 改动的文件
<路径 + 一句话说明;没有就写"无">
## 证据
<关键命令及输出摘录、测量值、测试结果、日志片段>
## 验收标准逐条
1. <标准> —— 满足/不满足,证据: ...
## 问题与建议
<遇到的意外、任务单没覆盖到需要大脑决定的点>
```
验收标准要求的各张表、设计说明、数值结果放在"证据"一节或其后的独立小节中。
'''
def main(path: str) -> None:
brain = Path(path).resolve()
rundir = brain.parent
rnd = brain.stem.split('-')[0] # R04 / R02b
text = brain.read_text(encoding='utf-8')
if '## 任务' not in text:
sys.exit('决策文件里没有 "## 任务" 节')
body = text.split('## 任务', 1)[1]
for stop in ('## 向用户提问', '## 总结'):
if stop in body:
body = body.split(stop, 1)[0]
parts = re.split(r'(?m)^### (T\w+)\s*$', body)
if len(parts) < 3:
sys.exit('没有找到任何 "### Tk" 节')
for i in range(1, len(parts), 2):
tk, sec = parts[i], parts[i + 1].strip('\n')
m = re.search(r'-\s*模型:\s*(\w+)', sec)
model = m.group(1).lower() if m else 'opus'
if model == 'fable':
print(f'[warn] {tk} 指定了 fable,改回 opus(Fable 只属于大脑)', file=sys.stderr)
model = 'opus'
rep = None
m = re.search(r'-\s*报告格式:.*?`([^`]+\.md)`', sec)
if m:
rep = m.group(1)
if rep.startswith('...'):
rep = str(rundir / Path(rep.replace('...', '').lstrip('\\/')).name)
elif not Path(rep).is_absolute():
rep = str(rundir / rep)
if not rep:
rep = str(rundir / f'{rnd}-{tk}-report.md')
out = (f'# {rnd}-{tk} 任务单(模型: {model})\n\n### {tk}\n{sec}\n'
+ REPORT_TEMPLATE.format(report=rep, rnd=rnd, tk=tk, model=model))
task_file = rundir / f'{rnd}-{tk}-task.md'
task_file.write_text(out, encoding='utf-8')
print(f'{tk} {model} {task_file} {rep}')
if __name__ == '__main__':
if len(sys.argv) != 2:
sys.exit(__doc__)
main(sys.argv[1])