☰
Greploop 实战指南:基于 Greptile 自动迭代优化 PR/MR/CL 直至满分评审
2026/9/27 8:28:48 网站建设 项目流程
  • 后端
  • 工作流自动化
  • 流程编排
  • 低代码

【免费下载链接】elsa-core

The Workflow Engine for .NET

项目地址:https://gitcode.com/gh_mirrors/el/elsa-core
点击查看免费下载

导读

Greploop 是存放在本仓库.agents/skills/greploop/目录下的一个 AI Agent 技能(Skill),用于驱动 AI 编程代理对 GitHub PR、GitLab MR 或 Perforce 变更列表(CL)执行“评审—修复—再评审”的闭环循环,直到 Greptile 代码评审工具给出 5/5 置信度且零未解决评论。读完本文,你将掌握 Greploop 的完整执行流程:平台自动探测、PR/MR/CL 识别与创建、Greptile 评审触发与轮询、评分解析、评论修复、线程解决以及最终结果报告,并能基于仓库中的参考文档(GitLab API 与 GitHub GraphQL 查询)深入落地到实际 CI/Agent 流水线中。

Greploop 是什么

Greploop 的核心目标非常明确:迭代修复一个 PR/MR/CL,直到 Greptile 给出满分评审——5/5 置信度、零未解决评论。它是一份结构化的 Agent 指令(skill),不是可执行二进制程序,而是由具备 Bash 执行能力的 AI 代理(如 Codex)逐条遵循的操作规程。

从仓库内的元数据可以看出它的工程化定位(见 .agents/skills/greploop/SKILL.md):

  • 名称与描述:name: greploop,描述明确为“迭代改进 PR(GitHub)/MR(GitLab)/shelved changelist(Perforce),直到 Greptile 给出 5/5 置信度且零未解决评论”。
  • 许可证:MIT(版权归 Greptile AI,见 .agents/skills/greploop/LICENSE)。
  • 兼容性:要求git、gh(GitHub CLI)或glab(GitLab CLI)已认证,且仓库已安装 Greptile;Perforce 场景需要已认证的p4CLI。
  • 允许的工具白名单:Bash(gh:*) Bash(glab:*) Bash(git:*) Bash(p4:*),即该技能只被允许通过这四类 CLI 完成全部操作。
  • 元数据版本:version: "1.2",作者greptileai。

使用前需确认前置条件全部满足:

平台必需 CLI附加要求
GitHubgit、gh(已认证)仓库已安装 Greptile,greptile-apps[bot]或greptile-apps-staging[bot]参与评审
GitLabgit、glab(已认证)仓库已安装 Greptile,Greptile 作为 pipeline job 运行
Perforcep4(已认证)正确的p4 clientworkspace,Greptile 通过 webhook 或 Swarm 集成

输入

Greploop 唯一可选输入是PR/MR/CL 编号。若未提供,则由代理自动探测:为当前分支查找对应的 PR/MR,或为 Perforce 查找默认的 pending changelist。

总体流程:六步闭环

Greploop 的执行主线由以下步骤组成:

  1. 平台探测(GitHub / GitLab / Perforce);
  2. 识别或创建 PR/MR/CL;
  3. 进入主循环(最多 5 次迭代,避免失控),每次迭代依次执行:
    • A. 触发 Greptile 评审并轮询完成;
    • B. 获取评审结果(置信度评分 + 未解决行内评论);
    • C. 检查退出条件;
    • D. 修复可操作的评论;
    • E. 解决已处理的讨论线程;
    • F. 提交、推送或重新 shelve;
  4. 输出结构化报告。

第一步:平台探测

Greploop 先检查 Perforce 环境,再回退到 git remote 探测:

# Check for Perforce environment if p4 info >/dev/null 2>&1; then VCS="perforce" else REMOTE_URL=$(git remote get-url origin) if echo "$REMOTE_URL" | grep -qi "gitlab"; then VCS="gitlab" else VCS="github" fi fi

两个值得注意的覆盖场景:

  • 自托管 GitLab 实例:如果主机名不包含gitlab字样,grep 探测会失败,此时通过传入--vcs gitlab覆盖。
  • Perforce:显式传入--vcs perforce。

