游乐游手机版
首页/AI教程/文章详情

LangChain代码审查Agent搭建三大踩坑与解决方案

时间:2026-06-11 16:46
基于LangChain搭建代码审查Agent时遇到三个主要问题:Token超限导致仅部分代码被审查,通过分块处理解决;输出建议不具体,采用结构化输出强制指定行号和修改方案;成本过高,改用GPT-3 5初筛再结合GPT-4深度审查,节省95%成本。

利用Agent自动进行代码审查,这个设想听起来很理想——能够显著节省人力成本。

我用LangChain搭了个代码审查Agent,踩了3个坑

最初以为实现起来很容易:通过GitHub API获取PR diff,然后交给GPT-4处理,等待它返回审查意见即可。然而实践后发现,事情远没那么简单——我接连踩了三个坑,白白浪费了一周时间。

坑1:Token超限,Review只审查了一半内容

PR中包含2000行代码,但Agent只分析了前500行就给出了结论——剩下的部分完全被忽略了。

问题根源在哪?GPT-4的上下文窗口限制为8K tokens,2000行代码加上diff格式,早已超出了这个容量。

初次尝试的代码如下:

from langchain_openai import ChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts import ChatPromptTemplate

llm = ChatOpenAI(model="gpt-4", temperature=0)
prompt = ChatPromptTemplate.from_template("Review this PR:{diff}Provide suggestions.")
chain = LLMChain(llm=llm, prompt=prompt)
result = chain.run(diff=pr_diff)

结果:只处理了前300行。

如何解决?最简单的办法:将代码分割成小块,每块500行,逐个审查,最后汇总所有意见。

from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
    chunk_size=4000,
    chunk_overlap=0,
    separators=["", "", " "]
)
chunks = splitter.split_text(pr_diff)
reviews = []
for chunk in chunks:
    review = chain.run(diff=chunk)
    reviews.append(review)

# 汇总所有意见
summary_prompt = ChatPromptTemplate.from_template("Summarize these reviews:{reviews}")
summary_chain = LLMChain(llm=llm, prompt=summary_prompt)
final_review = summary_chain.run(reviews="".join(reviews))

坑2:给出了一堆“建议”,但没有一条能落地执行

另一个令人头疼的问题:Agent总是说“建议优化性能”“建议增加错误处理”——但具体需要修改哪一行?完全没有指明。

根本原因在于Prompt写得太笼统。最初使用的提示是:

Review this PR and provide suggestions.

结果可想而知,输出了一大堆空洞的套话。

那该怎么办?强制要求Agent输出具体的行号和代码示例。通过结构化的输出格式,让Agent必须提供可落地的修改意见。

from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
from typing import List

class CodeReviewIssue(BaseModel):
    line_number: int = Field(description="Line number of the issue")
    severity: str = Field(description="Issue severity: high/medium/low")
    description: str = Field(description="Issue description")
    suggestion: str = Field(description="How to fix")

class CodeReview(BaseModel):
    issues: List[CodeReviewIssue] = Field(description="List of issues")

parser = PydanticOutputParser(pydantic_object=CodeReview)
prompt = ChatPromptTemplate.from_template(
    "Review this PR:{diff}"
    "{format_instructions}"
    "Return ONLY the structured output."
)
format_instructions = parser.get_format_instructions()
chain = LLMChain(llm=llm, prompt=prompt, output_parser=parser)
review = chain.run(diff=chunk, format_instructions=format_instructions)
for issue in review.issues:
    print(f"Line {issue.line_number} [{issue.severity}]: {issue.description}")
    print(f"Suggestion: {issue.suggestion}")

输出示例立刻变得可操作:

Line 42 [high]: Potential SQL injection vulnerability
Suggestion: Use parameterized queries:
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))

Line 87 [medium]: Missing error handling
Suggestion: Add try-except block:
try:
    response = requests.get(url)
    response.raise_for_status()
except RequestException as e:
    logger.error(f"Request failed: {e}")

