VPS లో సొంత AI PR రివ్యూ ఏజెంట్ను సెటప్ చేయడం ఎలా
మీ స్వంత VPSలో AI PR రివ్యూ ఏజెంట్ను రన్ చేయండి. కోడ్ భద్రత, డిఫ్-స్కోప్డ్ ప్రాంప్ట్లు, ఫైల్ ఫిల్టర్లు మరియు ప్రతి PRకు అయ్యే ఖర్చును ఎలా నియంత్రించాలో ఈ గైడ్లో తెలుసుకోండి.
Self-hosted PR review agent ఏమి చేస్తుంది
Self-hosted PR review agent అనేది మీరు సొంతంగా కలిగి ఉన్న సర్వర్లో నడిచే ఒక చిన్న ప్రోగ్రామ్. ఇది pull request (PR) యొక్క diff ను చదివి, కేవలం మార్పులు జరిగిన లైన్లను మాత్రమే ఒక మోడల్కు పంపుతుంది. తిరిగి వచ్చిన సమాధానం inline review comments గా పోస్ట్ చేయబడుతుంది. ఇది మీ branch ను ఎప్పుడూ checkout చేయదు, మరియు pull request లో మార్పులు లేని ఏ ఫైల్ను కూడా చదవదు. దీని వద్ద ఉండే ఏకైక ఆధారాలు ఒక మోడల్ API (application programming interface) కీ మరియు కేవలం కామెంట్ చేయడానికి మాత్రమే అనుమతి ఉన్న ఒక టోకెన్.
ఒక మోడల్ diff ను చదవగలదు. ఆ సమస్య పరిష్కారమైంది. అసలైన విషయం ఏమిటంటే, ఆ diff ఎక్కడికి వెళ్తుంది మరియు ఆ కీ ఎవరి వద్ద ఉంది అనేది. Hosted review bot అంటే ప్రతి ప్రైవేట్ రిపోజిటరీ నుండి వచ్చే ప్రతి diff మీ నెట్వర్క్ దాటి, మూడవ పక్షం వారి logs లో చేరి, వారి retention policy కింద నిల్వ చేయబడుతుంది. మీరు సొంతంగా కలిగి ఉన్న VPS (virtual private server) లో, diff అనేది GitHub నుండి మీ సర్వర్కు, అక్కడి నుండి మోడల్ API కి వెళ్తుంది. ఏ సమాచారాన్ని పంపాలో నిర్ణయించే ఆ నలభై లైన్ల కోడ్ను మీరు స్వయంగా చదువుకోవచ్చు.
ప్రారంభించే ముందు మీకు కావాల్సినవి
- Ubuntu 24.04 నడుస్తున్న ఒక VPS, దీనికి ఇప్పటికే self-hosted GitHub Actions runner రిజిస్టర్ అయి ఉండాలి. రిజిస్టర్ చేసేటప్పుడు దానికి
pr-reviewఅనే అదనపు లేబుల్ను ఇవ్వండి, ఎందుకంటే కింద ఉన్న వర్క్ఫ్లో ఆ లేబుల్ ఆధారంగానే ఎంపిక చేసుకుంటుంది. - Claude Console నుండి పొందిన ఒక Anthropic API key.
- మీరు పుల్ రిక్వెస్ట్లను ఎవరు ఓపెన్ చేయవచ్చో నియంత్రించగల ఒక రిపోజిటరీ. ప్రైవేట్ రిపోజిటరీ అయితే ఇది సులభం. పబ్లిక్ రిపోజిటరీల కోసం ఫోర్క్ సెక్షన్ను కింద చూడవచ్చు, కానీ అక్కడ పరిష్కారం కొంచెం క్లిష్టంగా ఉంటుంది.
VPSలో reviewer ను ఇన్స్టాల్ చేయండి
./svc.sh install రన్ చేసినప్పుడు మీరు సృష్టించిన unprivileged ఖాతాలోనే runner సర్వీస్ నడుస్తుంది. ఆ ఖాతాలోనే reviewer ను ఇన్స్టాల్ చేయండి, తద్వారా sudo అవసరం లేకుండానే job దానిని అమలు చేయగలదు. కింద ఉన్న runner స్థానంలో మీ ఖాతా పేరును ఉంచండి.
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 --version2026 ఆగస్టు నాటికి Ubuntu 24.04లో gh --version కమాండ్ gh version 2.45.0 ను ప్రింట్ చేస్తుంది. 2.20 వెర్షన్ నుండి ఏ వెర్షన్లోనైనా కింద ఉపయోగించిన --input ఫ్లాగ్ ఉంటుంది. Command 'gh' not found సందేశం కనిపిస్తే, universe కాంపోనెంట్ ఎనేబుల్ కాలేదని అర్థం, కాబట్టి sudo add-apt-repository universe రన్ చేసి మళ్ళీ ప్రయత్నించండి.
కీ మరియు టోకెన్ ఎక్కడ ఉంటాయి
రెండు రహస్యాలు, రెండు వేర్వేరు కాలపరిమితులు. వీటిలో ఏదీ రిపోజిటరీలో ఉండకూడదు.
ANTHROPIC_API_KEY అనేది ఒక రిపోజిటరీ రహస్యం, దీనిని Settings, ఆపై Secrets and variables, ఆపై Actions విభాగంలో సెట్ చేస్తారు. GitHub దీనిని ఎన్క్రిప్ట్ చేసి, రన్ టైమ్లో స్టెప్ యొక్క ఎన్విరాన్మెంట్లోకి పంపుతుంది. ఇది డిస్క్లో ఫైల్గా ఉండదు మరియు git హిస్టరీలో ఎప్పటికీ కనిపించదు.
GITHUB_TOKEN భిన్నంగా పనిచేస్తుంది. Actions ప్రతి జాబ్ కోసం ఒక కొత్త టోకెన్ను సృష్టించి, జాబ్ ముగియగానే దానిని తొలగిస్తుంది. ఆ టోకెన్ ఏమి చేయగలదో వర్క్ఫ్లోలోని permissions: బ్లాక్ ద్వారా నిర్ణయించబడుతుంది, కాబట్టి కనీస అధికారాల (least privilege) సూత్రం ఇక్కడే అమలు చేయబడుతుంది:
permissions:
contents: read
pull-requests: writeఆ టోకెన్ రివ్యూను పోస్ట్ చేయగలదు. అది కమిట్ను పుష్ చేయలేదు, బ్రాంచ్ను మెర్జ్ చేయలేదు, వర్క్ఫ్లో ఫైల్ను ఎడిట్ చేయలేదు లేదా మరొక రిపోజిటరీని తాకలేదు. కామెంట్ చేయగల ఏజెంట్ ఒక రివ్యూయర్ మాత్రమే. పుష్ చేయగల ఏజెంట్ ఒక కమిటర్, మరియు దానికి ఎవరూ అంగీకరించలేదు. మోడల్ కీని కూడా అంతే జాగ్రత్తగా చూసుకోండి, ఎందుకంటే అది మీ ఖాతాలో డబ్బును ఖర్చు చేస్తుంది. ఈ సమస్యకు సంబంధించిన మరిన్ని వివరాలు AI ఏజెంట్కు రహస్యాలు అందకుండా ఉంచడం లో ఉన్నాయి.
Actions జాబ్ లాగ్స్లో ఖచ్చితమైన రహస్య స్ట్రింగ్ను *** తో భర్తీ చేస్తుంది. ఇది ఖచ్చితమైన స్ట్రింగ్ను మాత్రమే గుర్తిస్తుంది, కాబట్టి మీరు base64 ఎన్కోడ్ చేసిన, రెండు లైన్లుగా విడగొట్టిన లేదా ఒక్కో అక్షరాన్ని ప్రింట్ చేసే కీ స్పష్టంగా కనిపిస్తుంది. ఎన్విరాన్మెంట్ను డంప్ చేసే డీబగ్ స్టెప్ను ఎప్పుడూ జోడించవద్దు.
ఫోర్క్ (fork) నుండి వచ్చే పుల్ రిక్వెస్ట్ మీ API కీని ఎందుకు చూడలేదు
GitHub నియమం చాలా స్పష్టమైనది: GITHUB_TOKEN మినహా, ఫోర్క్ చేసిన రిపోజిటరీ నుండి వర్క్ఫ్లో ట్రిగ్గర్ అయినప్పుడు secrets రన్నర్కు పంపబడవు. కాబట్టి, ఫోర్క్ నుండి రన్ అయ్యే pull_request మీ స్క్రిప్ట్ను ఎటువంటి ANTHROPIC_API_KEY లేకుండానే ప్రారంభిస్తుంది, దీనివల్ల మొదటి API కాల్ invalid x-api-key తో విఫలమవుతుంది.
దీనికి సులభమైన పరిష్కారంగా ట్రిగ్గర్ను pull_request_target కి మార్చాలని అనిపించవచ్చు, ఇది బేస్ రిపోజిటరీ సందర్భంలో రన్ అవుతుంది కాబట్టి secrets అందుతాయి. కానీ ఇక్కడ అలా చేయకండి. GitHub యొక్క భద్రతా మార్గదర్శకాల ప్రకారం, అటువంటి వర్క్ఫ్లోలు "privileged (ప్రత్యేక అధికారాలు కలిగినవి), అంటే అవి ఇతర privileged వర్క్ఫ్లో ట్రిగ్గర్లతో మెయిన్ బ్రాంచ్ యొక్క అదే cache ను పంచుకుంటాయి, అంతేకాకుండా వీటికి రిపోజిటరీకి రాసే హక్కులు మరియు రిఫరెన్స్ చేసిన secrets కు యాక్సెస్ ఉండవచ్చు", మరియు దీని ఫలితం "రిపోజిటరీని హ్యాక్ చేయడానికి ఉపయోగపడవచ్చు".
రన్నర్ గురించి అదే మార్గదర్శకాలు చాలా స్పష్టంగా ఉన్నాయి: "GitHub లోని పబ్లిక్ రిపోజిటరీల కోసం self-hosted రన్నర్లను దాదాపు ఎప్పుడూ ఉపయోగించకూడదు, ఎందుకంటే ఎవరైనా రిపోజిటరీకి పుల్ రిక్వెస్ట్లను పంపి, ఆ ఎన్విరాన్మెంట్ను ప్రమాదంలో పడేయవచ్చు."
ఇది రెండు డిజైన్ నిర్ణయాలకు దారితీస్తుంది. ఈ జాబ్ ఒక గార్డును కలిగి ఉంటుంది, కాబట్టి ఇది మీ స్వంత రిపోజిటరీకి పుష్ చేసిన బ్రాంచ్లపై మాత్రమే రన్ అవుతుంది. మరియు ఈ వర్క్ఫ్లోలో ఎటువంటి actions/checkout స్టెప్ ఉండదు. ఏజెంట్ వద్ద బ్రాంచ్ డిస్క్పై ఉండదు, కాబట్టి ప్రమాదకరమైన పుల్ రిక్వెస్ట్ అనేది కేవలం మోడల్కు పంపబడే టెక్స్ట్ మాత్రమే. ఇది మీ VPS పై ఎటువంటి బిల్డ్ స్క్రిప్ట్ను రన్ చేయలేదు, ఎందుకంటే మీ VPS లో దేనినీ అది రన్ చేయదు. అయితే, టెక్స్ట్ అంటే హాని లేనిది అని కాదు: ఒక అపరిచితుడు రాసిన diff అనేది మోడల్కు చేరే అన్ట్రస్టెడ్ ఇన్పుట్. మీరు ఏజెంట్కు వెబ్ సెర్చ్ అనుమతి ఇచ్చినప్పుడు ఎదుర్కొనే ట్రస్ట్ బౌండరీ ఇదే. ఇక్కడ దీనిని నియంత్రించే ఏకైక విషయం ఏమిటంటే, ఈ ఏజెంట్ కేవలం ఒక కామెంట్ పోస్ట్ చేయడం తప్ప మరేమీ చేయలేదు.
రిపోజిటరీని కాకుండా diff ను పొందండి
ఒక అభ్యర్థన మొత్తం diff ను 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"Accept: application/vnd.github.diff మీడియా రకం, pull request ను వివరించే JSON ఆబ్జెక్ట్ నుండి ప్రతిస్పందనను నేరుగా unified diff గా మారుస్తుంది, మరియు gh api ఆ బాడీని ఎటువంటి మార్పులు లేకుండా ప్రింట్ చేస్తుంది. మీరు చూసే మొదటి లైన్ diff --git a/ తో ప్రారంభం కావాలి. gh: Not Found (HTTP 404) అంటే టోకెన్కు రిపోజిటరీని చూసే అనుమతి లేదని అర్థం, ఇది fine-grained personal token విషయంలో దాదాపు ఎల్లప్పుడూ Pull requests అనుమతిని ఇవ్వకపోవడం వల్ల జరుగుతుంది.
టోకెన్ను ఖర్చు చేసే ముందు ఫిల్టర్ చేయండి
ఈ విభాగం ప్రజలు చదివే బాట్కు మరియు ప్రజలు మ్యూట్ చేసే బాట్కు మధ్య వ్యత్యాసాన్ని చూపుతుంది. మోడల్ ఒక్క బైట్ను కూడా చూడకముందే కింద పేర్కొన్న ప్రతి ఫిల్టర్ రన్ అవుతుంది.
- Path filters. Lock files, vendored directories, minified bundles మరియు generated code లను లాక్ చేయండి.
package-lock.jsonపై మోడల్ ఇచ్చే కామెంట్ కేవలం నాయిస్ మాత్రమే, మరియు డిఫ్లో ఉండే బైట్లలో ఎక్కువ భాగం ఇవే ఫైల్స్ ఆక్రమిస్తాయి. - A size cap. పరిమితి దాటితే, రివ్యూను స్కిప్ చేసి గ్రీన్ స్టేటస్తో ఎగ్జిట్ అవ్వండి. 4,000 లైన్ల రిఫాక్టర్ కోసం అరవై అంచనాలు వేసే బదులు, అది రివ్యూ చేయడానికి చాలా పెద్దదిగా ఉందని ఒక నిజాయితీ గల లైన్ మాత్రమే చెప్పండి.
- A severity threshold and a comment cap. High మరియు medium స్థాయి ఫలితాలను రిపోర్ట్ చేయండి, గరిష్టంగా పది వరకు, అత్యధిక తీవ్రత ఉన్న వాటికి మొదటి ప్రాధాన్యత ఇవ్వండి. పదకొండవ కామెంట్ను ఎవరూ చదవరు.
స్క్రిప్ట్
దీనిని /opt/pr-review/review.pyగా సేవ్ చేయండి. ఇది తన కాన్ఫిగరేషన్ను environment నుంచి చదువుకుంటుంది, కాబట్టి కోడ్లో మార్పులు చేయకుండానే వర్క్ఫ్లో మోడల్స్ను మార్చుకోవచ్చు.
#!/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,
).stdoutఫైల్ వారీగా diff ను విభజించడం వల్లే path filtering సాధ్యమవుతుంది. ప్రతి లైన్కు నంబరింగ్ ఇవ్వడం వల్లే రివ్యూ కామెంట్స్ సరైన చోట పడతాయి. GitHub కేవలం diff లో భాగమైన లైన్పై మాత్రమే inline comment ను అనుమతిస్తుంది, కాబట్టి మోడల్ ఒక అసలైన లైన్ నంబర్ను పేర్కొనాలి. నంబర్లను దానికి అందించడం ద్వారా, అది సొంతంగా ఊహించకుండా, ఉన్న నంబర్ను కాపీ చేయగలదు.
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)Hunk header నంబరింగ్ను కలిగి ఉంటుంది. @@ -12,7 +12,9 @@ ప్రకారం కొత్త ఫైల్ యొక్క hunk 12వ లైన్ వద్ద మొదలవుతుంది, కాబట్టి కౌంటర్ అక్కడ మొదలై, కొత్తగా చేర్చిన మరియు మార్పు లేని లైన్ల వద్ద పెరుగుతుంది. తొలగించిన లైన్లు కొత్త ఫైల్లో ఉండవు కాబట్టి వాటికి నంబరింగ్ ఉండదు. బ్యాక్స్లాష్తో మొదలయ్యే లైన్లపై ఉన్న గార్డ్, ఫైల్ చివరన git రాసే no-newline మార్కర్ను దాటవేస్తుంది; లేకపోతే అది తర్వాతి ప్రతి నంబర్ను ఒకటి పెంచేది.
రెండు ఎగ్జిట్లు 1 కి బదులుగా 0 స్టేటస్ను ఉపయోగిస్తాయి. ఫిల్టర్ చేసిన లేదా పరిమితి మించిన pull request గ్రీన్ చెక్ను చూపాలి. మనిషి స్పందించలేని రెడ్ చెక్ను పట్టించుకోరు, ఒకసారి ఒక చెక్ను విస్మరిస్తే, మిగిలినవన్నీ అలాగే విస్మరించబడతాయి.
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,
)ఆ బ్లాక్లోని మూడు వివరాలు చాలా ముఖ్యమైనవి. JSON ను మొదటి { మరియు చివరి } మధ్య కత్తిరించాలి, ఎందుకంటే మోడల్ కొన్నిసార్లు తన సమాధానాన్ని code fence లో ఉంచుతుంది, అప్పుడు json.loads ఆ ఫెన్స్ వద్ద ఆగిపోతుంది. path నుంచి ముందున్న b/ తొలగించబడుతుంది, ఎందుకంటే ఆ ప్రిఫిక్స్ diff header నుంచి వస్తుంది మరియు GitHub కు repository-relative path అవసరం. మరియు --input - మొత్తం రివ్యూను ఒకే API కాల్గా పంపుతుంది, తద్వారా పది నోటిఫికేషన్లకు బదులుగా ఒకే నోటిఫికేషన్ వెళ్తుంది.
రిపోర్ట్ చేయడానికి ఏమీ లేనప్పుడు, స్క్రిప్ట్ ఏమీ పోస్ట్ చేయదు. ప్రతి pull request పై "no issues found" అని రాసే బాట్, ప్రజలు దాన్ని చదవకుండా దాటవేసేలా చేస్తుంది, తద్వారా ముఖ్యమైన రిపోర్టును కూడా వారు పట్టించుకోరు.
వర్క్ఫ్లోలో దీనిని అనుసంధానించండి
దీనిని .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 ఆ env: బ్లాక్లో ఉండదు, ఎందుకంటే Actions ప్రతి జాబ్ కోసం దానిని ఇప్పటికే సెట్ చేస్తుంది. concurrency గ్రూప్ బిల్లు విషయంలో కీలకం: ఇది లేకపోతే, ఒక బ్రాంచ్కు మూడు క్విక్ ఫిక్స్లను పంపినప్పుడు మూడు పూర్తి రివ్యూలు రన్ అవుతాయి మరియు మీరు మూడింటికీ చెల్లించాల్సి ఉంటుంది, అదే ఇది ఉంటే చివరిది మాత్రమే మిగులుతుంది.
if: లైన్ రెండు పనులను చేస్తుంది. మొదటి సగం ఫోర్క్స్ (forks) నుండి వచ్చే pull requests ను స్కిప్ చేస్తుంది, కీ లేకపోతే అవి ఎలాగూ విఫలమవుతాయి. రెండవ సగం మీ టీమ్కు ఒక ఆఫ్ స్విచ్ను ఇస్తుంది: ఒక pull request కు no-ai-review లేబుల్ను జోడిస్తే, ఆ జాబ్ రన్ అవ్వదు.
ఒక pull request ను ఓపెన్ చేసి ఏం జరుగుతుందో గమనించండి:
gh run list --workflow=pr-review.yml --limit 3
gh run view --log
gh pr view 42 --commentsకొద్ది సెకన్లలో పూర్తయి, లాగ్లో nothing above the severity threshold; posting no comment ఉన్న రన్ సరిగ్గా పనిచేస్తున్నట్లు అర్థం. చిన్న మరియు క్లీన్ pull request విషయంలో ఇదే ఆశించిన ఫలితం.
ఆటోమేటెడ్ పుల్ రిక్వెస్ట్ రివ్యూ ధర ఎంత?
Diff అనేది ఇన్పుట్లో దాదాపు మొత్తం భాగాన్ని ఆక్రమిస్తుంది, కాబట్టి Diff పరిమాణం ధరను నిర్ణయిస్తుంది. కింద 500 లైన్ల Diff మరియు సిస్టమ్ ప్రాంప్ట్ను లెక్కించిన విధానం ఉంది, ఇది అంచనా కాకుండా టోకెన్ కౌంటింగ్ ఎండ్పాయింట్ ద్వారా లెక్కించబడింది.
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, Haiku 4.5 మోడల్పై 8,000 ఇన్పుట్ టోకెన్లను మరియు Sonnet 5 పై 10,400 టోకెన్లను తీసుకుంది. టెక్స్ట్ ఒక్కటే అయినా, లెక్కింపు వేరుగా ఉంది. 4.7 వెర్షన్ నుండి Claude మోడల్స్ కొత్త టోకెనైజర్ను ఉపయోగిస్తున్నాయి, ఇది అదే ఇన్పుట్ కోసం సుమారు 30% ఎక్కువ టోకెన్లను ఉత్పత్తి చేస్తుంది. దీని గురించి Anthropic తన ధరల పేజీలో పేర్కొంది. కేవలం మిలియన్ టోకెన్ల ధరను బట్టి కొత్త మోడల్ను పాత మోడల్తో పోల్చేటప్పుడు ఈ విషయాన్ని పరిగణనలోకి తీసుకోండి.
ఆగస్టు 2026 నాటికి ఉన్న ధరల జాబితా: Haiku 4.5 ధర మిలియన్ ఇన్పుట్ టోకెన్లకు $1 మరియు మిలియన్ అవుట్పుట్ టోకెన్లకు $5. Sonnet 5 ధర 31 ఆగస్టు 2026 వరకు పరిచయ ధరగా $2 మరియు $10, ఆ తర్వాత $3 మరియు $15. Opus 5 ధర $5 మరియు $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"
}
]ఇది Haiku 4.5 పై ప్రతి పుల్ రిక్వెస్ట్కు 1.4 సెంట్లు మరియు Opus 5 పై 9.1 సెంట్లు అవుతుంది. నెలకు 200 పుల్ రిక్వెస్ట్లను మెర్జ్ చేసే టీమ్ Haiku 4.5 పై సుమారు $2.80, Sonnet 5 పై $7.28, లేదా Opus 5 పై $18.20 చెల్లిస్తుంది. 1 సెప్టెంబర్ 2026 నుండి, Sonnet 5 ధరను 1.5 తో గుణించండి.
రెండు అంశాలు అసలు బిల్లును ఈ అంచనా కంటే పెంచుతాయి. synchronize ప్రతి పుష్కు రివ్యూలను ట్రిగ్గర్ చేస్తుంది, కాబట్టి ఎనిమిది పుష్లు ఉన్న యాక్టివ్ బ్రాంచ్ ఎనిమిది రివ్యూల ఖర్చును కలిగిస్తుంది. కన్కరెన్సీ రూల్ కేవలం పుష్లు దగ్గరగా జరిగినప్పుడు మాత్రమే సహాయపడుతుంది. ఈ గణాంకాలు పాత్ ఫిల్టర్లు సరిగ్గా పనిచేస్తున్నాయని భావిస్తాయి: ఫిల్టర్ చేయని ఒక లాక్ ఫైల్ ఇన్పుట్ను రెట్టింపు చేయగలదు.
ప్రాంప్ట్ క్యాషింగ్ ఇక్కడ సహాయపడదు. క్యాష్ చేయబడిన ప్రిఫిక్స్ కాల్ల మధ్య బైట్-ఐడెంటికల్గా ఉండాలి, కానీ Diff ప్రతిసారీ మారుతూ ఉంటుంది. సిస్టమ్ ప్రాంప్ట్ మాత్రమే స్థిరంగా ఉంటుంది, అది కనీస క్యాషబుల్ పొడవు కంటే చాలా తక్కువగా ఉంటుంది. సాధారణ నియమం కోసం, ప్రాంప్ట్ క్యాషింగ్ ఎప్పుడు లాభదాయకం చూడండి, మరియు పైన పేర్కొన్న మూడు మోడళ్లలో దేనిని ఎంచుకోవాలో తెలుసుకోవడానికి, ఏ పనికి ఏ Claude మోడల్ వాడాలి చూడండి.
మీరు దీన్ని ఆన్ చేసే ముందు మీ స్వంత Diffలను కొలవండి
payload బిల్డ్ అయిన తర్వాత ఈ లైన్ను జోడించండి, ఆపై గత నెలలోని కొన్ని పుల్ రిక్వెస్ట్లపై మాన్యువల్గా స్క్రిప్ట్ను రన్ చేయండి:
print(client.messages.count_tokens(
model=MODEL, system=SYSTEM, messages=[{"role": "user", "content": payload}]
).input_tokens)కౌంట్ ఎండ్పాయింట్ మోడల్ను రన్ చేయదు, కాబట్టి ఇది ఇన్పుట్ లేదా అవుట్పుట్ టోకెన్లను వినియోగించదు. ఇది మీరు పేర్కొన్న మోడల్కు చెందిన టోకెనైజర్ను ఉపయోగిస్తుంది. మీ స్వంత రిపోజిటరీ నుండి పది నిజమైన పుల్ రిక్వెస్ట్లపై దీన్ని రన్ చేయండి మరియు సగటు (mean) కంటే మధ్యస్థ విలువను (median) తీసుకోండి, తద్వారా ఒక భారీ మైగ్రేషన్ అంచనాను తప్పుదారి పట్టించదు.
రివ్యూ బాట్లను ఎందుకు మ్యూట్ చేస్తారు, దానిని ఎలా నివారించాలి
రెండు రకాల ప్రవర్తనలు ఈ బాట్లపై నమ్మకాన్ని దెబ్బతీస్తాయి. పైన పేర్కొన్న కోడ్లో ఈ రెండింటికీ పరిష్కారాలు ఉన్నాయి.
అన్నింటినీ ఒకేసారి రివ్యూ చేయడం. నలభై కామెంట్లను ఒకేసారి పోస్ట్ చేసే బాట్ వల్ల ఏ ఒక్క కామెంట్ కూడా చదవబడదు. తీవ్రత పరిమితి (severity threshold) మరియు పది కామెంట్ల పరిమితి అనేవి మర్యాద కోసం కాదు, అసలైన లోపాలు కనిపించేలా చేయడానికి ఇవి అవసరం. కామెంట్లను కత్తిరించే ముందు తీవ్రతను బట్టి క్రమబద్ధీకరించడం వల్ల, తక్కువ ప్రాముఖ్యత ఉన్న అంశాలు తొలగించబడతాయి, అంతే కానీ యాదృచ్ఛికంగా పది కామెంట్లు మిగలవు.
తనిఖీ చేయలేని అంశాలపై ఖచ్చితంగా వ్యాఖ్యానించడం. ఇంజనీర్లు బాట్ను శాశ్వతంగా నిలిపివేయడానికి ఇదే ప్రధాన కారణం. 40,000 లైన్ల కోడ్బేస్లో కేవలం 200 లైన్లను మాత్రమే చూసిన మోడల్, తాను ఎప్పుడూ చూడని ఫైల్ గురించి "ఇది redis_client.py లోని cache invalidation ను పాడు చేస్తుంది" అని రాస్తుంది. సిస్టమ్ ప్రాంప్ట్ దీనిని స్పష్టమైన భాషలో నివారిస్తుంది: చూపిన లైన్లలో కనిపించే లోపాలను మాత్రమే నివేదించండి, మీకు ఖచ్చితత్వం లేని దేనినైనా వదిలేయండి. సాధారణంగా ఖచ్చితత్వాన్ని కోరడం కంటే, లోపాన్ని నేరుగా పేర్కొనడం మెరుగ్గా పనిచేస్తుంది. అలాగే, ఫలితం ఏమీ లేకపోవడం సాధారణమేనని మోడల్కు చెప్పడం వల్ల, రెండు లైన్ల మార్పు గురించి కూడా ఏదో ఒకటి చెప్పాలని అది కల్పిత విషయాలను సృష్టించదు.
రివ్యూను COMMENT గా పోస్ట్ చేయండి, ఎప్పుడూ REQUEST_CHANGES గా చేయకండి. ఒక మోడల్ ఇచ్చే అభిప్రాయం మెర్జ్ను ఆపకూడదు. ఒకవేళ అది మెర్జ్ను ఆపగలిగితే, డెడ్లైన్ ఒత్తిడిలో ఉన్న ఎవరైనా సరే, బాట్తో వాదించే బదులు ఆ వర్క్ఫ్లో మొత్తాన్ని తొలగిస్తారు.
వైఫల్య రీతులు మరియు మీరు చూసే స్ట్రింగ్లు
రివ్యూను పోస్ట్ చేస్తున్నప్పుడు HTTP 422 ఎర్రర్. gh అనేది gh: Unprocessable Entity (HTTP 422)ని ప్రింట్ చేస్తుంది మరియు రెస్పాన్స్ బాడీలో ఫీల్డ్ పేరు ఉంటుంది: Pull request review thread line must be part of the diff. GitHub ఆ కామెంట్ను యాంకర్ చేయలేదు. సాధారణంగా మోడల్ సొంతంగా సృష్టించిన లైన్ నంబర్, b/ ప్రిఫిక్స్ను కలిగి ఉన్న path, లేదా తొలగించిన లైన్పై కామెంట్ చేయడం వంటివి దీనికి కారణాలు. తొలగించిన లైన్ విషయంలో sideని RIGHTకి బదులుగా LEFTకి సెట్ చేయాలి. పోస్ట్ చేయడానికి ముందు రివ్యూ JSONని ప్రింట్ చేసి, ఒక కామెంట్ను డిఫ్ (diff)తో సరిపోల్చుకోండి.
మోడల్ API నుండి invalid x-api-key. మొదటి messages.create కాల్ వద్ద ఈ స్టెప్ విఫలమవుతుంది. రిపోజిటరీలో ANTHROPIC_API_KEY సీక్రెట్ సెట్ చేయకపోవడం లేదా ఫోర్క్ (fork) నుండి పుల్ రిక్వెస్ట్ రావడం వల్ల Actions ఏ సీక్రెట్లను పంపకపోవడం దీనికి కారణం. if: లైన్లోని ఫోర్క్ గార్డ్ దీన్ని స్కిప్ చేయాలి, కాబట్టి ముందుగా ఆ లైన్ను తనిఖీ చేయండి.
gh: Resource not accessible by integration (HTTP 403). జాబ్ టోకెన్ పుల్ రిక్వెస్ట్లకు రాయలేదు. permissions: బ్లాక్కు pull-requests: writeని జోడించండి. ఒకవేళ అది ఇప్పటికే ఉంటే, Settings లోకి వెళ్లి, Actions, ఆపై General ని చూడండి. అక్కడ ఉన్న ఆర్గనైజేషన్ పాలసీ వర్క్ఫ్లో టోకెన్ అనుమతులను పరిమితం చేసే అవకాశం ఉంది.
json.decoder.JSONDecodeError. మోడల్ పార్స్ చేయగల JSONని అందించలేదు. టోకెన్ పరిమితిని దాటి రెస్పాన్స్ మధ్యలోనే ఆగిపోవడం దీనికి సాధారణ కారణం. లాగ్ లైన్ దీని కోసం stop_reasonని ప్రింట్ చేస్తుంది: max_tokens విలువ కనిపిస్తే, max_tokensని పెంచండి లేదా MAX_COMMENTSని తగ్గించండి.
వర్క్ఫ్లో అసలు రన్ అవ్వదు. పుల్ రిక్వెస్ట్ కోసం gh run list ఏమీ చూపదు. paths-ignore మార్చబడిన ఫైల్లను ఫిల్టర్ చేయలేదని నిర్ధారించుకోండి. ఆ తర్వాత ఫోర్క్ గార్డ్, లేబుల్ గార్డ్ మరియు VPSలో sudo systemctl status 'actions.runner.*' ద్వారా రన్నర్ యాక్టివ్గా ఉందో లేదో తనిఖీ చేయండి. రన్నర్ ఆఫ్లైన్లో ఉంటే, పుల్ రిక్వెస్ట్లో ఎటువంటి ఎర్రర్ మెసేజ్ లేకుండా జాబ్ క్యూలోనే ఉండిపోతుంది.
ప్రతి రివ్యూ ఖాళీగా వస్తుంది. ఒక రన్ కోసం MIN_SEVERITYని lowకి సెట్ చేయండి. ఫలితాలు కనిపిస్తే, థ్రెషోల్డ్ సరిగ్గా పనిచేస్తున్నట్లు అర్థం. ఏమీ కనిపించకపోతే, payloadని ప్రింట్ చేసి, ఫిల్టర్లు మొత్తం డిఫ్ను తొలగించలేదని నిర్ధారించుకోండి.
మీ ఇతర ఏజెంట్లతో పాటు దీనిని రన్ చేయడం
రివ్యూయర్ పరిమాణంలో చిన్నదిగా ఉంటుంది, కాబట్టి ఇప్పటికే అన్నీ నడుస్తున్న సర్వర్లోనే దీనిని కూడా ఉంచాలనిపించడం సహజం. కానీ రిపోజిటరీ భద్రత ముఖ్యమైతే, దీనిని విడిగా ఉంచండి. ఈ ప్రాసెస్ మీ కోడ్పై వ్యాఖ్యానించగల టోకెన్ను మరియు మీ డబ్బును ఖర్చు చేయగల కీని కలిగి ఉంటుంది. సెల్ఫ్-హోస్టెడ్ రన్నర్ అనేది డిజైన్ పరంగానే వర్క్ఫ్లో కోడ్ ఎగ్జిక్యూట్ అయ్యే ప్రదేశం. sudo హక్కులు లేని ఒక ప్రత్యేక అన్ప్రివిలేజ్డ్ అకౌంట్, మరే ఇతర సేవలు నడవని హోస్ట్లో ఉండటమే ప్రాథమిక భద్రతా ప్రమాణం. మీరు కోడ్ను చెక్-అవుట్ చేసే ఇంటరాక్టివ్ ఏజెంట్లను కూడా రన్ చేస్తుంటే, ప్రతి ఏజెంట్కు ఒక డిస్పోజబుల్ VM వాడటం సరైన పద్ధతి. అలాగే VPS పై కోడింగ్ ఏజెంట్ను రన్ చేయడం సాధారణ సెటప్ను వివరిస్తుంది. మీకు Anthropic API కొత్త అయితే, VPS పై మొదటి Claude API యాప్ దీనికంటే చిన్న స్థాయిలో ప్రారంభించడానికి అనువుగా ఉంటుంది.
FAQ
AI PR రివ్యూ ఏజెంట్కు నా రిపోజిటరీకి రైట్ యాక్సెస్ అవసరమా?
అవసరం లేదు. రివ్యూను పోస్ట్ చేయడానికి దీనికి pull-requests: write మరియు డిఫ్ (diff) పొందడానికి contents: read మాత్రమే అవసరం. ఇది పూర్తి జాబితా, మరియు మీరు దీన్ని వర్క్ఫ్లోలోని permissions: బ్లాక్లో సెట్ చేస్తారు, ఇది ప్రతి జాబ్ యొక్క GITHUB_TOKEN చేయగలిగే పనులను పరిమితం చేస్తుంది. ఈ రెండు లైన్లతో, ఏజెంట్ పుల్ రిక్వెస్ట్పై కామెంట్ చేయగలదు కానీ కమిట్ను పుష్ చేయలేదు లేదా బ్రాంచ్ను మెర్జ్ చేయలేదు. రివ్యూలను REQUEST_CHANGES కి బదులుగా event: COMMENT తో పోస్ట్ చేయండి, తద్వారా అది మెర్జ్ను అడ్డుకోలేదు.
నా రివ్యూ కామెంట్ HTTP 422తో ఎందుకు విఫలమవుతోంది?
GitHub ఇన్లైన్ రివ్యూ కామెంట్ను పుల్ రిక్వెస్ట్ డిఫ్లో భాగంగా ఉన్న లైన్పై మాత్రమే అంగీకరిస్తుంది, అది లేనప్పుడు Pull request review thread line must be part of the diffని తిరిగి ఇస్తుంది. path అనేది డిఫ్ హెడర్ నుండి ఎటువంటి b/ ప్రిఫిక్స్ లేకుండా రిపోజిటరీకి సంబంధించి ఉందని, మరియు లైన్ నంబర్ ఆ ఫైల్ యొక్క హంక్ (hunk) లోపల కనిపిస్తుందని నిర్ధారించుకోండి. side అనేది కొత్తగా చేర్చిన లేదా మార్పు లేని లైన్ కోసం RIGHT గా, మరియు తొలగించిన లైన్ కోసం LEFT గా ఉండాలి. డిఫ్లోని ప్రతి లైన్కు దాని కొత్త ఫైల్ లైన్ నంబర్ను ప్రిఫిక్స్గా జోడించి మోడల్కు పంపడం వల్ల, మోడల్ సొంతంగా నంబర్లను ఊహించకుండా ఆపవచ్చు.
ఫోర్క్ (fork) నుండి వచ్చే పుల్ రిక్వెస్ట్లతో పబ్లిక్ రిపోజిటరీపై దీన్ని రన్ చేయవచ్చా?
ఈ డిజైన్తో సాధ్యం కాదు. ఫోర్క్ నుండి ట్రిగ్గర్ అయిన వర్క్ఫ్లోకు GitHub సీక్రెట్స్ను పంపదు, కాబట్టి మోడల్ కీ అందుబాటులో ఉండదు మరియు రన్ విఫలమవుతుంది. GitHub కూడా సెల్ఫ్-హోస్టెడ్ రన్నర్లను "పబ్లిక్ రిపోజిటరీల కోసం దాదాపు ఎప్పుడూ ఉపయోగించకూడదు" అని పేర్కొంది, ఎందుకంటే ఎవరైనా మీ మెషీన్పై కోడ్ రన్ అయ్యేలా పుల్ రిక్వెస్ట్ను ఓపెన్ చేయవచ్చు. పబ్లిక్ ప్రాజెక్ట్ కోసం, రివ్యూయర్ను రిపోజిటరీకే పుష్ చేసిన బ్రాంచ్లకు పరిమితం చేయండి (దీనినే if: గార్డ్ చేస్తుంది), లేదా రివ్యూ స్టెప్ను GitHub-హోస్టెడ్ రన్నర్కు మార్చండి మరియు డిఫ్ మీ స్వంత ఇన్ఫ్రాస్ట్రక్చర్ నుండి బయటకు వెళ్తుందని అంగీకరించండి.
పుల్ రిక్వెస్ట్ రివ్యూ కోసం నేను ఏ మోడల్ను ఉపయోగించాలి?
Haiku 4.5 తో ప్రారంభించండి. నిర్ణీత లోపాల జాబితాకు వ్యతిరేకంగా పరిమితమైన డిఫ్ను చదవడం అనేది కష్టమైన రీజనింగ్ సమస్య కాదు, మరియు అత్యంత చౌకైన మోడల్ నెలవారీ బిల్లును ఎవరూ అభ్యంతరం చెప్పని స్థాయిలో ఉంచుతుంది. మీ లాంగ్వేజ్ లేదా ఫ్రేమ్వర్క్లో నిజమైన బగ్లను గుర్తించడంలో ఇది విఫలమవుతుందని మీరు భావిస్తే Sonnet 5 కి మారండి, ఊహించడం కంటే దీన్ని కొలమానంగా తీసుకోండి. Opus 5 అనేది ప్రతి పుల్ రిక్వెస్ట్కు మిగిలిన రెండింటి కంటే చాలా ఖరీదైనది, దీన్ని ప్రతి ఫీచర్ బ్రాంచ్ పుష్పై కంటే రిలీజ్ బ్రాంచ్పై ఉపయోగించడం సమర్థనీయం.