[控场AI]
· 6 分钟阅读· 3,037 字

基于LangGraph.js的自托管GitLab AI审查Agent实战

基于LangGraph.js的自托管GitLab AI审查Agent实战

一个自托管GitLab AI Agent在生产环境审查1000+合并请求,三分之二建议被采纳,核心经验是靠中间件而非Prompt保障可靠性。

一位开发者基于LangGraph.js构建的GitLab代码审查Agent已在生产环境运行数月,累计审查1000+合并请求,约三分之二的评论被MR作者采纳。项目最核心的工程经验有三点:其一,Agent系统的真正难点不在核心逻辑,而在失败处理——用中间件节点拦截循环、重复调用等异常,比反复调整Prompt更可靠;其二,引入Critic(评审)步骤,在评论发布前筛掉约四分之一的低价值内容,是高采纳率的直接原因;其三,按项目维护带去重和淘汰机制的记忆,保证Agent在数百次运行后仍保持实用性。此外,项目使用4-bit量化的Qwen3.6-35B-A3B配合sglang本地部署,并曾抓出Claude Sonnet/Opus编写代码中的真实错误,为关注数据隐私的团队提供了自托管方案的参考价值。

一个在生产环境跑了几个月的代码审查Agent

一位开发者在Reddit上分享了他基于 LangGraph.js 构建的自托管 GitLab AI Agent。这个工具的能力不止于概念演示——它已经在生产环境运行了数月,累计审查了 1000+ 个合并请求(Merge Request),自 6 月以来经历了 133 次发布迭代。

更值得关注的是实际效果数据:该 Agent 产生的审查评论中,约有三分之二被 MR 作者采纳并解决。对于一个自动化工具而言,这个采纳率意味着它输出的建议具备真实的工程价值,而非制造噪音。

这个 Agent 的职责范围覆盖三块:审查合并请求、处理 issue、以及提供对话式交互。项目以 MIT 协议开源,命名为 langgraph-harness。

reddit source: I built a self-hosted AI agent for GitLab on LangGraph.js. It has reviewed 1,000+ merge requests

真正的难点不在Agent逻辑,而在失败处理

作者坦言了一个反直觉的经验:大部分工作量并不在编写 Agent 的核心逻辑上。真正棘手的是处理那些实际运行中出现的失败模式。

他观察到三类典型故障:

  • Agent 陷入循环,无法正常收敛
  • 重复调用同一个工具,做无意义的重复动作
  • 以一个悬而未决的提问结束整个运行,而不是给出结论

针对这些问题,作者的解法不是靠不断调整 Prompt,而是引入了小型中间件节点(middleware nodes),在运行过程中实时捕获这些异常状态并进行纠正。他明确指出,这种做法「比单纯用 Prompt 修复更便宜也更可靠」。

这是一个值得工程师借鉴的思路——在 Agent 系统中,与其寄希望于大模型本身永远表现稳定,不如在流程层面设置拦截与纠偏机制,把不确定性约束在可控范围内。

LangGraph 是一个基于图结构的 Agent 编排框架,将 Agent 的执行过程建模为有向图:节点(node)代表具体的操作或大模型调用,边(edge)代表状态转移条件。这种结构天然支持循环——Agent 可以反复调用工具、评估结果并决定下一步,直到满足终止条件。然而,正是这种灵活性带来了上文提到的几类典型故障:当终止条件定义不清晰,或大模型输出不符合预期时,Agent 可能陷入无限循环,或在应当给出结论时转而抛出新问题。中间件节点(middleware nodes)本质上是插入执行图中的"守卫"节点,它们不执行业务逻辑,而是检查当前状态是否偏离预期轨道,并在必要时强制修正或终止流程。这种在编排层面做健壮性保障的思路,与微服务架构中的熔断器(circuit breaker)模式有异曲同工之处。

Critic步骤:过滤掉低价值评论

高采纳率的背后,有一个关键设计:Critic(评审)步骤。在评论正式发布到 MR 之前,系统会先对草拟的评论进行筛查,剔除其中价值较低的内容。