第二步:识别或创建 PR/MR/CL

GitHub:优先查看,必要时自动创建草稿 PR

if PR_JSON=$(gh pr view --json number,headRefName -q '{number: .number, branch: .headRefName}' 2>/dev/null); then echo "$PR_JSON" else PR_JSON="" fi

如果PR_JSON为空(当前分支/worktree 没有对应 PR),代理会在启动循环前自动发布一个草稿 PR,但必须遵守三条纪律:

  1. 先检查git status --short并判断预期变更范围——不要静默暂存无关改动;若 worktree 混杂且意图不清晰,停下并向用户询问;
  2. 确保工作在评审分支上——若当前分支缺失、受保护、是默认分支或不合适,创建/切换到codex/<descriptive-name>分支;
  3. 仅暂存目标改动、必要时提交、推送分支并创建草稿 PR:
git switch -c codex/<descriptive-name> # only when a review branch is needed git add <intended-files-only> git commit -m "<concise change summary>" # only when there are staged changes git push -u origin HEAD gh pr create --draft --fill

GitLab:读取 MR

glab mr view --output json | jq '{iid: .iid, branch: .source_branch}'

若尚未处于 MR 分支,需要先切到对应分支。

Perforce:列出与描述 pending changelist

# List pending changelists for current user/client p4 changes -s pending -u $P4USER -c $P4CLIENT # Describe a specific CL p4 describe -s <CL_NUMBER>

操作前必须确保p4 clientworkspace 正确。

三个平台的关键字段差异(后续所有 API 调用都依赖这些标识):

平台标识分支字段提交 SHA
GitHubnumberheadRefNameheadRefOid
GitLabiid(内部编号,非id)source_branchsha
Perforcechangelist 编号P4CLIENTshelved 文件

第三步:主循环(Max 5 次迭代)

A. 触发 Greptile 评审

GitHub / GitLab先推送最新改动,Perforce则重新 shelve 以更新评审文件:

# GitHub/GitLab git push # Perforce: Re-shelve to update the shelved files for review p4 shelve -f -c <CL_NUMBER>

推送后等待检查启动:sleep 5。

GitHub 侧防重复触发:先检查 Greptile 是否已在运行,避免重复发评论:

GREPTILE_STATE=$(gh pr checks <PR_NUMBER> --json name,state | jq -r '.[] | select(.name | test("greptile"; "i")) | .state') if [ "$GREPTILE_STATE" != "PENDING" ] && [ "$GREPTILE_STATE" != "IN_PROGRESS" ]; then gh pr comment <PR_NUMBER> --body "@greptile review" fi

随后轮询 Greptile check run 直至完成:

HEAD_SHA=$(gh pr view <PR_NUMBER> --json headRefOid -q .headRefOid) while true; do GREPTILE_CHECK=$(gh api "repos/{owner}/{repo}/commits/$HEAD_SHA/check-runs" \ --jq '.check_runs[] | select(.name | test("greptile"; "i"))' 2>/dev/null) if [ -z "$GREPTILE_CHECK" ]; then echo "Waiting for Greptile check to appear..." sleep 5 continue fi STATUS=$(echo "$GREPTILE_CHECK" | jq -r '.status // "completed"') CONCLUSION=$(echo "$GREPTILE_CHECK" | jq -r '.conclusion // "pending"') if [ "$STATUS" = "completed" ]; then if [ "$CONCLUSION" = "success" ]; then echo "Greptile check passed!" else echo "Greptile check completed with: $CONCLUSION" fi break fi echo "Waiting for Greptile... (status: $STATUS)" sleep 10 done

GitLab 侧同样先判断是否有 pipeline 在跑:

PIPELINES=$(glab api "projects/:fullpath/merge_requests/<MR_IID>/pipelines") GREPTILE_RUNNING=$(echo "$PIPELINES" | jq '[.[] | select(.status == "running" or .status == "pending")] | length') if [ "$GREPTILE_RUNNING" = "0" ]; then glab mr note <MR_IID> --message "@greptile review" fi

