Jinsi ya kuweka AI PR reviewer kwenye VPS yako
Jifunze namna ya kuendesha wakala wa ukaguzi wa PR kwenye seva yako binafsi. Punguza gharama, dhibiti faragha ya msimbo, na chuja faili kwa kutumia vichujio vya ukubwa.
Kazi ya wakala wa ukaguzi wa PR anayejiendeshea mwenyewe
Wakala wa ukaguzi wa PR anayejiendeshea mwenyewe ni programu ndogo iliyopo kwenye seva unayomiliki. Inasoma tofauti (diff) ya pull request (PR) na kutuma mistari iliyobadilishwa pekee kwa modeli. Majibu yanayorudi huchapishwa kama maoni ya ukaguzi ndani ya mstari husika. Programu hii haifanyi checkout ya branch yako, na haisomi faili yoyote ambayo pull request haijagusia. Vitambulisho pekee ilivyo navyo ni ufunguo mmoja wa API (application programming interface) ya modeli na tokeni moja inayoweza kutoa maoni pekee na isiyoweza kufanya kitu kingine chochote.
Modeli inaweza kusoma diff. Sehemu hiyo imetatuliwa. Kinachozingatiwa ni mahali ambapo diff inaenda na nani anayeshikilia ufunguo. Bot ya ukaguzi inayohifadhiwa na wahusika wengine inamaanisha kila diff kutoka kwa kila hazina (repository) ya kibinafsi inaondoka kwenye mtandao wako, inatua kwenye kumbukumbu (logs) za wahusika wengine, na inakaa chini ya sera yao ya utunzaji wa data. Kwenye VPS (virtual private server) unayomiliki, diff inatoka GitHub kwenda kwenye seva yako na kisha kwenda kwa API ya modeli, na unaweza kusoma mistari arobaini ya msimbo inayofanya maamuzi ya kile kinachotumwa.
Unachohitaji kabla ya kuanza
- VPS inayoendesha Ubuntu 24.04 ikiwa na self-hosted GitHub Actions runner iliyosajiliwa tayari kwenye hazina (repository). Ipe lebo ya ziada ya
pr-reviewwakati wa kuisajili, kwa sababu workflow iliyo hapa chini huchagua kulingana na lebo hiyo. - Ufunguo wa Anthropic API kutoka kwenye Claude Console.
- Hazina ambapo unadhibiti nani anaweza kufungua pull request. Hazina ya kibinafsi (private repository) ndiyo chaguo rahisi. Sehemu ya fork iliyo hapa chini inashughulikia hali ya hazina ya umma (public), na jibu lake ni gumu zaidi.
Sakinisha reviewer kwenye VPS
Huduma ya runner huendeshwa kama akaunti isiyo na upendeleo uliyoiunda ulipokimbiza ./svc.sh install. Sakinisha reviewer chini ya akaunti hiyo hiyo ili kazi iweze kuitekeleza bila sudo. Badilisha runner hapa chini na jina la akaunti yako.
sudo apt update && sudo apt install -y gh python3-venv
sudo install -d -m 755 -o runner -g runner /opt/pr-review
sudo -u runner python3 -m venv /opt/pr-review/venv
sudo -u runner /opt/pr-review/venv/bin/pip install anthropic
gh --versiongh --version huchapisha gh version 2.45.0 kwenye Ubuntu 24.04 kufikia Agosti 2026. Toleo lolote kuanzia 2.20 na kuendelea lina flag ya --input inayotumika hapa chini. Ujumbe wa Command 'gh' not found unamaanisha kuwa sehemu ya universe haijawashwa, kwa hivyo kimbiza sudo add-apt-repository universe na ujaribu tena.
Mahali ambapo ufunguo na token huishi
Siri mbili, muda wa matumizi tofauti. Hakuna hata moja inayopaswa kuwekwa kwenye repository.
ANTHROPIC_API_KEY ni siri ya repository, inayowekwa chini ya Settings, kisha Secrets and variables, kisha Actions. GitHub husimba siri hii kwa njia ya encryption na kuiingiza kwenye mazingira ya hatua husika wakati wa utekelezaji. Haiwi kamwe faili kwenye diski na haionekani kamwe kwenye historia ya git.
GITHUB_TOKEN hufanya kazi kwa njia tofauti. Actions hutengeneza token mpya kwa kila job na kuifuta pale job inapokamilika. Kile ambacho token hiyo inaweza kufanya huwekwa na block ya permissions: kwenye workflow, kwa hivyo hapa ndipo kanuni ya least privilege inapozingatiwa kikamilifu:
permissions:
contents: read
pull-requests: writeToken hiyo inaweza kutuma mapitio (review). Haiwezi kupush commit, ku-merge branch, kuhariri faili ya workflow, au kugusa repository nyingine. Wakala (agent) anayeweza kutoa maoni ni mkaguzi (reviewer). Wakala anayeweza kupush ni committer, na hakuna aliyekubaliana na hilo. Ufunguo wa model uweke kwa uangalifu uleule, kwa sababu unatumia pesa kwenye akaunti yako. Kuna maelezo zaidi kuhusu aina hii ya tatizo katika kuzuia siri zisifikiwe na AI agent.
Actions hubadilisha mfuatano kamili wa siri na *** kwenye logi za job. Inalinganisha mfuatano kamili pekee, kwa hivyo ufunguo unaoufanyia base64 encode, kuugawanya katika mistari miwili, au kuuchapisha herufi moja baada ya nyingine utaonekana wazi. Usiongeze hatua ya debug inayotoa maelezo yote ya mazingira (environment).
Kwa nini pull request kutoka kwa fork haioni API key yako
Kanuni ya GitHub ni fupi: isipokuwa kwa GITHUB_TOKEN, secrets hazipitishwi kwa runner wakati workflow inapoanzishwa kutoka kwenye repository iliyofanyiwa fork. Kwa hivyo, pull_request inayoendeshwa kutoka kwa fork huanzisha script yako bila ANTHROPIC_API_KEY, na API call ya kwanza inafeli kwa invalid x-api-key.
Suluhisho la kuvutia ni kubadili trigger iwe pull_request_target, ambayo huendeshwa katika muktadha wa repository ya msingi na hupata secrets hizo. Usifanye hivyo hapa. Mwongozo wa usalama wa GitHub unasema kuwa workflows hizo "zina upendeleo, kumaanisha zinashiriki cache sawa ya main branch na workflows nyingine zenye upendeleo, na zinaweza kuwa na uwezo wa kuandika kwenye repository na kufikia secrets zilizorejelewa", na kwamba matokeo yake "yanaweza kutumiwa vibaya kuteka repository".
Mwongozo huohuo uko wazi kuhusu runner: "Self-hosted runners hazipaswi kamwe kutumiwa kwa repositories za umma kwenye GitHub, kwa sababu mtumiaji yeyote anaweza kufungua pull requests dhidi ya repository hiyo na kuhatarisha mazingira."
Hiyo inaongoza maamuzi mawili ya usanifu. Job hiyo ina ulinzi ili iendeshwe tu kwenye branches zilizotumwa (pushed) kwenye repository yako mwenyewe. Na workflow haina hatua ya actions/checkout hata kidogo. Agent haina branch hiyo kwenye diski, kwa hivyo pull request yenye nia mbaya ni maandishi tu yanayotumwa kwa model. Haiwezi kuendesha build script kwenye VPS yako, kwa sababu hakuna kitu kwenye VPS yako kinachoiendesha. Hata hivyo, maandishi si sawa na kutokuwa na madhara: diff iliyoandikwa na mgeni ni input isiyoaminika inayofika kwenye model, mpaka uleule wa uaminifu unaokutana nao unapompa agent uwezo wa kutafuta kwenye mtandao, na kitu pekee kinachoiwekea mipaka hapa ni kwamba agent huyu hawezi kufanya chochote isipokuwa kuweka maoni (comment).
Pakua diff, siyo hazina (repository)
Ombi moja hupata diff nzima kama maandishi ya kawaida (plain text).
export GH_TOKEN=your_token # in the workflow this comes from secrets.GITHUB_TOKEN
gh api /repos/OWNER/REPO/pulls/42 -H "Accept: application/vnd.github.diff"Aina ya media ya Accept: application/vnd.github.diff ndiyo inayobadilisha jibu kutoka kwa JSON object inayoelezea pull request kuwa unified diff yenyewe, na gh api huchapisha mwili huo bila kuubadilisha. Mstari wa kwanza unaouona unapaswa kuanza na diff --git a/. gh: Not Found (HTTP 404) inamaanisha kuwa token haiwezi kuona hazina hiyo, ambayo kwenye fine-grained personal token karibu kila mara inamaanisha kuwa ruhusa ya Pull requests haikuwekwa.
Chuja kabla ya kutumia token
Sehemu hii ndiyo inayotofautisha kati ya bot inayopendwa na bot inayonyamazishwa. Kila kichujio hapa chini hufanya kazi kabla ya modeli kuona hata byte moja.
- Vichujio vya path. Funga faili, saraka za vendored, bundle zilizofupishwa (minified) na msimbo uliotengenezwa kiotomatiki. Maoni ya modeli kuhusu
package-lock.jsonni kelele tupu, na faili hizo mara nyingi ndizo zinazochukua nafasi kubwa zaidi katika diff. - Kikomo cha ukubwa. Kikomo kikivukwa, ruka ukaguzi na utoke kwa mafanikio. Refactor ya mistari 4,000 hupata mstari mmoja wa kweli unaosema kuwa ni kubwa mno kukaguliwa kiotomatiki, badala ya makisio sitini.
- Kizingiti cha uzito na kikomo cha maoni. Ripoti matokeo ya uzito wa juu na wa kati, hadi kumi, ukianzia na yale yenye uzito mkubwa zaidi. Hakuna anayesoma maoni ya kumi na moja.
Hati ya utekelezaji
Hifadhi faili hii kama /opt/pr-review/review.py. Inasoma usanidi wake kutoka kwenye mazingira (environment), hivyo mtiririko wa kazi unaweza kubadilisha modeli bila kuhitaji kubadilisha msimbo.
#!/usr/bin/env python3
"""Review only the changed lines of one pull request."""
import json
import os
import subprocess
import sys
import anthropic
REPO = os.environ["GITHUB_REPOSITORY"]
PR = os.environ["PR_NUMBER"]
MODEL = os.environ.get("REVIEW_MODEL", "claude-haiku-4-5-20251001")
MAX_DIFF_BYTES = int(os.environ.get("MAX_DIFF_BYTES", "120000"))
MIN_SEVERITY = os.environ.get("MIN_SEVERITY", "medium")
MAX_COMMENTS = 10
RANK = {"low": 0, "medium": 1, "high": 2}
SKIP = ("package-lock.json", "poetry.lock", "/vendor/", "/node_modules/", ".min.js")
raw_diff = subprocess.run(
["gh", "api", f"/repos/{REPO}/pulls/{PR}",
"-H", "Accept: application/vnd.github.diff"],
check=True, capture_output=True, text=True,
).stdoutKugawanya diff kwa kila faili ndiko kunakowezesha uchujaji wa njia (path filtering). Kuweka namba kwenye kila mstari ndiko kunakofanya maoni ya ukaguzi yaweze kuwekwa mahali sahihi. GitHub inakubali maoni ya ndani ya mstari (inline comment) kwenye mstari ambao ni sehemu ya diff pekee, kwa hivyo modeli lazima itaje namba halisi ya mstari. Kuipa namba hizo kunaiwezesha kunakili namba sahihi badala ya kubuni nyingine.
def per_file(diff_text):
"""Split a unified diff into one string per file."""
sections, current = [], []
for line in diff_text.splitlines():
if line.startswith("diff --git ") and current:
sections.append("\n".join(current))
current = []
current.append(line)
if current:
sections.append("\n".join(current))
return sections
def annotate(section):
"""Prefix every line that exists in the new file with its line number."""
out, n, in_hunk = [], 0, False
for line in section.splitlines():
if line.startswith("@@"):
n = int(line.split("+")[1].split(",")[0].split(" ")[0])
in_hunk = True
out.append(line)
elif not in_hunk or line.startswith(("-", "\\")):
out.append(line)
else:
out.append(f"{n}\t{line}")
n += 1
return "\n".join(out)
kept = [s for s in per_file(raw_diff)
if not any(p in s.split("\n", 1)[0] for p in SKIP)]
payload = "\n".join(annotate(s) for s in kept)
if not payload.strip():
print("every changed file was filtered out")
raise SystemExit(0)
if len(payload) > MAX_DIFF_BYTES:
print(f"diff is {len(payload)} bytes, over the {MAX_DIFF_BYTES} cap")
raise SystemExit(0)Kichwa cha hunk hubeba namba hizo. @@ -12,7 +12,9 @@ inaonyesha kuwa hunk ya faili mpya inaanza kwenye mstari wa 12, kwa hivyo kaunta huanzia hapo na kuongezeka kwenye mistari iliyoongezwa na ile isiyobadilishwa pekee. Mistari iliyoondolewa hupita bila kupewa namba, kwa sababu haipo kwenye faili mpya. Kizuizi kwenye mistari inayoanza na backslash huruka alama ya no-newline ambayo git huandika mwishoni mwa faili, ambayo ingesababisha kila namba inayofuata kuhama kwa nafasi moja.
Matokeo yote mawili hutumia status 0, si 1. Pull request iliyochujwa au iliyo kubwa kupita kiasi inapaswa kuonyesha alama ya kijani ya tiki. Alama nyekundu ambayo binadamu hawezi kuifanyia kazi hupuuzwa, na pindi alama moja inapopuuzwa, zote hupuuzwa.
SYSTEM = (
"You review one pull request diff. Every line that exists in the new file is "
"prefixed with its line number and a tab character. "
"Report only defects you can see in the lines shown: a crash, a resource leak, "
"a security mistake, a wrong boundary condition, a broken contract with code "
"that is visible in this diff. Do not comment on style, naming or formatting. "
"Do not guess about code you cannot see. Leave out anything you are not "
"certain about. An empty findings list is a normal and common answer. "
'Reply with JSON only, in this shape: {"findings": [{"path": "src/app.py", '
'"line": 42, "severity": "high", "comment": "what is wrong, then why"}]} '
"Every line number must be one you can see in the left column of that file."
)
client = anthropic.Anthropic()
message = client.messages.create(
model=MODEL,
max_tokens=2000,
system=SYSTEM,
messages=[{"role": "user", "content": payload}],
)
print(f"stop={message.stop_reason} in={message.usage.input_tokens} "
f"out={message.usage.output_tokens}", file=sys.stderr)
text = message.content[0].text
findings = json.loads(text[text.find("{"):text.rfind("}") + 1])["findings"]
findings = [f for f in findings if RANK.get(f["severity"], 0) >= RANK[MIN_SEVERITY]]
findings.sort(key=lambda f: -RANK.get(f["severity"], 0))
del findings[MAX_COMMENTS:]
if not findings:
print("nothing above the severity threshold; posting no comment")
raise SystemExit(0)
review = {
"event": "COMMENT",
"body": f"Automated review of the changed lines. {len(findings)} finding(s).",
"comments": [
{"path": f["path"].removeprefix("b/"), "line": f["line"], "side": "RIGHT",
"body": f"**{f['severity']}** {f['comment']}"}
for f in findings
],
}
subprocess.run(
["gh", "api", "-X", "POST", f"/repos/{REPO}/pulls/{PR}/reviews", "--input", "-"],
input=json.dumps(review), text=True, check=True,
)Maelezo matatu katika block hiyo ni muhimu sana. JSON hukatwa kati ya { ya kwanza na } ya mwisho kwa sababu modeli wakati mwingine huweka jibu lake ndani ya uzio wa msimbo (code fence), na json.loads hushindwa kusoma uzio huo. path huondolewa b/ ya mwanzo, kwa kuwa kiambishi awali hicho hutoka kwenye kichwa cha diff na GitHub inataka njia inayohusiana na hazina (repository-relative path). Na --input - hutuma ukaguzi mzima kama ombi moja la API, ili matokeo kumi yafike kama taarifa moja badala ya kumi tofauti.
Wakati hakuna cha kuripoti, hati haichapishi chochote. Boti inayoandika "hakuna masuala yaliyopatikana" kwenye kila pull request huwafundisha watu kuipuuza, na hatimaye hupuuza hata ile iliyo na umuhimu.
Iunganishe kwenye mtiririko wa kazi
Hifadhi hii kama .github/workflows/pr-review.yml:
name: pr-review
on:
pull_request:
types: [opened, synchronize, reopened]
paths-ignore:
- '**.md'
- 'docs/**'
permissions:
contents: read
pull-requests: write
concurrency:
group: pr-review-${{ github.event.pull_request.number }}
cancel-in-progress: true
jobs:
review:
if: github.event.pull_request.head.repo.full_name == github.repository && !contains(github.event.pull_request.labels.*.name, 'no-ai-review')
runs-on: [self-hosted, linux, pr-review]
steps:
- name: Review the changed lines
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REVIEW_MODEL: claude-haiku-4-5-20251001
MIN_SEVERITY: medium
run: /opt/pr-review/venv/bin/python /opt/pr-review/review.pyGITHUB_REPOSITORY haipo kwenye kizuizi hicho cha env: kwa sababu Actions huiweka kwa kila job tayari. Kikundi cha concurrency ni muhimu kwa gharama: bila hicho, kusukuma marekebisho matatu ya haraka kwenye branch moja huendesha review tatu kamili na unalipia zote tatu, na ukiwa nacho ni ile ya mwisho pekee inayobaki.
Mstari wa if: unafanya kazi mbili. Nusu ya kwanza inaruka pull requests kutoka kwenye forks, ambazo zingefeli hata hivyo kwa kukosa key. Nusu ya pili inawapa timu yako swichi ya kuzimia: ongeza lebo ya no-ai-review kwenye pull request na job hiyo haitaendeshwa.
Fungua pull request na uangalie kinachotokea:
gh run list --workflow=pr-review.yml --limit 3
gh run view --log
gh pr view 42 --commentsUendeshaji unaomalizika ndani ya sekunde chache ukiwa na nothing above the severity threshold; posting no comment kwenye log unafanya kazi kwa usahihi. Kwenye pull request ndogo na safi, hilo ndilo matokeo yanayotarajiwa.
Gharama ya ukaguzi wa pull request wa kiotomatiki ni kiasi gani?
Diff ndiyo sehemu kubwa ya input, kwa hivyo ukubwa wa diff ndio huamua bei. Hapo chini kuna diff ya mistari 500 iliyopimwa pamoja na system prompt, iliyohesabiwa kwa kutumia endpoint ya kuhesabu token badala ya makadirio.
The data behind this chart
[
{
"label": "Haiku 4.5",
"input_tokens": "8,000",
"output_tokens": "1,200"
},
{
"label": "Sonnet 5",
"input_tokens": "10,400",
"output_tokens": "1,560"
},
{
"label": "Opus 5",
"input_tokens": "10,400",
"output_tokens": "1,560"
}
]Diff hiyo ilifikia 8,000 input tokens kwenye Haiku 4.5 na 10,400 kwenye Sonnet 5. Maandishi ni yale yale, lakini idadi ni tofauti. Miundo ya Claude kuanzia 4.7 na kuendelea hutumia tokenizer mpya inayozalisha takriban 30% ya token nyingi zaidi kwa input ile ile, jambo ambalo Anthropic imeliweka kwenye ukurasa wake wa bei. Zingatia hili kila unapolinganisha muundo mpya na wa zamani kwa kutumia bei ya kila milioni ya token pekee.
Bei rasmi kufikia Agosti 2026: Haiku 4.5 ni $1 kwa kila milioni ya input tokens na $5 kwa kila milioni ya output. Sonnet 5 ni $2 na $10 chini ya bei ya utangulizi inayodumu hadi 31 Agosti 2026, kisha itakuwa $3 na $15. Opus 5 ni $5 na $25.
The data behind this chart
[
{
"label": "Haiku 4.5",
"cost_per_pr_cents": 1.4,
"cost_200_prs_usd": "2.80"
},
{
"label": "Sonnet 5",
"cost_per_pr_cents": 3.64,
"cost_200_prs_usd": "7.28"
},
{
"label": "Opus 5",
"cost_per_pr_cents": 9.1,
"cost_200_prs_usd": "18.20"
}
]Hiyo ni 1.4 senti kwa kila pull request kwenye Haiku 4.5 na 9.1 senti kwenye Opus 5. Timu inayounganisha pull requests 200 kwa mwezi hulipa takriban $2.80 kwenye Haiku 4.5, $7.28 kwenye Sonnet 5, au $18.20 kwenye Opus 5. Kuanzia 1 Septemba 2026, zidisha mstari wa Sonnet 5 kwa 1.5.
Mambo mawili huongeza gharama halisi kuliko makadirio hayo. synchronize huchochea ukaguzi kila unaposukuma (push) mabadiliko, kwa hivyo branch inayotumika sana yenye push nane hugharimu ukaguzi nane, na sheria ya concurrency husaidia tu wakati push zinapofanyika kwa wakati mmoja. Takwimu hizi pia huchukulia kuwa vichungi vya njia (path filters) vinafanya kazi: faili moja ya lock isiyochujwa inaweza kuongeza input mara mbili peke yake.
Prompt caching haisaidii hapa. Prefix iliyohifadhiwa lazima iwe sawa kabisa (byte-identical) kati ya maombi, na diff huwa tofauti kila wakati. System prompt ndiyo sehemu pekee thabiti, na iko chini sana ya urefu wa chini unaoweza kuhifadhiwa (cacheable length). Kwa sheria ya jumla, angalia wakati prompt caching inapolipa gharama zake, na kwa ajili ya kuchagua kati ya miundo mitatu hapo juu, muundo wa Claude wa kutumia kwa kazi ipi.
Pima diff zako mwenyewe kabla ya kuiwasha
Ongeza mstari huu baada ya payload kujengwa, kisha endesha script hiyo kwa mkono dhidi ya pull requests chache za mwezi uliopita:
print(client.messages.count_tokens(
model=MODEL, system=SYSTEM, messages=[{"role": "user", "content": payload}]
).input_tokens)Endpoint ya kuhesabu haitumii muundo (model), kwa hivyo haitumii input au output tokens, na hutumia tokenizer ya muundo unaoutaja. Iendeshe kwenye pull requests kumi halisi kutoka kwenye repository yako na uchukue median badala ya mean, ili migration moja kubwa isiharibu makadirio yako.
Kwa nini roboti za ukaguzi hunyamazishwa, na jinsi ya kuepuka hilo
Tabia mbili huharibu imani kwa roboti hizi, na zote mbili zina suluhisho katika msimbo hapo juu.
Kukagua kila kitu kwa wakati mmoja. Roboti inayotoa maoni arobaini haisomwi hata moja. Kizingiti cha ukali (severity threshold) na kikomo cha maoni kumi si suala la adabu, bali ni mambo yanayofanya matokeo ya kweli yaonekane. Kupanga kulingana na ukali kabla ya kufupisha kunamaanisha kuwa kikomo hicho huondoa matokeo yasiyo muhimu badala ya kuchagua kumi kiholela.
Kutoa maoni kwa ujasiri kuhusu kitu ambacho haiwezi kukihakiki. Hii ndiyo tabia inayowafanya wahandisi kuizima kabisa. Mfano (model) unaoonyeshwa mistari 200 ya codebase yenye mistari 40,000 bado utaandika "hii inavunja utaratibu wa cache invalidation katika redis_client.py" kuhusu faili ambalo haijawahi kuliona. Prompt ya mfumo inakataa hilo kwa lugha rahisi: ripoti tu kasoro zinazoonekana katika mistari iliyoonyeshwa, na acha chochote ambacho huna uhakika nacho. Kutaja kosa moja kwa moja hufanya kazi vizuri zaidi kuliko kuomba usahihi kwa ujumla, na kumwambia mfano kuwa matokeo matupu ni jambo la kawaida ndilo linalozuia kubuni kitu cha kusema kuhusu mabadiliko ya mistari miwili.
Tuma ukaguzi kama COMMENT, kamwe usitume kama REQUEST_CHANGES. Maoni ya mfano hayapaswi kuwa na uwezo wa kuzuia merge, na pindi tu yanapoweza kufanya hivyo, mtu mwenye muda mfupi wa kukamilisha kazi ataondoa workflow nzima badala ya kubishana nayo.
Njia za kufeli, pamoja na ujumbe utakaouona
HTTP 422 wakati wa kutuma review. gh huchapisha gh: Unprocessable Entity (HTTP 422) na mwili wa majibu (response body) hutaja uwanja husika: Pull request review thread line must be part of the diff. GitHub haiwezi kuweka maoni hayo. Sababu za kawaida ni namba ya mstari ambayo model imebuni, path ambayo bado ina kiambishi awali cha b/, au maoni kwenye mstari ulioondolewa, ambayo yanahitaji side iwekwe kuwa LEFT badala ya RIGHT. Chapisha JSON ya review kabla ya kuituma na uhakiki maoni moja kwa mkono dhidi ya diff.
invalid x-api-key kutoka kwa API ya model. Hatua hii hufeli kwenye mwito wa kwanza wa messages.create. Aidha siri ya ANTHROPIC_API_KEY haijawekwa kwenye repository, au pull request imetoka kwenye fork hivyo Actions haikupitisha siri yoyote. Kinga ya fork katika mstari wa if: inapaswa kuiruka, kwa hivyo kagua mstari huo kwanza.
gh: Resource not accessible by integration (HTTP 403). Token ya job haiwezi kuandika kwenye pull requests. Ongeza pull-requests: write kwenye block ya permissions:. Ikiwa tayari ipo, angalia Settings, kisha Actions, kisha General, ambapo sera ya shirika inaweza kuzuia kile ambacho token yoyote ya workflow inaruhusiwa kuomba.
json.decoder.JSONDecodeError. Model haikurejesha JSON inayoweza kuchambuliwa (parseable). Sababu ya kawaida ni majibu yaliyogonga kikomo cha token na kusimama katikati ya object. Mstari wa log huchapisha stop_reason kwa ajili ya hili hasa: thamani ya max_tokens inamaanisha ongeza max_tokens au punguza MAX_COMMENTS.
Workflow haiwaki kamwe. gh run list haionyeshi chochote kwa ajili ya pull request. Hakikisha kuwa paths-ignore haikuchuja kila faili iliyobadilishwa, kisha kagua kinga ya fork na kinga ya label, kisha kama runner iko hai kwa kutumia sudo systemctl status 'actions.runner.*' kwenye VPS. Runner iliyo offline huacha job ikiwa kwenye foleni bila ujumbe wowote wa hitilafu kwenye pull request.
Kila review inarudi ikiwa tupu. Weka MIN_SEVERITY kuwa low kwa ajili ya run moja. Ikiwa matokeo yataonekana, basi threshold inafanya kazi yake. Ikiwa hakuna kinachoonekana, chapisha payload na uthibitishe kuwa vichujio havijaondoa diff nzima.
Kukiendesha pamoja na mawakala wako wengine
Reviewer ni ndogo, kwa hivyo ni rahisi kushawishika kuiweka kwenye seva inayofanya kila kitu kingine. Iweke kando ikiwa repository yako ni muhimu. Mchakato huu unashikilia token inayoweza kutoa maoni kwenye code yako na ufunguo unaoweza kutumia pesa zako, na runner inayojiendesha yenyewe kimsingi ni mahali ambapo code ya workflow hutekelezwa. Akaunti maalum isiyo na upendeleo (unprivileged account) isiyo na haki za sudo, kwenye host isiyoendesha kitu kingine chochote, ndiyo msingi wa usalama. Ikiwa unaendesha pia mawakala shirikishi (interactive agents) wanaofanya checkout ya code, VM inayoweza kufutwa kwa kila wakala ndiyo muundo unaofaa, na kuendesha wakala wa coding kwenye VPS kunashughulikia usanidi wa jumla. Ikiwa Anthropic API ni ngeni kwako, programu ya kwanza ya Claude API kwenye VPS ni mahali pazuri zaidi pa kuanzia kuliko hapa.
FAQ
Je, wakala wa AI wa kukagua PR anahitaji ruhusa ya kuandika kwenye hazina yangu?
Hapana. Anahitaji pull-requests: write ili kuweka ukaguzi na contents: read ili kuchota diff. Hiyo ndiyo orodha nzima, na unaweka ruhusa hizo kwenye sehemu ya permissions: ya workflow, ambayo inadhibiti kile ambacho GITHUB_TOKEN ya kila kazi inaweza kufanya. Kwa mistari hiyo miwili, wakala anaweza kutoa maoni kwenye pull request lakini hawezi kupush commit au kuunganisha (merge) branch. Tuma ukaguzi kwa kutumia event: COMMENT badala ya REQUEST_CHANGES ili pia asiweze kuzuia merge.
Kwa nini maoni yangu ya ukaguzi yanashindwa kwa HTTP 422?
GitHub inakubali maoni ya ukaguzi ya ndani ya mstari (inline) kwenye mstari ambao ni sehemu ya diff ya pull request, na inarudisha Pull request review thread line must be part of the diff wakati haupo. Hakikisha kuwa path inahusiana na hazina bila kiambishi awali cha b/ kutoka kwenye kichwa cha diff, na kwamba namba ya mstari inaonekana ndani ya hunk ya faili hiyo. side lazima iwe RIGHT kwa mstari ulioongezwa au ambao haujabadilishwa na LEFT kwa ule ulioondolewa. Kuweka kiambishi awali cha namba ya mstari wa faili mpya kwenye kila mstari wa diff kabla ya kuutuma kwa modeli ndiko kunakozuia modeli kubuni namba zake yenyewe.
Je, ninaweza kuendesha hii kwenye hazina ya umma yenye pull requests kutoka kwa forks?
Huwezi kwa usanifu huu. GitHub haipitishi siri (secrets) kwenye workflow iliyoanzishwa kutoka kwa fork, kwa hivyo ufunguo wa modeli unakosekana na uendeshaji unashindwa. GitHub pia inasema kuwa self-hosted runners "hazipaswi kamwe kutumika kwa hazina za umma", kwa sababu mtu yeyote anaweza kufungua pull request inayofanya msimbo uendeshwe kwenye mashine yako. Kwa mradi wa umma, ama zuia mkaguzi kwenye branch zilizopushwa kwenye hazina yenyewe, jambo ambalo ndilo linalofanywa na ulinzi wa if:, au hamisha hatua ya ukaguzi kwenye runner inayohifadhiwa na GitHub na ukubali kuwa diff inatoka nje ya miundombinu yako.
Ni modeli ipi ninayopaswa kutumia kwa ukaguzi wa pull request?
Anza na Haiku 4.5. Kusoma diff iliyopunguzwa dhidi ya orodha maalum ya aina za kasoro si tatizo gumu la kihoja, na modeli ya bei nafuu zaidi huweka gharama ya kila mwezi kwenye kiwango ambacho hakuna anayelalamika. Hamia kwenye Sonnet 5 ikiwa utagundua inakosa mende (bugs) halisi katika lugha au mfumo wako, na pima hilo badala ya kulidhania. Opus 5 ndiyo ghali zaidi kati ya hizo tatu kwa kiasi kikubwa kwa kila pull request, jambo ambalo ni rahisi kuhalalisha kwenye release branch kuliko kwenye kila push ya kila feature branch.