- 后端
- 工作流自动化
- 流程编排
- 低代码
【免费下载链接】elsa-core
The Workflow Engine for .NET
导读
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 | 附加要求 |
|---|---|---|
| GitHub | git、gh(已认证) | 仓库已安装 Greptile,greptile-apps[bot]或greptile-apps-staging[bot]参与评审 |
| GitLab | git、glab(已认证) | 仓库已安装 Greptile,Greptile 作为 pipeline job 运行 |
| Perforce | p4(已认证) | 正确的p4 clientworkspace,Greptile 通过 webhook 或 Swarm 集成 |
输入
Greploop 唯一可选输入是PR/MR/CL 编号。若未提供,则由代理自动探测:为当前分支查找对应的 PR/MR,或为 Perforce 查找默认的 pending changelist。
总体流程:六步闭环
Greploop 的执行主线由以下步骤组成:
- 平台探测(GitHub / GitLab / Perforce);
- 识别或创建 PR/MR/CL;
- 进入主循环(最多 5 次迭代,避免失控),每次迭代依次执行:
- A. 触发 Greptile 评审并轮询完成;
- B. 获取评审结果(置信度评分 + 未解决行内评论);
- C. 检查退出条件;
- D. 修复可操作的评论;
- E. 解决已处理的讨论线程;
- F. 提交、推送或重新 shelve;
- 输出结构化报告。
第一步:平台探测
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,但必须遵守三条纪律:
- 先检查
git status --short并判断预期变更范围——不要静默暂存无关改动;若 worktree 混杂且意图不清晰,停下并向用户询问; - 确保工作在评审分支上——若当前分支缺失、受保护、是默认分支或不合适,创建/切换到
codex/<descriptive-name>分支; - 仅暂存目标改动、必要时提交、推送分支并创建草稿 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 --fillGitLab:读取 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 |
|---|---|---|---|
| GitHub | number | headRefName | headRefOid |
| GitLab | iid(内部编号,非id) | source_branch | sha |
| Perforce | changelist 编号 | P4CLIENT | shelved 文件 |
第三步:主循环(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 doneGitLab 侧同样先判断是否有 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 |
|---|---|---|
| GitHub | PR description(body) | PR reviews(找greptile-apps[bot]/greptile-apps-staging[bot]的最新条目) |
| GitLab | MR description(description) | MR notes(按author.username过滤,用户名因安装而异,首次运行需确认) |
| Perforce | CL 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. 修复可操作的评论
对每条未解决评论:
- 读取对应文件,在上下文中理解评论;
- 判断它是可操作(需要改代码)还是信息性;
- 可操作则实施修复;
- 信息性评论或误报则记录说明,但仍然要解决该线程。
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=trueGitLab 相关 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 pushPerforce把改动重新纳入 CL 并 re-shelve:
p4 shelve -f -c <CL_NUMBER>推送 / shelve 后sleep 5等待检查启动,然后回到步骤A进入下一轮迭代。
第四步:报告
循环退出后输出结构化总结:
| 字段 | 值 |
|---|---|
| Platform | GitHub / GitLab / Perforce |
| Iterations | N |
| Final confidence | X/5 |
| Comments resolved | N |
| Remaining comments | N(如有) |
若因达到最大迭代次数退出,需列出剩余未解决评论并给出后续建议。
输出格式示例
满分达标:
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: 0Codex 场景下的执行委托约定
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
相关推荐
Greploop 实战指南:基于 Greptile 自动化 PR/MR/CL 审查迭代闭环,直至 5/5 满分通过
Greploop 实战指南:基于 Greptile 自动化 PR/MR/CL 审查迭代闭环,直至 5/5 满分通过 导读 Greploop 是本仓库(Onyx/
AI 应用大模型RAGAI Agent后端前端企业级多模态智能体系统架构设计与部署实践
企业级多模态智能体系统架构设计与部署实践 UI TARS桌面应用作为基于视觉语言模型(VLM)的多模态AI代理栈,将GUI智能体能力与视觉识别技术深度融合,为技
后端工作流自动化流程编排低代码GitHub GraphQL 查询实战:在 Greptile 自动代码审查中获取与批量解决 PR 评审线程
GitHub GraphQL 查询实战:在 Greptile 自动代码审查中获取与批量解决 PR 评审线程 本文基于 danswer 仓库内置的 Greptil
AI 应用大模型RAGAI Agent后端前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考