这才是关键所在——审查意见必须能直接指导代码修改,否则就是徒劳无功。

坑3:成本爆炸,审查一个PR花费了30美元

最后一个坑最令人心疼——费用。使用GPT-4审查一个1000行的PR,消耗了200K tokens,折合30美元。

为什么这么贵?GPT-4本身价格就不低,而且每次都需要将完整的diff发送过去。最初计算时觉得还算合理:

1000行diff ≈ 10K tokens
分块20块,每块5K tokens
GPT-4 input 0.03/1K tokens,output 0.06/1K tokens
总成本:(20 * 5K * 0.03) + (20 * 1K * 0.06) = 3 + 1.2 = 4.2美元

但实际上消耗了200K tokens,因为Agent反复尝试不同的审查策略,一下子就飙升到了30美元。

解决方案很实际:换个策略。先用GPT-3.5-turbo进行快速初筛,找出可能存在问题的文件,然后仅对这些文件使用GPT-4做深度审查。效率几乎不受影响,成本却大幅下降。

# 先用GPT-3.5快速扫描
llm_fast = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
quick_scan_prompt = ChatPromptTemplate.from_template(
    "Quick scan this PR and identify files with potential issues:{diff}"
    "Return ONLY the list of files that need detailed review."
)
scan_chain = LLMChain(llm=llm_fast, prompt=quick_scan_prompt)
files_to_review = scan_chain.run(diff=pr_diff)

# 只对问题文件用GPT-4深度Review
llm_deep = ChatOpenAI(model="gpt-4", temperature=0)
for file in files_to_review:
    file_diff = extract_file_diff(pr_diff, file)
    review = deep_review_chain.run(diff=file_diff)

成本对比直接说明了效果:

方案1:纯GPT-4,200K tokens,30美元
方案2:GPT-3.5初筛 + GPT-4深度,20K tokens GPT-3.5 + 50K tokens GPT-4,0.06 + 1.5 = 1.56美元
节省:95%成本

最终方案:完整代码

经过一番折腾,最终方案融合了前面所有的技巧——分块避免Token超限,结构化输出保证可执行性,组合模型控制成本。下面是完整的代码实现:

import os
from typing import List
from github import Github
from langchain_openai import ChatOpenAI
from langchain.chains import LLMChain
from langchain.prompts import ChatPromptTemplate
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field

# GitHub配置
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
github = Github(GITHUB_TOKEN)

# LangChain配置
llm_fast = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)
llm_deep = ChatOpenAI(model="gpt-4", temperature=0)

class CodeReviewIssue(BaseModel):
    line_number: int
    severity: str
    description: str
    suggestion: str

class CodeReview(BaseModel):
    issues: List[CodeReviewIssue]

parser = PydanticOutputParser(pydantic_object=CodeReview)

def get_pr_diff(repo_name: str, pr_number: int) -> str:
    """获取PR的diff"""
    repo = github.get_repo(repo_name)
    pr = repo.get_pull(pr_number)
    return pr.get_files()[0].patch

def quick_scan(diff: str) -> List[str]:
    """快速扫描,识别需要Review的文件"""
    prompt = ChatPromptTemplate.from_template(
        "Quick scan this PR and identify files with potential issues:{diff}"
        "Return ONLY the list of file paths, one per line."
    )
    chain = LLMChain(llm=llm_fast, prompt=prompt)
    result = chain.run(diff=diff)
    return [f.strip() for f in result.split("") if f.strip()]

def deep_review(diff: str) -> CodeReview:
    """深度Review"""
    splitter = RecursiveCharacterTextSplitter(
        chunk_size=4000,
        chunk_overlap=0,
        separators=["", "", " "]
    )
    chunks = splitter.split_text(diff)
    all_issues = []
    for chunk in chunks:
        prompt = ChatPromptTemplate.from_template(
            "Review this code:{diff}"
            "{format_instructions}"
            "Return ONLY the structured output."
        )
        chain = LLMChain(llm=llm_deep, prompt=prompt, output_parser=parser)
        review = chain.run(diff=chunk, format_instructions=parser.get_format_instructions())
        all_issues.extend(review.issues)
    return CodeReview(issues=all_issues)

