aibug
Skill4 starsChanged 26 days agoApache-2.0View on GitHub
连接 aibug 系统,循环自动修复 PENDING 状态的 Bug。依次执行:登录获取 token → 获取下一个 Bug → 分析代码并修复 → 更新状态(AI_FIXED/AI_PARTIALLY_FIXED/FAILED),直到无更多待处理 Bug;可用 --bug-id=N[,N…] 只处理指定条目(任意原状态)。必须配合 aibug 系统使用。支持 /aibug -h 查看帮助。
- Sends data out
In this repository14 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- aicaseSkill
- api-testSkill
- common-rulesSkill
- db-compareSkill
- do-security-checkSkill
- do-testSkill
- git-summarySkill
- new-android-buildSkill
- new-deploySkill
- new-java-projectSkill
- new-macos-buildSkill
- new-nginx-confSkill
- new-test-caseSkill
The file
Files
aibug
自动连接 aibug Bug 管理系统,循环获取并修复 PENDING 状态的 Bug,直到队列为空。
触发条件:用户要求自动修复 Bug、接入 aibug 系统,或说"开始修 Bug"。
执行方式:必须串行执行,禁止并行。 同一时刻只允许一个本 skill 实例;每条 Bug 通过子 agent 处理,严格逐条串行——上一条 Bug 完成状态回传(AI_FIXED / AI_PARTIALLY_FIXED / FAILED)并回读确认后,才可为下一条 Bug 启动子 agent。禁止并行启动多个实例、并行启动多个子 agent 同时处理不同 Bug,也禁止与 /aicase、/do-test 并发运行。
零、参数处理
如果用户传入 -h 或 --help,不执行任何操作,直接把下面的帮助信息原样输出在本次回复正文里后结束
——斜杠命令把 SKILL.md 注入我的上下文不等于已展示给你,正文里只回一句"已输出/已同步"就是没输出。
-h 与其它参数或说明文字同时出现时,一律只出帮助、忽略其余参数:本轮不猜附加要求,需要同时执行就把
-h 去掉分两次调用。
用法: /aibug [选项]
选项(通过命令行传入的参数直接使用,不再交互询问)
--host=URL aibug 系统 Base URL(如 --host=http://your-server:8082)
--username=NAME 登录账号
--password=PASS 登录密码
--project-id=N 项目 ID(必填,未指定直接报错;如 --project-id=1)
--bug-id=N[,N…] 只处理指定 Bug(可选,正整数;逗号分隔可给多个,如 --bug-id=170,172,
仍严格逐条串行;指定后跳过队列,状态按各自 #bugId 回写)
-h, --help 显示本帮助(出现即忽略其它参数,只出帮助)
工作流程
1. POST {host}/aibug/api/auth/login 登录,获取 token(请求体程序内组装,口令不写成 JSON 连写进命令行)
2. GET {host}/aibug/api/bugs/next 获取下一个 PENDING Bug
(传了 --bug-id 时改为按清单逐个 GET {host}/aibug/api/bugs/<id> 取卡,不限当前状态)
3. PUT {host}/aibug/api/bugs/{id}/status 标记为 IN_PROGRESS(队列与指定模式都执行)
4. 委托子智能体分析 Bug 并修复;每修复一个即刻验证(编译/构建/复测),
验证通过才可标记 AI_FIXED / AI_PARTIALLY_FIXED,禁止最后统一验证;
代码中已有修复、本轮无需改动(已修复/重复修复)时,按原现象复验通过即回传 AI_FIXED,不回传 FAILED
5. PUT {host}/aibug/api/bugs/{id}/status 标记为 AI_FIXED、AI_PARTIALLY_FIXED
(必填 fixNote)或 FAILED(必填 failReason);说明字段按固定标签分行填写,
纯文本不写 markdown 标记(弹窗按 markdown 渲染,可选贴 http/站内链接)
{id} 一律取当前 Bug 卡的 #bugId,只允许该单条接口,禁用 /bugs/batch/status
6. 循环回到第 2 步,直到无更多 PENDING Bug(指定模式:清单里还有 ID 就取下一个,全部走完即结束)
Bug 字段说明
id Bug 唯一 ID
content Bug 描述文本(说明需要修复的内容)
fileUrls 附件相对路径(截图等,相对于 host)
status 当前状态:PENDING(待处理)/ IN_PROGRESS(处理中)
/ AI_FIXED(AI 修复)/ AI_PARTIALLY_FIXED(部分修复,徽标显示「AI 半修」)/ FAILED(失败)
/ RESOLVED(已解决,人工闭环状态,本 skill 不回传)/ CLOSED(已关闭)
failReason 失败原因(状态为 FAILED 时必填),固定三行纯文本:
现象 / 定位 / 下一步
fixNote 部分修复说明(状态为 AI_PARTIALLY_FIXED 时必填),固定三行纯文本:
已修复 / 待修复 / 验证
示例
/aibug --host=http://your-server:8082 --username=admin --password=secret --project-id=1
/aibug --host=... --username=... --password=... --project-id=1 --bug-id=170,172
/aibug -h一、收集参数
1.1 解析命令行参数
| 命令行写法 | 对应参数 |
--host=URL | HOST(必填,无默认值) |
--username=NAME | USERNAME(必填,无默认值) |
--password=PASS | PASSWORD(必填,无默认值) |
--project-id=N | PROJECT_ID(必填,无默认值) |
--bug-id=N[,N…] | BUG_IDS(可选,正整数,逗号分隔可给多个;指定后只处理这些 Bug,跳过 /bugs/next 队列,状态按各自 #bugId 逐条回写) |
1.2 参数校验与补齐
PROJECT_ID必须通过--project-id=N显式指定:未指定时直接报错终止(输出错误:缺少 --project-id=N,必须指定项目 ID),不交互询问、不继续执行。BUG_IDS可选,逗号分隔的 ID 清单(如--bug-id=170或--bug-id=170,172,185):每段都必须是正整数, 任一段非法(非数字、0、负数、带空格、空段、多余逗号)直接报错终止(输出错误:--bug-id 必须为正整数或逗号分隔的正整数列表), 不静默忽略、不退回队列模式;清单去重后按用户给定顺序逐条串行处理,不重排、不按状态排序。PASSWORD仍由--password=PASS传入(不新增其它口令参数):口令值只用于登录那一次请求, 装配请求体的方式见第二节——不得以"password":"<值>"的连写形态出现在命令行。- 其余必填参数缺失时一次性列出,统一交互询问:
| 参数 | 说明 |
HOST | aibug 系统 Base URL,如 http://your-server:8082 |
USERNAME | 登录账号 |
PASSWORD | 登录密码 |
所有参数确定后,向用户回显参数列表(密码替换为 ****),确认后开始执行。
二、认证
顺序硬约束:先登录 → 取到 token → 才允许访问任何其它接口。 登录未成功(含响应含 error、HTTP 非 200、
token 字段缺失或为空)之前,禁止发起 /bugs/next、/bugs/{id} 等任何请求,也不得"先拿空 token 试一下"。
请求体禁止内联凭据(必做):--password 传进来的值先落到 shell 变量,再交给程序组装,禁止把口令
字面量写进 curl 的 -d / --data-raw / URL,即命令行里不得出现 "password":"<值>" 这种连写形态。命令执行链
上的凭据脱敏会把该形态的值改写成 ***(3 字符),服务端按 BCrypt 正常拒绝,返回 401 + 用户名或密码错误
——文案与"真的口令错"完全一致,从响应体无从区分。请求体一律在程序内用 json.dumps 组装:
python3 - "$HOST" "$USERNAME" "$PASSWORD" <<'PY'
import hashlib, json, sys, urllib.error, urllib.request
host, user, pw = sys.argv[1], sys.argv[2], sys.argv[3]
body = json.dumps({"username": user, "password": pw}).encode()
print(f"body_bytes={len(body)} pw_len={len(pw)} pw_sha={hashlib.sha256(pw.encode()).hexdigest()[:12]}")
req = urllib.request.Request(f"{host}/aibug/api/auth/login", data=body,
headers={"Content-Type": "application/json"})
try:
with urllib.request.urlopen(req) as r:
print(f"http={r.status} token_len={len(json.loads(r.read())['token'])}")
except urllib.error.HTTPError as e:
print(f"http={e.code} error={e.read().decode()[:120]}")
except urllib.error.URLError as e:
print(f"http=none 连接失败={e.reason}") # 地址/服务问题,与口令无关
PY上述输出同时给出口令长度与 sha 前 12 位,够做自检,不泄露原文。
响应(成功,200):
{"id": 1, "username": "admin", "displayName": "管理员", "token": "<TOKEN>"}- 登录成功即把
token存入变量,之后每个请求都带Authorization: Bearer <token>。 - 判为"凭据问题"之前,必须先做传参自检(三项全过才可以对用户说口令有误,否则就是假阴性死循环——用户给对
口令也没用):
① 核对实际发出的请求体字节数与预期一致(上面的
body_bytes对比按明文口令算出的len(json.dumps(...)))。被改写成***时差值恒为 4(带引号的口令 9 字节 →"***"5 字节,即原口令 7 字符),但绝对值 随 JSON 分隔符风格变:紧凑写法{"username":"admin",...}是 41 → 37,json.dumps默认带空格是 44 → 40,所以要比的是同一组装方式下"预期 vs 实际发出",别拿别处的绝对值来对; ② 换一种不经 shell 引号与脱敏的发送姿势复测(按上面程序内组装 body 的 urllib 写法); ③ 两种姿势结果不一致 → 结论是本地传参链路问题:改用程序内组装 body 的姿势重发,不得向用户索取口令、 不得计入登录失败次数;两种姿势一致且自检通过仍 401,才允许判定为凭据问题。 - 失败按状态码分型处理(报告里必须同时写出状态码与响应体,只抄 message 无法定位):
400:请求构造问题——字段名写错、缺Content-Type: application/json、body 不是合法 JSON(服务端@Valid @RequestBody校验失败)。属可自纠项,改正后最多重试一次。401+用户名或密码错误:先过上面的传参自检,确认不是本地改写之后才按凭据问题处理。服务端只有 "用户不存在"与"口令不匹配"两条路径且都返回同一句话(AuthService.login),分不清是哪一种,也不许猜。 确认后立即停止,向用户报告并索取正确口令;不得换口令反复尝试、不得对同一账号刷登录。- 连接失败 / 超时 / 非 JSON 响应:地址或服务问题,与口令无关,按未开始如实报告。
- 服务端没有失败次数锁定机制,一次失败不会锁号;但同上,凭据错误只能问用户要,不能靠重试解决。
- 后续任一请求返回
401(token 过期或失效):允许重新登录一次刷新 token 后继续该请求;再失败即停止并报告。 - 含凭据或令牌的响应一律不落盘(通用约束,不只管 token):不写
/tmp、不写工程runtime/、不写任何 文件,只在当前 shell 变量或程序内存里用;Authorization头与 token 值不进报告、日志、台账与 commit。 口令同理,用到即弃。
三、修复循环
以下步骤循环执行,直到无更多 PENDING Bug 为止。指定模式(传了 BUG_IDS)按清单逐条走一遍:每个 #bugId 都完成 3.3 判定并经 3.4 回读确认后才取下一个,全部走完即结束整个流程,不回队列。
执行过程输出要求(必做)
每轮循环对每个实际 API 调用向用户输出一行记录,只含 方法 + 路径 + 结果,禁止输出完整 curl 命令、请求头与 JSON 原文:
[登录] POST /aibug/api/auth/login → 200,token 长度 72
[取 Bug] GET /aibug/api/bugs/next?projectId={PROJECT_ID} → 200,#<id>
[回传状态] PUT /aibug/api/bugs/{id}/status → 200,status=IN_PROGRESS
[回读确认] GET /aibug/api/bugs/{id} → 200,status=IN_PROGRESS
[回传状态] PUT /aibug/api/bugs/{id}/status → 200,status=AI_PARTIALLY_FIXED,fixNote=已修复/待修复/验证
[回读确认] GET /aibug/api/bugs/{id} → 200,status=AI_PARTIALLY_FIXED,fixNote 三行逐行一致[登录]行每轮开头记一次;失败时写→ <http>,<error>,并追加一句传参自检:已做(本地改写已排除/未排除)或传参自检:未做——没做自检就不能只写"口令错误"。- 路径中
{PROJECT_ID}、{id}替换为真实值;token 值与 Authorization 头一律不出现(只允许写 token 长度)。 fixNote/failReason是多行结构化字段,输出行里只标注标签序列(如fixNote=已修复/待修复/验证),不在这里展开正文,正文由 3.4 的回读验证逐行比对。- 非 200 或响应含
error时在同一行追加一句话原因,不重试转述响应体。 - 同一轮内
[取 Bug]、[回传状态]、[回读确认]三行的#<id>必须完全一致(都等于当前 Bug 卡的id);不一致立即停手,按"状态回写寻址约束"处理。
状态回写寻址约束(必做)
所有状态写入只认当前 Bug 卡的 #bugId,一次只改一条:
- 唯一合法通道:
PUT {HOST}/aibug/api/bugs/{CURRENT_ID}/status,{CURRENT_ID}逐字等于本轮 Bug 卡的id(队列模式取/bugs/next的返回值;指定模式取当前正在处理的那个清单 ID,多 ID 时逐条切换,绝不把上一条的 ID 接到下一条上);回读同样用该 ID 的GET {HOST}/aibug/api/bugs/{CURRENT_ID} - 全文示例里的
{id}与{CURRENT_ID}同义,都指当前 Bug 卡的id,不存在第二个 ID 变量(参数解析里的清单变量统一叫BUG_IDS,处理到哪一条,{id}就是哪一条) - 禁止批量接口
PUT {HOST}/aibug/api/bugs/batch/status(body 用ids数组一次改多条,无法保证落点),任何情形都不使用 - 禁止从对话历史、台账、上一条 Bug 的结论或子智能体返回文本里推断 ID:
{CURRENT_ID}只由主循环从取卡响应里确定,子智能体只回传结论,回写由主循环发起 - 发起 PUT 前先回显一行
#<id> → 即将回写 <状态>;PUT 路径、PUT 响应里的id、回读路径三处必须完全相同 - 出现任一不一致(回读
id≠ 提交id、读到的是其它 Bug、PUT 响应含error)→ 立即终止本轮;指定模式下(无论单 ID 还是清单里第几条)一律停止整个执行,剩余 ID 不再处理——回写落点异常属系统级故障,继续跑只会扩大误写面,记台账#<id> → 回写 ID 不一致,已终止,列入完成汇总的"回写异常"清单;不带猜测重试、不改写任何其它 Bug 的状态 - 重复报单(多条 Bug 指向同一问题点)时,逐条各自回写各自的
#id,不得只回写一条或把结论写到另一条上
上下文与权重控制(全程必做)
上下文增长优化(防止长循环撑爆上下文窗口):
- 子智能体隔离:3.3 的分析与修复默认委托给子智能体(Agent 工具)执行——子智能体拥有独立上下文,定位/阅读/修改代码的完整过程不进入主循环;主循环只接收结构化结果(常规 4 行,
AI_PARTIALLY_FIXED/FAILED追加 3 行回写字段)。 - 响应瘦身:所有 API 响应只保留
id、content(≤500 字,超长截断)、fileUrls、status、fixNote、error字段;禁止把完整 JSON 原文粘进对话。 - 台账式记录:主循环只维护一行式台账
#<id>(原状态 <X>)→ AI_FIXED/AI_PARTIALLY_FIXED/FAILED(AI_FIXED 中本轮零改动的已修复/重复修复追加标注AI_FIXED(已修复,无改动:<文件:行>)、AI_PARTIALLY_FIXED 摘 fixNote 的"待修复"行、FAILED 摘 failReason 的"定位"行),异常终止写#<id>(原状态 <X>)→ 异常终止,卡在 IN_PROGRESS。指定模式(--bug-id)里"原状态"与取卡时的fixNote/failReason原文是用户回退的唯一依据,必须逐字保留(过长可另起一行按#<id>挂在台账下方,禁止只写"已摘要");其余情形不保留分析细节,也不在台账里重复整段回写字段。 - 定期压缩:每处理完 5 个 Bug,或感知上下文占用约 60% 时,执行一次
/compact,并明确要求保留:连接参数与 token、台账表、当前未完成 Bug 的状态。
当前 Bug 信息权重优先(当前需求/bug 信息高于历史上下文):
- Bug 卡先行:开始处理每个 Bug 时,先输出"当前 Bug 卡"(
#id / content / fileUrls / 目标状态);该 Bug 的处理全程以卡内信息为唯一事实来源。 - 禁止串味:当前 Bug 卡与之前 Bug 的结论、历史对话、经验假设冲突时,一律以当前 Bug 卡为准;不复用上一个 Bug 的定位结果、根因判断或修复方案。
- 干净上下文:子智能体 prompt 只包含当前 Bug 卡 + 工程路径 + 修复约束,不携带任何历史 Bug 信息,天然保证当前需求获得最高权重。
3.1 获取下一个 Bug
指定模式(传了 BUG_IDS):跳过本步的队列拉取,按清单顺序逐个 #bugId 取卡,一次只处理一条(当前这条走完才取下一条):
# 对 BUG_IDS 里的每个 ID 各执行一次(记为 {CURRENT_ID},严格串行)
curl -s "{HOST}/aibug/api/bugs/{CURRENT_ID}" \
-H "Authorization: Bearer <token>"- 响应含
error、404 或id不等于该#bugId→ 单 ID 时直接报错终止(输出错误:#<id> 不存在或不可读);多 ID 时该条记台账#<id> → 不存在或不可读,已跳过、不改其状态,继续清单下一条,全部走完列入汇总,不转队列模式; projectId与PROJECT_ID不一致 → 同上(单 ID 报错终止、多 ID 记异常跳过该条),防止跨项目误回写;- 不限当前状态:
PENDING / IN_PROGRESS / AI_FIXED / AI_PARTIALLY_FIXED / FAILED / RESOLVED / CLOSED均可重新处理,本轮终态覆盖原状态;覆盖前先向用户明示#<id> <原状态> → <本轮判定状态>,并把原状态与原有fixNote/failReason原文记入台账(服务端在其它状态下会清空说明字段,落库后不可恢复);3.2 的预标记一旦发生,本轮任何异常终止都会让该条停在IN_PROGRESS、脱离/bugs/next队列,善后见 3.2 末与第四节"异常终止"清单; - 该条处理完(3.4 回读确认通过)后,清单里还有未处理 ID 就取下一个,否则进入完成输出,不回到本步拉队列。
队列模式(未传 BUG_IDS):按下述流程循环拉取 PENDING 清单。
curl -s "{HOST}/aibug/api/bugs/next?projectId={PROJECT_ID}" \
-H "Authorization: Bearer <token>"响应(有 Bug):
{
"id": 6,
"content": "Bug 描述文本",
"fileUrls": "/images/202608/xxx.png",
"filePaths": "/data/aibug/images/202608/xxx.png",
"status": "PENDING",
"fixNote": null,
"projectId": 1,
...
}响应(无更多 Bug):返回 HTTP 204(No Content,无响应体);出现 204、或 4xx、或响应含 error 时,退出循环,向用户报告"所有 Bug 已处理完毕"。
项目校验(必做):取到 Bug 后立即将响应中的 projectId 与命令行 PROJECT_ID 比对:
- 一致 → 进入 3.2;
- 不一致 → 不更新该 Bug 状态,记台账
#<id> → 项目校验不通过(projectId=<实际值> ≠ <PROJECT_ID>),跳过该 Bug,回到本步取下一个; - 若再次取回同一 Bug ID(服务端过滤异常),立即终止循环并向用户告警,该记录列入完成汇总的"项目校验不通过"清单,防止死循环。
3.2 标记为 IN_PROGRESS
获取到 Bug 后(队列模式与指定模式一律,含 --bug-id 清单里的每一条),立即更新状态,防止被重复领取:
curl -s -X PUT "{HOST}/aibug/api/bugs/{id}/status" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"status":"IN_PROGRESS","projectId":{PROJECT_ID}}'回读验证(必做):PUT 后立即回读,确认状态确实落库,防止"提示成功、实际未生效":
curl -s "{HOST}/aibug/api/bugs/{id}" \
-H "Authorization: Bearer <token>"- 响应中
status必须为IN_PROGRESS,否则重试一次;仍不一致则停止处理该 Bug,向用户报告不一致详情。 - 预标记后的异常终止善后(必做):本轮无论因何中止(用户中断、3.3 判不出结果、token 重登后仍 401、上面这条回读两次不一致),该条都会停在
IN_PROGRESS——队列模式下它不再被/bugs/next下发,指定模式下它已盖掉CLOSED/RESOLVED/AI_FIXED等原状态。台账与第四节"异常终止"清单必须写明#<id> 卡在 IN_PROGRESS,原状态 <X>,fixNote/failReason 原文 <台账原文>,提示用户到 aibug 界面改回;不得自行把它改回原状态或PENDING(本 skill 只回写AI_FIXED/AI_PARTIALLY_FIXED/FAILED),也不得臆造一条新的 PUT。
3.3 分析并修复 Bug(子智能体隔离)
默认方式:委托子智能体(Agent 工具,subagent_type 用 general-purpose),prompt 只包含:
- 当前 Bug 卡:
#id、content(原文)、附件完整地址({HOST}{fileUrls},如有) - 禁止子智能体碰 aibug 接口(写进 prompt 的硬约束):不得调用登录、
/bugs/next、/bugs/{id}、/bugs/{id}/status等任何 aibug API,不得自行取卡、改状态或回写说明字段;只做代码定位 / 修改 / 验证, 按 3.3 格式回传结构化结论。取卡与回写只由主循环发起——子智能体若自己拿内联口令去 curl,会撞上第二节那个 脱敏改写坑,并把"登录失败"的错误结论带回主循环。 - 工程根路径,以及约束:最小化修复、只改代码不执行 git commit、修复后必须验证、按下方三态判定标准给出结果、
AI_PARTIALLY_FIXED/FAILED必须按 3.4 的三行标签结构回写说明字段,且字段值是纯文本(这两个字段在 aibug 弹窗按 markdown 渲染,除可选的 http/站内链接外不得带任何 markdown 标记)、无法修复时明确说明原因
串行约束(必做):每条 Bug 单独委托一个子智能体,同一时刻最多只有一个子智能体在运行;当前子智能体返回结果并记入台账后,才可为下一条 Bug 启动新的子智能体,禁止同时派出多个子智能体并行修复。
要求子智能体以下列固定格式返回(常规 4 行,修改文件 可占多行;结果为 AI_PARTIALLY_FIXED / FAILED 时必须追加对应的 3 行结构化回写字段),主循环只把结论记入台账,并按原样把回写字段提交给服务端,禁止改写成一段连续文字:
结果: AI_FIXED | AI_PARTIALLY_FIXED | FAILED
修改文件: <逐行列出;FAILED 写 无;已修复/重复修复写 无(已存在修复:<文件:行 或 接口>)>
验证: <验证方式> → 通过 | 失败
说明: <一句话根因>
回写字段(fixNote): <仅 AI_PARTIALLY_FIXED,按 3.4 三行结构:已修复 / 待修复 / 验证>
回写字段(failReason): <仅 FAILED,按 3.4 三行结构:现象 / 定位 / 下一步>结果 为 AI_FIXED 时两个回写字段都省略;缺行、标签改名、把多点写成一段散文、或字段值里带 markdown 标记(加粗/行内代码/表格/引用/行首 #、-、*、数字./空行/代码块围栏),一律视为格式不合规退回子智能体按结构重发,主循环不得自行拼句子补全或直接提交。
三态判定标准(写入子智能体 prompt,必须逐点核对):把 content 拆成独立问题点逐条核对——
- 全部问题点均已修复且验证通过 →
AI_FIXED - 仅部分问题点修复(如只覆盖一端/一条路径/一个接口,其余点未处理或需外部系统、需产品决策配合)→
AI_PARTIALLY_FIXED,并按回写字段(fixNote)写满三行,已修复行必须是本轮验证通过的内容 - 该改的一点没改、或修复后验证不通过 →
FAILED,并按回写字段(failReason)写满三行(本轮无改动但复验确认原现象已消失的,按下方"已修复 / 重复修复"判AI_FIXED,不归入本条)
禁止把已全量修好且验证通过的 Bug 报成 AI_PARTIALLY_FIXED(避免虚增人工待办),也禁止用 AI_PARTIALLY_FIXED 掩盖验证失败。
已修复 / 重复修复(写入子智能体 prompt,与三态同级判定):定位后发现所报问题点在现有代码中已经修复(历史提交已覆盖、上一轮修复后状态回传失败被重新领取、同一问题被重复报单),本轮无需任何改动时,判定只看按原现象的实测复验,与常规验证方式相同(编译/构建/接口 curl/相关测试)——
- 复验确认
content描述的现象已不再出现 →结果: AI_FIXED、验证: <验证方式> → 通过,修改文件行写无(已存在修复:<文件:行 或 接口>),说明行写清来源(历史提交已覆盖/与 #<id> 重复报单/上一轮未回传状态);禁止因"本轮没改代码"报FAILED或AI_PARTIALLY_FIXED - 复验仍能复现现象 → 不算已修复,回到上面三态正常判定(该改的改,改完复验;确实修不了才
FAILED) - 既无法复现也无从验证(缺环境/缺数据/必须人工操作)→ 不视为已修复,按
FAILED走,定位行写明阻塞点
同一问题点被报成多条 Bug 时,每条按自己的 #id 独立回传 AI_FIXED(服务端各条状态互不影响),不做"只回传一条、其余跳过"。
子智能体内部执行:理解 content → 查看附件图片(如有)→ 定位代码 → Edit/Write 最小化修复 → 即刻验证(必做):修复完成后在同一轮内立即验证,验证通过才返回结果,然后才进入 3.4 更新状态、再取下一个 Bug;禁止把验证推迟到所有 Bug 修复完后统一做。验证方式按工程类型选最低成本——Java 工程 mvn -q -DskipTests compile 编译通过;前端工程构建或 lint 通过;Bug 指向具体接口时用 curl 复测该接口行为符合描述预期;工程有相关测试则运行对应测试。验证未通过则继续修复直至通过,仍无法通过则如实报告 验证: 失败,不得虚报 AI_FIXED。
回退方式(无法使用子智能体时):主循环内联执行上述四步,但必须遵守"上下文与权重控制"——响应与文件内容只截取相关片段,不把大段原文粘进对话。
3.4 更新 Bug 状态
按 3.3 的三态判定结果回传,一次 PUT 一个终态:
| 子智能体结果 | 回传状态 | 必填说明字段 |
结果: AI_FIXED + 验证: 通过,问题点全部覆盖 | AI_FIXED | 无 |
结果: AI_FIXED + 验证: 通过,本轮零改动(已修复/重复修复) | AI_FIXED | 无 |
结果: AI_PARTIALLY_FIXED + 已修复部分 验证: 通过 | AI_PARTIALLY_FIXED | fixNote |
结果: FAILED,或复验仍不通过 | FAILED | failReason |
标记 AI_FIXED 的前提:该 Bug 的验证已在本轮修复后即刻完成(不是全部修完后统一验证),且子智能体结果同时满足 结果: AI_FIXED 与 验证: 通过。已修复 / 重复修复同样满足该前提——本轮虽无代码改动,但按 content 原现象做的复验就是本轮验证,通过即按该 Bug 的 #id 正常回传 AI_FIXED(复用下方"全部修复"的 PUT 命令),不得标 FAILED、也不得为"留痕"改成 AI_PARTIALLY_FIXED(服务端 AI_FIXED 状态不保存说明字段,判据只留在台账与本轮汇总)。若 验证: 失败,退回子智能体追加修复一轮(携带失败现象),复验仍失败则标记 FAILED,failReason 按下文三行结构填写,现象 行写"修复后复验未通过:<验证方式与失败现象>"。
全部修复 → 标记为 AI_FIXED:
curl -s -X PUT "{HOST}/aibug/api/bugs/{id}/status" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"status":"AI_FIXED","projectId":{PROJECT_ID}}'部分修复 → 标记为 AI_PARTIALLY_FIXED,并填写 fixNote(必填,缺失服务端返回 400):
curl -s -X PUT "{HOST}/aibug/api/bugs/{id}/status" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"status":"AI_PARTIALLY_FIXED","projectId":{PROJECT_ID},"fixNote":"已修复:<…>\n待修复:<…>\n验证:<…> → 通过"}'无法修复 → 标记为 FAILED,并填写 failReason(必填):
curl -s -X PUT "{HOST}/aibug/api/bugs/{id}/status" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"status":"FAILED","projectId":{PROJECT_ID},"failReason":"现象:<…>\n定位:<…>\n下一步:<…>"}'说明字段结构化写法(fixNote / failReason 通用,必做)
禁止把多处信息揉进一段连续文字,两个字段都按固定标签分行书写。aibug 查看弹窗对这两个字段(含 Bug content)走 markdown 渲染(react-markdown + remark-gfm + remark-breaks),因此字段值要同时满足下面三组规则。
分行结构:
- 一行一个标签,标签固定不可改名、不可省略、不可合并;一行只写一件事
- 值内用单个
\n分行提交(JSON 里写\n)即可断行——remark-breaks已生效,不需要行尾补两个空格,也不需要加空行 - 单行 ≤60 字符、整体 ≤200 字符(按字符数,含路径与接口名;markdown 链接语法里的地址不计入单行 60 字符,但仍计入 200 字符总长);只写问题点级别的事实,不贴代码、不写排查过程叙述
- 位置与接口写成
文件:行(如BugServiceImpl.java:88)、GET /api/bugs这类裸文本,不用反引号包裹 - 列表页的说明行仍是单行截断纯文本(不走 markdown),因此第一行(
已修复/现象)必须单独看懂,不能依赖后两行才成立
markdown 规避(以下按实测渲染结果给出,写错比一段散文更乱):
- 禁止 markdown 标记语法:
**加粗**渲染成粗体、反引号渲染成行内代码、|渲染成表格(叠加remark-breaks还会把表格行打断)、>渲染成引用块、成对的*或_渲染成斜体、~~x~~渲染成删除线。字段值一律裸文本,不为"好看"加任何标记 - 禁止行首
#+ 空格(# 165 …、## 待修复 …):实测渲染成一级/二级大标题。#165 修复…(#紧跟字符)实测仍是正文,但为免误加空格,Bug ID 统一放行内(已修复:#165 …)或写Bug 165 - 禁止行首
-、+、*、数字.:实测解析成列表项,缩进错位;待修复/下一步行的多个并列点仍在同一行内用;分隔,不要改写成 markdown 列表 - 禁止代码块围栏(连续三个反引号):整段渲染成
<pre><code>黑底块,还会把缩进带进弹窗 - 禁止空行:连续两个
\n会切成两个<p>、段间距把三行撑散;一个标签行内也不许有裸换行 - 尖括号不必回避,但注意自动链接形态:实测
<500ms、a<b、甚至<b>加粗</b>都会被转义成正文字面显示(组件未启用 raw HTML),不会被吞;只有<https://example.com/x>这种尖括号包 URL 的写法会变成自动链接。要写地址就用下面"允许且建议使用"的 markdown 链接语法 - 两处下划线/星号分别出现在不同标签行也不会配对成斜体(实测
deleted_flag跨行两例仍为正文),但同一行内成对就会,命名尽量只用下划线连接、不加对仗符号
允许且建议使用:待修复 / 下一步 行可以贴 markdown 链接指向复现截图或外部工单,如 [复现截图](/images/202608/xxx.png)——实测渲染成 <a href="/images/202608/x.png">(相对路径原样保留进 href),弹窗内新窗口打开(组件已带 rel="noopener noreferrer");/images/ 由 nginx 三套环境统一指向 /data/aibug/images/,站内相对路径可直接用。禁止 javascript:、data: 与 base64 内联图:组件的 URL 过滤只放行 http/https/irc/ircs/mailto/xmpp 与相对路径,实测 [点我](javascript:alert(1)) 渲染成空 href、base64 内联图渲染成空 src 的 <img>(浏览器还会报空 src 警告),点了没反应还白占 200 字符预算。
fixNote 固定三行:
| 行 | 标签 | 内容 |
| 1 | 已修复 | 问题点 → 改动位置(文件:行 / 接口 / 页面),只写本轮已验证通过的部分 |
| 2 | 待修复 | 未覆盖的问题点 → 未做原因(缺文件 / 依赖外部系统 / 需产品确认),禁止写"其余部分"这类空话 |
| 3 | 验证 | 验证方式 → 通过 |
failReason 固定三行:
| 行 | 标签 | 内容 |
| 1 | 现象 | 复现出的失败表现,或本轮复验失败的具体现象 |
| 2 | 定位 | 阻塞原因 → 涉及位置。常见情形:Bug 指向的文件在当前工程不存在 / 逻辑超出当前代码范围(依赖外部系统)/ 描述不足以确定如何修复 |
| 3 | 下一步 | 需要谁提供什么才能继续修复(如 @运维 提供 xx 配置、@产品 确认 xx 规则) |
示例(fixNote):
已修复:列表分页 total 计算 -> BugServiceImpl.java:88 改为按过滤后条件统计
待修复:页码越界未处理 -> 需前端分页组件同步改造([复现截图](/images/202608/x.png))
验证:curl GET /bugs?projectId=1 翻到越界页码 -> 通过(返回空列表不再 500)示例(failReason):
现象:导出接口 500,日志报 unknown column deleted_flag
定位:本工程无 deleted_flag 字段,表结构由外部库维护 -> OrderMapper.xml:41
下一步:@DBA 确认线上表是否已有 deleted_flag,或提供建表语句- 每个
AI_PARTIALLY_FIXED的 Bug,要把待修复那一行原样列入本次任务的人工待办清单(common-rules 规范一"人工待办"板块),标注#<id>,@角色按该行点名的归属填写,未点名时默认@研发
回读验证(必做):PUT 后用与 3.2 相同的方式回读 GET /bugs/{id},确认 status 为 AI_FIXED、AI_PARTIALLY_FIXED 或 FAILED;标为 AI_PARTIALLY_FIXED / FAILED 时还要逐行确认回读的 fixNote / failReason 与提交内容一致、三个标签行齐全未塌成一行。服务端存的是提交原文(markdown 只在展示端渲染),逐行比对按原文即可;带链接的字段,另在 aibug 查看弹窗确认链接可点开、没有被解析成标题/列表/代码块。不一致则重试一次,仍不一致则向用户告警,并保留该 Bug 的 ID、期望状态与缺失或被改动的标签行。
服务端只在对应状态下保存说明字段:
failReason仅FAILED保留,fixNote仅AI_PARTIALLY_FIXED保留,其余状态一律置空。因此后续把某条AI_PARTIALLY_FIXED的 Bug 改成AI_FIXED/RESOLVED时原fixNote会被清空,需要留痕的剩余问题应先另建 Bug 或在本轮汇总中记录。
3.5 循环至下一个 Bug
完成一个 Bug 的处理后,回到 3.1,继续获取下一个 PENDING Bug。指定模式(传了 BUG_IDS)不回队列:清单里还有未处理的 #bugId 就按顺序取下一个(各自回写各自的 #id),全部处理完直接进入第四节。
四、完成输出
所有 Bug 处理完毕后,向用户输出汇总:
## aibug 修复完成
共处理 Bug:N 个
- AI_FIXED:N 个(其中已修复/重复修复、本轮零改动 m 个:逐条列出 #id 与已存在修复位置;无则 0)
- AI_PARTIALLY_FIXED:N 个(逐条列出 #id 与 fixNote 的 `待修复` 行原文;无则 0)
- FAILED:N 个(逐条列出 #id 与 failReason 的 `现象` + `下一步` 行原文;无则 0)
- 项目校验不通过:N 个(逐条列出 #id 与实际 projectId;无则 0)
- 回写异常(ID 不一致,已终止):N 个(逐条列出 #id 与期望状态;无则 0)
- 异常终止(卡在 IN_PROGRESS):N 个(逐条列出 #id、取卡时的原状态、台账记下的 fixNote/failReason 原文;无则 0)
(队列模式)队列已清空,无更多 PENDING Bug。
(指定模式·单 ID)#<id> 处理完毕,本轮只回写该条状态,未触碰其它 Bug。
(指定模式·多 ID)共 N 个 ID:逐条列出 `#<id> <原状态> → <本轮终态>`;被跳过的(不存在 / 项目校验不通过)逐条列出原因。- 汇总里引用说明字段时只摘对应标签行的原文,禁止把三行改写成一段叙述。
AI_PARTIALLY_FIXED的 Bug 已脱离 PENDING 队列(服务端/bugs/next只下发PENDING),本轮及后续/aibug都不会再自动处理其剩余问题;需在 aibug 界面把状态改回PENDING才会重新进入队列。- 卡在
IN_PROGRESS的条目同样脱离队列,且指定模式下原状态已被 3.2 的预标记盖掉、说明字段已被服务端清空;只能按台账记录到 aibug 界面人工改回原状态或PENDING,本 skill 不回写这两个状态。 fixNote的待修复行与failReason的下一步行产生的事项,一律进入规范一的"人工待办"板块;行首@角色按该行点名的归属填写(如@DBA、@运维、@产品),未点名归属时默认@研发。
五、注意事项
- 所有参数(HOST、USERNAME、PASSWORD、PROJECT_ID)均无默认值,必须由用户在每次调用时提供。
PROJECT_ID必须通过命令行--project-id=N传入;缺失时直接报错终止,不做交互询问兜底。--bug-id为可选的指定模式:跳过/bugs/next,只处理清单里这些#bugId并各自回写,不限原状态但会覆盖原状态;处理完即结束,不回队列,也不触碰任何其它 Bug。逗号分隔可给多个(如--bug-id=170,172),去重后按给定顺序逐条串行;取卡失败或项目校验不通过时,单 ID 报错终止、多 ID 记异常跳过该条。- 状态回写只允许按
#bugId的单条接口PUT /aibug/api/bugs/{id}/status;后端另有PUT /aibug/api/bugs/batch/status(ids数组批量改多条),本 skill 一律禁用,详见"状态回写寻址约束"。 - 口令仍由
--password=PASS传入,只用于登录那一次请求,不写入任何文件、不在日志中明文输出;但值必须先落 shell 变量再由程序json.dumps组装请求体,命令行里不得出现"password":"<值>"连写形态(会被凭据脱敏改写成***,造成与"口令错"同文案的 401)。 - 对外报告 401 时,结论必须写成
凭据校验未通过(本地传参改写已排除 / 未排除),不得单说"口令错误"; 自检未做或未排除时,不得向用户索取新口令。 FAILED状态必须提供failReason,AI_PARTIALLY_FIXED状态必须提供fixNote,否则 API 返回 400。fixNote/failReason一律按 3.4 的三行标签结构回写(值内用单个\n分行),禁止写成一段连续文字。- 这两个字段在 aibug 查看弹窗按 markdown 渲染,字段值必须是纯文本标签行:不写 markdown 标记(粗体、行内代码、表格、引用、成对
*/_、删除线),行首不用#+空格与-、+、*、数字.,不写空行与代码块围栏;尖括号本身安全(raw HTML 会被转义成正文),但<url>形态会变成自动链接,写地址统一用 markdown 链接语法,且只允许http/https或站内相对路径。 - 服务端对
status做枚举校验(PENDING / IN_PROGRESS / AI_FIXED / AI_PARTIALLY_FIXED / FAILED / RESOLVED / CLOSED;显示名AI_FIXED=「AI 修复」、AI_PARTIALLY_FIXED=「AI 半修」(语义名仍是"部分修复",徽标宽度上限只容 4 字)、RESOLVED=「已解决」),非法值返回 HTTP 400 及{"error": ...};每次 PUT 后必须检查响应中的error字段,出现则视为更新失败。 - 回传
AI_FIXED/AI_PARTIALLY_FIXED得到 400 非法值,说明该环境尚未执行状态更名迁移(FIXED→AI_FIXED见V9__rename_fixed_to_ai_fixed.sql、PARTIALLY_FIXED→AI_PARTIALLY_FIXED见V10__rename_partially_fixed.sql,均在deploy-conf/db/migrations/aibug/):如实报告「该环境状态枚举未升级」并停止回写,不得改回FIXED/PARTIALLY_FIXED试探(已升级环境只认AI_系码,两代码不可混用)。 - 读到响应里出现未订正的历史值
FIXED/PARTIALLY_FIXED(枚举已升级、数据未跟进的历史行)时,按原样记入台账并在汇总里点出,不猜测其含义、不试图批量订正——本 skill 只按#bugId单条回写。 AI_PARTIALLY_FIXED只用于"确有代码改动且已改动部分验证通过"的情形:全量修好一律AI_FIXED,禁止用它搪塞未验证的修复。本轮一点未改时先按原现象复验再定状态:复验确认现象已消失(已修复/重复修复)一律回传AI_FIXED,只有复验仍能复现且确实无法修复、或改动后验证不通过,才FAILED。- 每次修复前先标记
IN_PROGRESS(队列与指定模式都执行),确保同一 Bug 不被并发处理;处理完毕必须按 3.4 回写终态并回读确认。 - 预标记的代价:
IN_PROGRESS一旦写入,该条就脱离/bugs/next队列,指定模式下还会盖掉CLOSED/RESOLVED/AI_FIXED等原状态并连带清空fixNote/failReason(服务端规则,落库不可恢复)。本轮异常终止时必须按台账记下的原状态与原文在汇总的"异常终止"清单里点明,交人工在 aibug 界面回退;本 skill 不回写PENDING/RESOLVED/CLOSED,不得自行善后。 - 必须串行执行:本 skill 全程单实例、每条 Bug 委托子 agent 逐条串行处理,禁止并行(多实例、多个子 agent 同时处理多条 Bug、与 /aicase 或 /do-test 并发均不允许);用户要求并行时应明确拒绝并说明该约束。
- 本 skill 仅修改代码文件,不执行
git commit,由用户决定是否提交修复结果。
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