再按提交 SHA 找到对应 pipeline,定位 Greptile job 并轮询至终态(success/failed/canceled),完整脚本见 SKILL.md 第 190–224 行。其中用到的 GitLab API 细节(:fullpath自动解析、pipeline/job 字段、分页约定)可在 .agents/skills/greploop/references/gitlab-api.md 中查到。

Perforce 侧:没有原生 check run。如果 Greptile 是通过p4 shelve触发的 webhook 集成,就等待其处理,并轮询 CL 上 Greptile 的评审评论直至出现评分。

B. 获取 Greptile 评审结果

Greptile 可能把评分放在两个位置(Perforce 是三个),必须全部检查,取最新的评分:

平台评分来源 1评分来源 2
GitHubPR description(body)PR reviews(找greptile-apps[bot]/greptile-apps-staging[bot]的最新条目)
GitLabMR description(description)MR notes(按author.username过滤,用户名因安装而异,首次运行需确认)
PerforceCL description(p4 describe -s中 Greptile 追加的评分块)Helix Swarm 评论 API(如GET /api/v11/comments?topic=reviews/<REVIEW_ID>,按user/body/flags字段过滤)
# GitHub: PR description gh pr view <PR_NUMBER> --json body -q '.body' # GitHub: PR reviews gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/reviews # GitLab: MR description glab mr view <MR_IID> --output json | jq -r '.description' # GitLab: MR notes glab api "projects/:fullpath/merge_requests/<MR_IID>/notes"

解析文本时关注两类信息:

  • 置信度评分:类似3/5或5/5(也可能写作Confidence: 3/5)的模式;
  • 评论数量:摘要中标注的行内评审评论条数。

随后拉取所有未解决的行内评论:

# GitHub gh api repos/{owner}/{repo}/pulls/<PR_NUMBER>/comments # GitLab glab api "projects/:fullpath/merge_requests/<MR_IID>/discussions"

GitLab 侧过滤条件:DiffNote类型、来自 Greptile、位于最新提交上、且"resolved": false。Swarm 侧则过滤未标记为 resolved/addressed 的 Greptile bot 评论。

C. 检查退出条件

满足以下任意一条即停止循环:

  • 置信度评分为5/5且零未解决评论;
  • 达到最大迭代次数(此时如实报告当前状态)。

D. 修复可操作的评论

对每条未解决评论:

  1. 读取对应文件,在上下文中理解评论;
  2. 判断它是可操作(需要改代码)还是信息性;
  3. 可操作则实施修复;
  4. 信息性评论或误报则记录说明,但仍然要解决该线程。

E. 解决线程

GitHub使用 GraphQL 分页拉取未解决线程(.agents/skills/greploop/references/graphql-queries.md 中给出了完整查询):

gh api graphql -f query=' query($cursor: String) { repository(owner: "OWNER", name: "REPO") { pullRequest(number: PR_NUMBER) { reviewThreads(first: 100, after: $cursor) { pageInfo { hasNextPage endCursor } nodes { id isResolved comments(first: 1) { nodes { body path author { login } } } } } } } }'

批量解决已处理的线程(利用 GraphQL 的别名语法一次提交多个 mutation):

gh api graphql -f query=' mutation { t1: resolveReviewThread(input: {threadId: "ID1"}) { thread { isResolved } } t2: resolveReviewThread(input: {threadId: "ID2"}) { thread { isResolved } } }'

GitLab逐条解决:先拉取"resolved": false的 discussions,再按id逐个 PUT(GitLab 不支持批量解决,必须循环):

glab api "projects/:fullpath/merge_requests/<MR_IID>/discussions?per_page=100" glab api --method PUT \ "projects/:fullpath/merge_requests/<MR_IID>/discussions/<DISCUSSION_ID>" \ --field resolved=true

GitLab 相关 API 的完整字段说明(notes[0].position.new_path文件路径、per_page分页直到数组长度小于per_page)见 .agents/skills/greploop/references/gitlab-api.md。

F. 提交、推送 / 重新 shelve

GitHub / GitLab提交前同样强调写集(write set)收敛:存在无关改动时禁止git add -A,只暂存目标文件,范围不清晰就停下询问:

git add <intended-files-only> git commit -m "address greptile review feedback (greploop iteration N)" git push

Perforce把改动重新纳入 CL 并 re-shelve:

p4 shelve -f -c <CL_NUMBER>

推送 / shelve 后sleep 5等待检查启动,然后回到步骤A进入下一轮迭代。

第四步:报告

循环退出后输出结构化总结:

字段值
PlatformGitHub / GitLab / Perforce
IterationsN
Final confidenceX/5
Comments resolvedN
Remaining commentsN(如有)

若因达到最大迭代次数退出,需列出剩余未解决评论并给出后续建议。

输出格式示例

满分达标:

Greploop complete. Platform: GitHub Iterations: 2 Confidence: 5/5 Resolved: 7 comments Remaining: 0

未完全解决(达到 5 次迭代上限):

Greploop stopped after 5 iterations. Platform: GitLab Confidence: 4/5 Resolved: 12 comments Remaining: 2 Remaining issues: - src/auth.ts:45 — "Consider rate limiting this endpoint" - src/db.ts:112 — "Missing index on user_id column"

Perforce 场景:

Greploop complete. Platform: Perforce Changelist: 12345 Iterations: 3 Confidence: 5/5 Resolved: 9 comments Remaining: 0

Codex 场景下的执行委托约定

SKILL.md 的第 0 步有一条重要的编排约定:当 Greploop 由 Codex 调用且子代理可用时,主代理必须默认把实际执行委托给子代理,并把探测到的 PR/MR/CL 标识、仓库/worktree 路径、当前分支、VCS 平台、用户范围约束以及已知的变更文件意图一并传下去。父代理只负责监控进度、转发简洁状态更新并汇报最终结果。仅当子代理不可用或环境无法委托时才由父代理直接执行。这保证了长循环任务不会阻塞主对话上下文。

工程实践要点与安全边界

通读整个技能可以发现几条刻意强调的纪律,任何把 Greploop 接入自己流水线的团队都值得沿用:

  • 循环上限 5 次:防止评分长期不达标时无限烧 CI 资源,超限时如实报告而不是假装成功;
  • 写集收敛:全程禁止无差别git add -A,只暂存“目标文件”或“Greptile 修复涉及的文件”,工作区混杂时停下询问,这是防止误提交无关改动的核心护栏;
  • 防重复触发:发@greptile review评论前先检查是否已有 check run / pipeline 在运行,避免并发评审造成混乱;
  • 结果双源校验:评分可能同时出现在描述与评论中,必须两处都查并以最新者为准;
  • 信息性评论也需解决线程:修复了代码才算完成,但信息性/误报评论记录说明后同样要 resolve,才能把“未解决评论数”清零。

与仓库的关系及进一步阅读

Greploop 作为可复用的 Agent 技能完整存放在.agents/skills/greploop/目录下,与仓库中的其他开发技能(如.agents/skills/elsa-release/、.agents/skills/speckit-*/)并列,属于仓库为 AI 代理开发的协作基础设施,而非 Elsa 运行时本身的业务代码。若要在 CI 中把 Greploop 固化为工作流,可以参考其官方脚本骨架编写.github/workflows/greploop.yml类配置。

建议继续阅读的仓库文件:

  • 技能主体:.agents/skills/greploop/SKILL.md
  • GitLab API 参考(MR、pipeline、job、notes、discussions 的完整调用与字段):.agents/skills/greploop/references/gitlab-api.md
  • GitHub GraphQL 参考(reviewThreads 分页查询与批量 resolve mutation):.agents/skills/greploop/references/graphql-queries.md
  • 许可证说明:.agents/skills/greploop/LICENSE
  • 后端
  • 工作流自动化
  • 流程编排
  • 低代码

【免费下载链接】elsa-core

The Workflow Engine for .NET

项目地址:https://gitcode.com/gh_mirrors/el/elsa-core
点击查看免费下载

相关推荐

上一篇:AssemblyScript + WASI 实战:用 Wasmtime 运行系统时间、stdin 输入、控制台输出与安全随机数
下一篇:如何在PC上完美运行Switch游戏:Yuzu模拟器完整使用教程

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询