GitHub is the central hub of software development — where code is written, reviewed, and shipped. AI agents with GitHub access can transform repositories from passive code stores into actively managed systems where issues are triaged automatically, pull requests receive intelligent review comments, and CI failures get analyzed and resolved faster.
For engineering teams drowning in review backlogs, issue queues, and repetitive code tasks, integrating AI agents with GitHub is one of the highest-ROI automation investments available.
What AI Agents Can Do With GitHub Access#
AI agents connected to GitHub unlock a broad set of developer workflow automations:
Pull Request Automation
- Review new PRs and post specific, actionable comments on code quality, potential bugs, and style violations
- Suggest missing test coverage based on what code changed
- Summarize large PRs into human-readable descriptions for reviewers
- Check for breaking API changes in library updates
Issue Management
- Triage new issues: assign labels (bug, enhancement, question), set priority, and route to relevant team members
- Identify duplicate issues by searching existing tickets for semantic similarity
- Auto-respond to common questions using repository documentation
- Generate weekly issue summaries for engineering leads
Code Generation and Fixes
- Implement straightforward bug fixes in a new branch based on issue descriptions
- Generate boilerplate for new features from specifications
- Refactor specific files on request and open PRs with changes
Release Automation
- Generate changelogs from merged PR descriptions
- Create release notes that classify changes by type (feature, fix, breaking change)
- Draft announcement blog posts from release notes
For related patterns, see AI agent examples for software engineering.
Setting Up GitHub API Access#
Option A: Personal Access Token (Development)#
- Go to GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens
- Click Generate new token
- Set repository access to your target repositories
- Grant permissions: Contents (Read), Pull requests (Read & Write), Issues (Read & Write)
- Copy the token and store in your environment
export GITHUB_TOKEN="github_pat_your_token_here"
export GITHUB_REPO_OWNER="your-org"
export GITHUB_REPO_NAME="your-repo"
Option B: GitHub App (Production)#
For production deployments with better security:
- Go to GitHub → Settings → Developer settings → GitHub Apps → New GitHub App
- Configure permissions: Contents (Read), Pull requests (Read & Write), Issues (Read & Write)
- Subscribe to events: pull_request, issues, issue_comment
- After creation, install the App on your repositories
- Generate and store the App's private key for JWT authentication
Option 1: No-Code Integration with n8n#
Best for: Teams who want GitHub automation without writing Python
n8n's GitHub nodes handle most common GitHub workflows:
Automated PR Review Notification Workflow#
- Add a GitHub Trigger node — event:
Pull Request, action:opened - Add an OpenAI node — prompt: "Review this pull request description and changed files list. Identify potential issues and suggest improvements."
- Add a GitHub node — action:
Create Issue Commenton the PR
This three-node workflow automatically reviews and comments on every new PR without any custom code.
Issue Triage Workflow#
- GitHub Trigger: event
Issues, actionopened - OpenAI: "Classify this issue. Return JSON:
{"labels": [], "priority": "low|medium|high", "assignee_team": ""}" - Code node: Parse JSON response
- GitHub: Add labels, set milestone, post welcome comment
Option 2: LangChain with Python#
Best for: Custom agent logic with fine-grained control over GitHub operations
Installation#
pip install langchain langchain-openai PyGithub python-dotenv
Build GitHub Tools#
import os
from github import Github
from langchain.tools import tool
from dotenv import load_dotenv
load_dotenv()
gh = Github(os.getenv("GITHUB_TOKEN"))
repo = gh.get_repo(f"{os.getenv('GITHUB_REPO_OWNER')}/{os.getenv('GITHUB_REPO_NAME')}")
@tool
def get_pull_request(pr_number: int) -> str:
"""Get details about a specific pull request including title, description, and changed files."""
pr = repo.get_pull(pr_number)
files = [f.filename for f in pr.get_files()]
return f"""PR #{pr_number}: {pr.title}
Author: {pr.user.login}
State: {pr.state}
Description: {pr.body or 'No description provided'}
Changed files: {', '.join(files[:20])}
{'...' if len(files) > 20 else ''}"""
@tool
def post_pr_comment(pr_number: int, comment: str) -> str:
"""Post a review comment on a pull request."""
pr = repo.get_pull(pr_number)
pr.create_issue_comment(comment)
return f"Comment posted on PR #{pr_number}"
@tool
def get_pr_diff(pr_number: int) -> str:
"""Get the diff (code changes) for a pull request. Returns first 4000 chars."""
pr = repo.get_pull(pr_number)
files = pr.get_files()
diff_text = []
for f in files:
diff_text.append(f"File: {f.filename}\n{f.patch or 'Binary file'}")
return "\n---\n".join(diff_text)[:4000]
@tool
def create_issue(title: str, body: str, labels: list = None) -> str:
"""Create a new GitHub issue with optional labels."""
issue = repo.create_issue(
title=title,
body=body,
labels=labels or []
)
return f"Issue #{issue.number} created: {issue.html_url}"
@tool
def list_open_issues(label: str = None) -> str:
"""List open issues in the repository, optionally filtered by label."""
issues = repo.get_issues(state='open', labels=[label] if label else [])
result = []
for issue in list(issues)[:20]:
result.append(f"#{issue.number}: {issue.title} (Labels: {[l.name for l in issue.labels]})")
return "\n".join(result) or "No open issues found"
@tool
def add_issue_labels(issue_number: int, labels: list) -> str:
"""Add labels to a GitHub issue."""
issue = repo.get_issue(issue_number)
issue.add_to_labels(*labels)
return f"Labels {labels} added to issue #{issue_number}"
PR Review Agent#
from langchain_openai import ChatOpenAI
from langchain.agents import create_tool_calling_agent, AgentExecutor
from langchain_core.prompts import ChatPromptTemplate
llm = ChatOpenAI(model="gpt-4o", temperature=0)
tools = [get_pull_request, get_pr_diff, post_pr_comment,
create_issue, list_open_issues, add_issue_labels]
prompt = ChatPromptTemplate.from_messages([
("system", """You are a senior software engineer conducting code reviews on GitHub.
When reviewing a PR:
1. Get the PR details and diff
2. Analyze for: bugs, security issues, performance problems, missing tests, style violations
3. Post a constructive, specific comment highlighting concerns and suggestions
4. Be encouraging — acknowledge good patterns alongside issues
5. Keep comments concise and actionable
When triaging issues:
1. Read the issue carefully
2. Classify: bug, enhancement, documentation, or question
3. Assess priority based on impact and urgency
4. Add appropriate labels
5. Post a helpful response"""),
("human", "{input}"),
("placeholder", "{agent_scratchpad}"),
])
agent = create_tool_calling_agent(llm, tools, prompt)
executor = AgentExecutor(agent=agent, tools=tools, verbose=True, max_iterations=8)
# Review a specific PR
result = executor.invoke({"input": "Review PR #47 and post a constructive code review comment"})
print(result["output"])
Real-World Use Case: Automated Issue Triage Agent#
A high-volume open-source repository receives 50+ issues per week. This agent runs on a schedule to triage unprocessed issues:
from datetime import datetime, timedelta
def run_issue_triage_agent():
"""Triage all issues opened in the last 24 hours."""
cutoff = datetime.now() - timedelta(hours=24)
# Get recent issues without labels (untriaged)
recent_issues = repo.get_issues(state='open', since=cutoff)
untriaged = [i for i in recent_issues if not i.labels]
for issue in untriaged[:10]: # Process up to 10 per run
result = executor.invoke({
"input": f"""Triage this GitHub issue:
Title: {issue.title}
Body: {issue.body or 'No description'}
Issue number: {issue.number}
1. Add appropriate labels (bug/enhancement/documentation/question/duplicate)
2. Post a helpful response acknowledging the issue and asking for clarification if needed
3. If it looks like a duplicate, mention that in your comment"""
})
print(f"Triaged #{issue.number}: {result['output']}")
# Run on schedule via cron or GitHub Actions
run_issue_triage_agent()
This pattern is described in the autonomous agent patterns tutorial.
GitHub Actions Integration#
Deploy your AI agent as a GitHub Actions workflow for zero-infrastructure operation:
# .github/workflows/ai-pr-review.yml
name: AI PR Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: pip install openai PyGithub
- name: Run AI Review
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
PR_NUMBER: ${{ github.event.pull_request.number }}
run: python scripts/ai_pr_review.py
Rate Limits and Best Practices#
| Credential type | Rate limit | Best for |
|---|---|---|
| Personal Access Token | 5,000 req/hour | Development, single-repo agents |
| GitHub App | 5,000+ req/hour (scales) | Production, multi-repo deployments |
| GitHub Actions token | 1,000 req/hour | CI/CD pipeline agents |
Production best practices:
- Cache PR diffs: Store retrieved diffs to avoid re-fetching for the same commit SHA
- Respect rate limits: Check
X-RateLimit-Remainingheaders and pause before hitting limits - Use GraphQL for complex queries: GraphQL is more efficient for fetching nested data (PR + files + reviews in one request)
- Validate webhook signatures: Always verify
X-Hub-Signature-256headers before processing webhooks - Limit auto-actions: Use agent for read/comment operations; require human approval for merge/push actions
Next Steps#
- Build an AI Agent with LangChain — Complete framework tutorial
- AI Agents Jira Integration — Pair GitHub with Jira for full project tracking
- AI Agents Linear Integration — Modern project management alternative to Jira
- Tool Calling in AI Agents — How agents invoke GitHub API tools
- AI Agent Examples in Engineering — Real engineering automation patterns