def post_review_comment(repo_name: str, pr_number: int, review: CodeReview):
    """在PR上发布Review评论"""
    repo = github.get_repo(repo_name)
    pr = repo.get_pull(pr_number)
    for issue in review.issues:
        pr.create_review_comment(
            body=f"**[{issue.severity.upper()}]** {issue.description}"
                 f"Suggestion: {issue.suggestion}",
            commit=pr.get_commits().reversed[0],
            path="src/main/java/example/Example.java",
            position=issue.line_number
        )

def review_pr(repo_name: str, pr_number: int):
    """完整的Review流程"""
    diff = get_pr_diff(repo_name, pr_number)
    files_to_review = quick_scan(diff)
    for file in files_to_review:
        file_diff = extract_file_diff(diff, file)
        review = deep_review(file_diff)
        post_review_comment(repo_name, pr_number, review)

# 使用示例
if __name__ == "__main__":
    review_pr("helloworldtang/mq-tutorial", 123)

GitHub项目地址:https://github.com/helloworldtang/ai-code-review-agent

一句话总结:分块处理避免Token超限,结构化输出确保可执行性,GPT-3.5与GPT-4组合使用降低成本。

来源:https://cloud.tencent.com.cn/developer/article/2685479
上一篇月编程语言榜:Python飙升Java跌出前三,AI烧钱引关注 下一篇AF_Cache:用于高通量蛋白质相互作用预测的AlphaFold高效化流程
本站内容用于信息整理与展示,如有侵权或内容问题请及时联系处理。

相关推荐

补充同频道和同主题内容,方便继续浏览更多相关内容。

同类最新

继续查看同栏目最近更新的文章。

更多
CapCut AI Docker 一键部署:镜像拉取、端口映射与数据目录配置教程
AI教程 · 2026-06-30

CapCut AI Docker 一键部署:镜像拉取、端口映射与数据目录配置教程

CapCutAI容器化部署需先确认镜像来源与授权范围,再完成环境准备、镜像拉取、端口映射、数据目录挂载和启动验证,适合本地试用、团队内网演示与轻量化AI剪辑服务管理。

CapCut AI Windows本地安装配置2026最新版含下载与环境要求
AI教程 · 2026-06-30

CapCut AI Windows本地安装配置2026最新版含下载与环境要求

CapCutAI与剪映AI在Windows端适合短视频、口播、课程和营销素材剪辑,安装前需确认系统、显卡、存储与网络条件,优先选择官方渠道下载,并完成账号、素材目录、硬件加速和导出参数配置。

Veo新手保姆级安装教程:从下载到首次运行
AI教程 · 2026-06-30

Veo新手保姆级安装教程:从下载到首次运行

Veo适合用文字生成短视频,新手应先确认官方入口、准备账号与设备环境,再按网页或应用方式完成启用。首次运行重点在提示词、参数、素材合规与结果保存,避免使用非官方安装包。

Veo本地模型运行下载路径设置与性能优化指南
AI教程 · 2026-06-30

Veo本地模型运行下载路径设置与性能优化指南

Veo本地模型部署需先确认模型来源与硬件条件,再完成下载校验、目录规划、路径配置和推理参数优化。重点关注显存占用、依赖版本、缓存位置、授权范围与常见报错处理。

Veo安装失败解决指南:常见报错与日志排查及升级回滚方案
AI教程 · 2026-06-30

Veo安装失败解决指南:常见报错与日志排查及升级回滚方案

Veo安装失败通常与系统环境、依赖版本、网络源、权限和缓存有关。排查时应先确认版本要求,再查看安装日志,按报错类型处理,并提前备份项目,确保升级与回滚可控。