按作者的数据,这个环节到目前为止丢弃了大约四分之一的草拟评论。换句话说,Agent 并不会把生成的所有意见一股脑丢给开发者,而是先做一轮自我审视。这正是前文提到的三分之二采纳率得以成立的重要原因——减少无效评论,本身就是提升信噪比的直接手段。

自托管模型抓出了Claude写的Bug

这个项目最有意思的一个细节是:这套审查工具会审查它自己的代码仓库。

其默认的自托管配置使用 Qwen3.6-35B-A3B 模型(4-bit 量化,通过 sglang 部署)。作者透露,这个本地部署的模型,曾经抓出了原本由 Claude Sonnet / Opus 编写的代码中的真实错误。

他特别强调这「不是基准测试,只是碰巧发生了」。这个观察虽然不构成严格的性能对比,但它传递出一个信号:在特定的代码审查场景下,一个经过良好工程封装的中等规模自托管模型,完全有能力捕捉到顶级闭源模型遗留的问题。对于注重数据隐私、不希望把代码送往外部 API 的团队来说,这是一个有说服力的参考案例。

Qwen3.6-35B-A3B 是阿里巴巴通义千问广告系列的一个混合专家(MoE)模型,总参数量约 36B,但激活参数仅约 3.5B,因此推理成本显著低于同规模稠密模型。4-bit 量化(quantization)是将模型权重从 16/32 位浮点数压缩为 4 位整数表示的技术,可在几乎不损失实用精度的前提下,将模型内存占用压缩至约原来的四分之一,使得在消费级或中端 GPU 上本地部署 35B 级模型成为可能。sglang 是一个专为大语言模型推理优化的高性能服务框架,支持连续批处理(continuous batching)和 RadixAttention 等技术,相比 Ollama 等工具在吞吐量上更具优势,适合有一定并发需求的生产场景。这套组合——MoE 架构 + 激进量化 + 高效推理框架——代表了当前本地部署实用化 LLM 的主流技术路径。

按项目维度的记忆机制

长期运行的 Agent 会面临一个现实问题:如何在数百次运行后依然保持有用,而不是不断重复犯错或给出已被否决的建议。

作者的方案是按项目(per project)维护记忆。系统会提取并沉淀以下几类信息:

  • 项目的编码约定(conventions)
  • 反复出现的误报(recurring false positives)
  • 过往已做出的决策(past decisions)

这些记忆会被去重并随时间淘汰(deduped and retired),避免记忆无限膨胀导致质量下降。正是这套机制,让 Agent 在跑了几百次之后仍然能保持实用性,而不是沦为噪音发生器。

Agent 记忆的「新陈代谢」问题在学术上对应 RAG(检索增强生成)系统的知识库维护难题,在工程上则更接近缓存失效(cache invalidation)问题。如果记忆只增不减,随着时间推移,早期记录的编码约定可能已被推翻,曾经的误报模式在新版本中已修复,但这些过时信息仍会被检索并影响 Agent 判断。去重(deduplication)解决的是语义重复问题——同一条约定被多次记录后,不应在上下文中重复出现占用有效长度。「淘汰(retire)」则通常基于时间衰减或访问频率:长期未被命中的记忆条目会被降权或删除。这两个机制共同维持记忆库在有限规模内保持高信息密度,是 Agent 在长期运行后不退化为噪音源的关键工程保障。

对生产级LangGraph实践的启示

这个案例对正在或计划用 LangGraph 构建生产系统的开发者,提供了几点可迁移的经验:

工程的重心应该放在可靠性保障上,而非一味打磨 Agent 的「智能」。循环检测、重复调用拦截、运行终态校验这些看似琐碎的中间件,才是让系统能在生产环境稳定运行数月的真正支柱。

Critic 式的二次筛查能显著提升输出质量,用一个额外的审查环节换来采纳率的提升,是划算的交易。

记忆的「新陈代谢」同样关键——持续累积而不清理的记忆,最终会成为负担。去重与淘汰机制值得在设计初期就纳入考虑。

作者在帖子最后抛出了一个开放问题:其他在生产环境运行 LangGraph 的人,是否也遇到了同样的问题?这恰恰说明,Agent 的生产化落地仍处在集体摸索阶段,这类真实的工程复盘比任何理论都更有价值。

分享:

相关推荐