Appearance
实施指南
前置准备
系统要求检查
在开始实施之前,请确保系统满足以下要求:
必需依赖
bash
# 检查 Bash 版本(需要 4.0+)
bash --version
# 预期输出: GNU bash, version 4.0 或更高
# 检查 Git
git --version
# 检查 OpenCode
opencode --version
# 检查 jq(JSON 处理)
jq --version
# 检查 tmux(用于监控,可选)
tmux -V安装缺失依赖
bash
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install -y bash git jq tmux
# macOS
brew install bash git jq tmuxOpenCode GLM4.7 配置
bash
# 配置 OpenCode 使用 GLM4.7
opencode config set model glm-4-flash
opencode config set api-key YOUR_GLM_API_KEY
# 验证配置
opencode config list环境变量设置
bash
# 添加到 ~/.bashrc 或 ~/.zshrc
export RALPH_MAX_ITERATIONS=50
export RALPH_MAX_API_CALLS=100
export RALPH_SESSION_TIMEOUT=86400 # 24小时
export RALPH_LOG_LEVEL=INFO
# 重新加载配置
source ~/.bashrc方案 A:原生集成实施步骤
步骤 1:下载并适配 Ralph
bash
# 1. 克隆 Ralph 仓库
cd ~
git clone https://github.com/frankbria/ralph-claude-code.git
cd ralph-claude-code
# 2. 创建适配分支(可选)
git checkout -b opencode-adaptation
# 3. 备份原始文件
cp ralph_loop.sh ralph_loop.sh.original
cp ralph_import.sh ralph_import.sh.original步骤 2:修改 Ralph 配置
修改 ralph_loop.sh
bash
# 找到 build_claude_command() 函数并修改
# 原始代码(大约在 200 行左右)
build_claude_command() {
local prompt="$1"
local output_format="$2"
local cmd="claude"
cmd="$cmd --continue"
cmd="$cmd -p \"$prompt\""
if [ "$output_format" = "json" ]; then
cmd="$cmd --output-format json"
fi
echo "$cmd"
}
# 修改为
build_claude_command() {
local prompt="$1"
local output_format="$2"
local cmd="opencode"
cmd="$cmd --continue-session"
cmd="$cmd -p \"$prompt\""
if [ "$output_format" = "json" ]; then
cmd="$cmd --json-output"
fi
echo "$cmd"
}修改 install.sh(如果需要)
bash
# 找到 install_global_commands() 函数
# 确保安装路径正确
BIN_DIR="$HOME/.local/bin"
mkdir -p "$BIN_DIR"
# 复制脚本到全局路径
cp ralph_loop.sh "$BIN_DIR/ralph"
chmod +x "$BIN_DIR/ralph"
cp ralph_monitor.sh "$BIN_DIR/ralph-monitor"
chmod +x "$BIN_DIR/ralph-monitor"步骤 3:创建 Stop Hook 钩子
bash
# 在项目中创建 hooks 目录
mkdir -p hooks
# 创建 stop-hook.sh
cat > hooks/stop-hook.sh << 'EOF'
#!/bin/bash
set -euo pipefail
# OpenCode Stop Hook - 适配版
# 用于拦截退出并决定是否继续循环
# 配置
MIN_COMPLETION_INDICATORS=2
DEBUG=false
# 日志函数
log() {
if [ "$DEBUG" = "true" ]; then
echo "[DEBUG] $@" >&2
fi
}
# 主逻辑
main() {
local output_file="$1"
log "Stop Hook triggered for: $output_file"
# 检查输出文件是否存在
if [ ! -f "$output_file" ]; then
log "Output file not found: $output_file"
exit 0 # 允许退出
fi
# 提取完成指示器
local completion_indicators=0
local output_content=$(cat "$output_file")
# 检查完成相关关键词
completion_indicators+=$(echo "$output_content" | grep -oEi "complete|done|finished|ready|implemented|completed" | wc -l)
log "Completion indicators: $completion_indicators"
# 检查 EXIT_SIGNAL
local exit_signal="false"
if echo "$output_content" | grep -q "EXIT_SIGNAL.*true"; then
exit_signal="true"
fi
log "EXIT_SIGNAL: $exit_signal"
# 检查显式完成标记
local explicit_complete=false
if echo "$output_content" | grep -q "<<COMPLETED>>" || echo "$output_content" | grep -q "任务完成"; then
explicit_complete=true
fi
log "Explicit complete: $explicit_complete"
# 双重条件判断
if [ $completion_indicators -ge $MIN_COMPLETION_INDICATORS ] && [ "$exit_signal" = "true" ]; then
log "✅ Completion conditions met, allowing exit"
exit 0 # 允许退出
elif [ "$explicit_complete" = "true" ]; then
log "✅ Explicit completion marker found, allowing exit"
exit 0 # 允许退出
else
log "❌ Completion conditions not met, blocking exit"
exit 2 # 阻止退出,触发下一轮循环
fi
}
main "$@"
EOF
# 添加执行权限
chmod +x hooks/stop-hook.sh步骤 4:初始化研究项目
bash
# 1. 使用 Ralph 设置项目
ralph-setup research-report-generator
# 2. 进入项目目录
cd research-report-generator
# 3. 项目结构应如下:
# research-report-generator/
# ├── PROMPT.md
# ├── @fix_plan.md
# ├── @AGENT.md
# ├── specs/
# ├── src/
# ├── examples/
# ├── logs/
# ├── docs/generated/
# └── hooks/
# └── stop-hook.sh步骤 5:配置研究项目
编辑 PROMPT.md
bash
cat > PROMPT.md << 'EOF'
# 自动化研究报告生成任务
## 项目目标
生成一份关于「人工智能在医疗诊断中的应用」的专业研究报告,字数约 15000-20000 字。
## 报告结构要求
研究报告必须包含以下章节:
1. **研究背景与意义**
- 医疗诊断的现状与挑战
- AI 技术的发展历程
- 研究价值与意义
2. **文献综述**
- 国内外研究现状
- 主要技术流派分析
- 存在的问题与不足
3. **技术方法论**
- 机器学习算法在诊断中的应用
- 深度学习模型分析
- 多模态诊断技术
4. **案例分析**
- 影像诊断(CT、MRI、X光)
- 病理诊断
- 实验室诊断
5. **挑战与限制**
- 数据隐私与安全
- 模型可解释性
- 临床应用的伦理问题
6. **未来发展趋势**
- 技术发展方向
- 临床应用前景
- 政策法规展望
7. **结论与建议**
- 研究总结
- 实践建议
- 未来研究方向
## 质量要求
- 学术规范:使用 APA 格式引用文献
- 数据支撑:所有观点需有可靠来源
- 案例丰富:至少包含 5 个实际应用案例
- 图文并茂:包含必要的图表和示意图
## 完成标准
当满足以下所有条件时,在响应末尾输出 <<COMPLETED>> 标记:
- [ ] 所有 7 个章节完整撰写
- [ ] 字数在 15000-20000 字之间
- [ ] 文献引用不少于 30 篇
- [ ] 包含至少 5 个实际案例
- [ ] 格式规范,无语法错误
- [ ] 包含必要的图表
EOF编辑 @fix_plan.md
bash
cat > @fix_plan.md << 'EOF'
# 任务优先级列表
## 高优先级任务(P0)
- [ ] 创建研究报告目录结构
- [ ] 撰写「研究背景与意义」章节(约 2000 字)
- [ ] 撰写「技术方法论」章节(约 3000 字)
## 中优先级任务(P1)
- [ ] 撰写「文献综述」章节(约 3000 字)
- [ ] 撰写「案例分析」章节(约 3500 字)
- [ ] 撰写「挑战与限制」章节(约 2000 字)
## 低优先级任务(P2)
- [ ] 撰写「未来发展趋势」章节(约 2000 字)
- [ ] 撰写「结论与建议」章节(约 1500 字)
- [ ] 添加必要的图表和示意图
- [ ] 完善文献引用(不少于 30 篇)
- [ ] 格式校对与排版优化
- [ ] 最终审查与质量检查
EOF编辑 @AGENT.md
bash
cat > @AGENT.md << 'EOF'
# 构建和运行说明
## 开发环境
- AI 助手:OpenCode + GLM4.7
- 编程语言:Markdown
- 版本控制:Git
## 工作流程
1. 阅读 PROMPT.md 了解项目需求
2. 参考 @fix_plan.md 按优先级执行任务
3. 每完成一个任务,在 @fix_plan.md 中标记为 [x]
4. 定期提交 Git commit 保存进度
## 输出规范
- 所有研究报告内容输出到 src/ 目录
- 使用 Markdown 格式
- 文件命名规范: `01-章节名.md`, `02-章节名.md`
- 在每个章节末尾更新进度状态
## 进度跟踪
在每个迭代结束时,在响应末尾添加:RALPH_STATUS: { "progress": 0-100, "current_task": "当前正在进行的任务", "completed_tasks": ["已完成的任务1", "已完成的任务2"], "pending_tasks": ["待办任务1", "待办任务2"], "EXIT_SIGNAL": false, "notes": "当前进展说明" }
## 完成条件
当所有 P0-P2 任务完成且满足 PROMPT.md 中的质量要求时,设置 EXIT_SIGNAL: true。
EOF步骤 6:启动自动化循环
bash
# 方式 1:带 tmux 监控启动(推荐)
ralph --monitor
# 方式 2:手动启动两个终端
# 终端 1
ralph --verbose
# 终端 2
ralph-monitor
# 方式 3:后台运行
nohup ralph > logs/ralph.stdout 2> logs/ralph.stderr &
echo $! > logs/ralph.pid
ralph-monitor步骤 7:监控与调试
查看实时状态
bash
# 使用 ralph-monitor
ralph-monitor
# 或手动查看日志
tail -f logs/ralph.log
# 查看 JSON 状态
cat status.json | jq '.'常用调试命令
bash
# 检查循环状态
ralph --status
# 重置断路器
ralph --reset-circuit
# 查看断路器状态
ralph --circuit-status
# 检查会话状态
cat .ralph_session
cat .ralph_session_history
# 查看 API 调用统计
grep "API call" logs/ralph.log | wc -l处理中断
bash
# 如果循环被中断,恢复执行
cd research-report-generator
ralph # 会自动恢复上次的状态
# 如果需要从特定循环恢复
ralph --continue
# 重置会话(清除上下文)
ralph --reset-session方案 B:外部循环实施步骤
步骤 1:创建项目结构
bash
# 1. 创建项目目录
mkdir research-project-external
cd research-project-external
# 2. 创建子目录
mkdir -p outputs logs src hooks
# 3. 创建必要的文件
touch .current_status.json
touch .loop_count
touch .api_calls步骤 2:编写核心脚本
创建 ralph-external-loop.sh
bash
cat > ralph-external-loop.sh << 'EOF'
#!/bin/bash
set -euo pipefail
# Ralph 外部循环控制器 - OpenCode + GLM4.7
# 不依赖 Stop Hook,使用外部 Bash 循环实现
# 配置参数
MAX_ITERATIONS=50
MAX_API_CALLS=100
HOURLY_LIMIT_DURATION=3600 # 1小时
LOOP_DELAY=5 # 循环间隔秒数
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# 初始化
init() {
echo -e "${GREEN}初始化 Ralph 外部循环...${NC}"
if [ ! -f .loop_count ]; then
echo 0 > .loop_count
fi
if [ ! -f .api_calls ]; then
echo 0 > .api_calls
fi
if [ ! -f .hour_limit_reset ]; then
date +%s > .hour_limit_reset
fi
# 初始化状态文件
if [ ! -f .current_status.json ]; then
cat > .current_status.json << 'INIT'
{
"loop_count": 0,
"progress": 0,
"current_task": "初始化项目",
"completed_tasks": [],
"pending_tasks": [
"创建报告目录结构",
"撰写研究背景章节",
"文献检索与分析",
"撰写方法论述",
"数据分析与可视化",
"撰写结论与建议",
"格式校对与排版"
],
"last_update": "",
"api_calls_this_hour": 0,
"no_progress_count": 0
}
INIT
fi
echo "✅ 初始化完成"
}
# 读取当前状态
read_status() {
if [ -f .current_status.json ]; then
cat .current_status.json
else
echo '{}'
fi
}
# 更新状态
update_status() {
local status="$1"
echo "$status" > .current_status.json
}
# 生成上下文提示词
generate_prompt() {
local status="$1"
local loop_count=$(echo "$status" | jq -r '.loop_count // 0')
local progress=$(echo "$status" | jq -r '.progress // 0')
local current_task=$(echo "$status" | jq -r '.current_task // ""')
local completed_tasks=$(echo "$status" | jq -r '.completed_tasks // []')
local pending_tasks=$(echo "$status" | jq -r '.pending_tasks // []')
cat << PROMPT
# 自动化研究报告生成 - 第 $((loop_count + 1)) 次迭代
## 📊 当前状态
- 进度: ${progress}%
- 循环次数: $loop_count
## ✅ 已完成任务
$(if [ "$completed_tasks" != "[]" ]; then
echo "$completed_tasks" | jq -r '.[]' | sed 's/^/ - /'
else
echo " (无)"
fi)
## ⏳ 待办任务
$(if [ "$pending_tasks" != "[]" ]; then
echo "$pending_tasks" | jq -r '.[]' | head -5 | sed 's/^/ - /'
else
echo " (无)"
fi)
## 📝 本次任务
$current_task
## 📋 原始需求
$(cat PROMPT.md)
---
### 指令
1. 执行当前任务
2. 完成后在响应末尾使用以下格式报告进展:
\`\`\`
RALPH_UPDATE:
{
"completed_task": "完成的任务名称",
"next_task": "建议的下一个任务",
"progress": 新的进度百分比
}
\`\`\`
3. 如果所有任务完成,在最后添加: <<COMPLETED>>
请开始执行任务。
PROMPT
}
# 检查完成状态
check_completion() {
local output="$1"
if echo "$output" | grep -q "<<COMPLETED>>"; then
return 0 # 完成
fi
return 1 # 未完成
}
# 解析输出并更新状态
parse_and_update_status() {
local output="$1"
local current_status="$2"
local completed_task=$(echo "$output" | grep -oP '(?<=RALPH_UPDATE:).*' | jq -r '.completed_task // ""')
local next_task=$(echo "$output" | grep -oP '(?<=RALPH_UPDATE:).*' | jq -r '.next_task // ""')
local new_progress=$(echo "$output" | grep -oP '(?<=RALPH_UPDATE:).*' | jq -r '.progress // 0')
local updated_status="$current_status"
if [ -n "$completed_task" ]; then
updated_status=$(echo "$updated_status" | \
jq --arg ct "$completed_task" '.completed_tasks += [$ct]')
fi
if [ -n "$next_task" ]; then
updated_status=$(echo "$updated_status" | \
jq --arg nt "$next_task" '.current_task = $nt')
fi
updated_status=$(echo "$updated_status" | \
jq --argjson lp "$new_progress" '.progress = $lp')
echo "$updated_status"
}
# 主循环
main_loop() {
init
echo -e "${YELLOW}开始自动化循环...${NC}"
echo ""
while true; do
# 读取循环计数
local loop_count=$(cat .loop_count)
# 检查最大循环次数
if [ "$loop_count" -ge "$MAX_ITERATIONS" ]; then
echo -e "${RED}达到最大循环次数 ($MAX_ITERATIONS),退出${NC}"
break
fi
# 读取当前状态
local current_status=$(read_status)
# 生成提示词
local prompt=$(generate_prompt "$current_status")
# 执行 OpenCode
echo -e "${GREEN}[循环 $((loop_count + 1))/$MAX_ITERATIONS] 正在执行...${NC}"
local output=$(opencode -p "$prompt" 2>&1)
# 保存输出
echo "$output" > "outputs/loop_$(printf '%04d' $loop_count).txt"
# 更新 API 调用计数
local api_calls=$(cat .api_calls)
((api_calls++))
echo "$api_calls" > .api_calls
# 解析并更新状态
local updated_status=$(parse_and_update_status "$output" "$current_status")
update_status "$updated_status"
# 检查完成
if check_completion "$output"; then
echo -e "${GREEN}✅ 任务完成!${NC}"
break
fi
# 更新循环计数
((loop_count++))
echo "$loop_count" > .loop_count
# 等待
echo "等待 $LOOP_DELAY 秒..."
sleep "$LOOP_DELAY"
echo ""
done
echo -e "${GREEN}循环结束,总迭代次数: $loop_count${NC}"
echo "最终状态:"
cat .current_status.json | jq '.'
}
# 主函数
main() {
main_loop
}
main "$@"
EOF
chmod +x ralph-external-loop.sh创建 monitor.sh
bash
cat > monitor.sh << 'EOF'
#!/bin/bash
set -euo pipefail
# Ralph 外部循环监控面板
clear_monitor() {
clear
echo "═══════════════════════════════════════════════════"
echo " Ralph 外部循环 - 实时监控面板"
echo "═══════════════════════════════════════════════════"
echo ""
}
display_status() {
if [ ! -f .current_status.json ]; then
echo "⚠️ 状态文件不存在"
return
fi
local status=$(cat .current_status.json)
echo "📊 当前进度: $(echo "$status" | jq -r '.progress // 0')%"
echo "🔄 迭代次数: $(echo "$status" | jq -r '.loop_count // 0')"
echo "📝 当前任务: $(echo "$status" | jq -r '.current_task // "无"')"
echo ""
echo "✅ 已完成任务:"
local completed=$(echo "$status" | jq -r '.completed_tasks // []')
if [ "$completed" = "[]" ]; then
echo " (无)"
else
echo "$completed" | jq -r '.[]' | sed 's/^/ - /'
fi
echo ""
echo "⏳ 待办任务:"
local pending=$(echo "$status" | jq -r '.pending_tasks // []')
if [ "$pending" = "[]" ]; then
echo " (无)"
else
echo "$pending" | jq -r '.[]' | head -5 | sed 's/^/ - /'
fi
echo ""
echo "📞 API 调用: $(cat .api_calls 2>/dev/null || echo 0)/100 (每小时)"
echo "⏰ 最后更新: $(echo "$status" | jq -r '.last_update // "无"')"
}
main() {
while [ -f .current_status.json ] || [ -f .loop_count ]; do
clear_monitor
display_status
echo ""
echo "═══════════════════════════════════════════════════"
echo "按 Ctrl+C 退出监控"
sleep 2
done
echo "循环已结束或文件不存在"
}
main
EOF
chmod +x monitor.sh步骤 3:配置项目
bash
# 创建 PROMPT.md(与方案 A 相同)
cat > PROMPT.md << 'EOF'
# 自动化研究报告生成任务
[与方案 A 相同的 PROMPT.md 内容]
EOF
# 初始化状态文件
cat > .current_status.json << 'INIT'
{
"loop_count": 0,
"progress": 0,
"current_task": "创建研究报告目录结构",
"completed_tasks": [],
"pending_tasks": [
"创建报告目录结构",
"撰写研究背景与意义章节",
"撰写文献综述章节",
"撰写技术方法论章节",
"撰写案例分析章节",
"撰写挑战与限制章节",
"撰写未来发展趋势章节",
"撰写结论与建议章节",
"添加图表和示意图",
"完善文献引用",
"格式校对与排版"
],
"last_update": "$(date -Iseconds)",
"api_calls_this_hour": 0,
"no_progress_count": 0
}
INIT步骤 4:启动循环
bash
# 终端 1:启动主循环
./ralph-external-loop.sh
# 终端 2:启动监控
./monitor.sh配置优化建议
GLM4.7 提示词优化
提高任务完成准确率
markdown
# 增强的 GLM4.7 提示词模板
你是一个专业的研究报告生成助手。
## 重要指令
1. **一次只做一个任务**:专注于完成一个具体的任务,不要试图一次完成所有事情
2. **明确报告进展**:完成后使用 RALPH_UPDATE 格式报告你完成了什么
3. **质量优先**:确保每个任务都高质量完成,不要匆忙推进
## 输出规范
当你完成一个任务时,必须使用以下格式:
\`\`\`
RALPH_UPDATE:
{
"completed_task": "清晰描述你完成的任务",
"next_task": "建议的下一个任务(基于 @fix_plan.md)",
"progress": 新的进度百分比
}
\`\`\`
## 质量检查清单
在报告任务完成前,请自查:
- [ ] 内容是否完整
- [ ] 是否有具体的案例或数据支撑
- [ ] 格式是否正确
- [ ] 是否存在拼写或语法错误
只有通过自查后,才设置 EXIT_SIGNAL: true。性能优化配置
bash
# 调整循环参数以优化性能
# 对于复杂任务,减少循环频率
export RALPH_LOOP_DELAY=10 # 10秒间隔
# 增加最大循环次数(如果任务复杂)
export RALPH_MAX_ITERATIONS=100
# 根据预算调整 API 限制
export RALPH_MAX_API_CALLS=50 # 每小时50次调用
# 启用详细日志以便调试
export RALPH_LOG_LEVEL=DEBUG故障排查
常见问题 1:循环无法启动
症状:运行 ralph 后没有任何输出
排查步骤:
bash
# 检查脚本权限
ls -la ralph
# 检查是否在正确的目录
pwd
# 查看错误日志
cat logs/ralph.error
# 手动测试 OpenCode
opencode -p "测试" --help解决方案:
bash
# 重新安装 Ralph
cd ~/ralph-claude-code
./install.sh
# 或添加执行权限
chmod +x ralph常见问题 2:循环过早退出
症状:循环在 1-2 次后就停止
排查步骤:
bash
# 检查输出日志
tail -n 50 logs/ralph.log
# 查看 OpenCode 错误
cat outputs/loop_0001.txt
# 检查 Stop Hook
cat hooks/stop-hook.sh可能原因:
- EXIT_SIGNAL 被错误地设置为 true
- GLM4.7 输出中包含了过多完成关键词
- OpenCode 调用失败
解决方案:
bash
# 退出检测过于宽松,提高阈值
export MIN_COMPLETION_INDICATORS=5
# 或在 PROMPT.md 中明确指示 GLM4.7 不要设置 EXIT_SIGNAL常见问题 3:循环陷入无限循环
症状:循环一直运行但不进展
排查步骤:
bash
# 检查循环次数
cat .loop_count
# 查看最近的输出
tail outputs/loop_*.txt
# 检查断路器状态
ralph --circuit-status可能原因:
- GLM4.7 每次输出相同内容
- 任务定义不清晰
- 断路器未正确触发
解决方案:
bash
# 手动停止循环
ralph --reset-circuit
# 重新定义更清晰的任务
vim @fix_plan.md
# 从头开始
rm .ralph_session
ralph常见问题 4:API 速率限制
症状:显示达到速率限制,循环暂停
解决方案:
bash
# 等待 60 分钟自动恢复
# 或手动重置 API 计数器
echo 0 > .api_calls
echo $(($(date +%s) + 3600)) > .hour_limit_reset
# 或者增加限制(如果预算允许)
export RALPH_MAX_API_CALLS=200参考资料
- frankbria/ralph-claude-code README - Ralph 官方安装和配置指南
- OpenCode Documentation - OpenCode CLI 使用文档
- GLM-4 API Reference - GLM4.7 API 参考文档
- Bash Scripting Best Practices - Bash 脚本最佳实践