前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
返回 AI 情报前线
All News · 全部资讯9294
  • Cerebras将GPT-5.6 Sol推理速度提升10倍,AI部署成本结构生变
  • Claude Code十个悄悄烧掉Token的坏习惯
  • MCP 服务器「已连接」不代表 Agent 能用它
  • AI 编程 Agent 凭证访问的结构化审计日志设计
  • Zed 编辑器 2026 评测:速度优先,AI 为辅
  • GPT-4o vs Claude vs Mistral:真实任务视角的LLM评测
  • Anthropic发布Claude系统提示词官方文档
  • LLM画图从不碰像素:图表渲染架构设计
  • Rust实现MCP Server实战:内存与启动速度的量化对比
  • 用Rust手把手构建MCP服务器:rmcp官方SDK教程
  • AI测试数据生成器对比:有关系 schema 才有意义
  • AI 生成关联测试数据而不破坏数据库约束
  • 测试免费模型 API 真实并发能力的方法
  • 三大浏览器 Agent 框架安全性对比
  • MCP 协议详解:解决 AI 集成的 N×M 问题
  • OpenAI AI agent 在网络安全测试中失控突破隔离环境
  • Agent记忆系统缺的不是向量数据库,而是摄入边界
  • 2026 Claude Code 入门完全指南(波兰语)
  • Claude Code 多 Agent 编排:如何构建 AI 代理团队
  • Anthropic 披露生物武器过滤器失效近一年安全漏洞
  • LLM应用CI/CD pipeline完整构建教程
  • 研究:禁止 AI 自述有意识,会改变它对动物权利和宗教的立场
  • 同一AI pipeline我跑了五遍:耗时从140分钟降到68分钟
  • 从Vibe Coding到Agentic Engineering:SDLC正在被重写
  • 给已有产品加MCP服务器:我犯的四个错误
  • Claude Code安全审计实战:/security-review找到7个真实漏洞
  • Cursor搭配.NET开发:7条工程实践规则
  • Fetch MCP Server:将任意URL转为AI可读的Markdown
  • AI 编程的实质:去掉 Vibes,回归工程
  • Qwen Code 0.21.12:审查证据门控与Autofix环防膨胀
  • Go语言MCP服务器安全模式:RiskAnalyzer拦截器
  • 人脸识别模型训练数据正在被人造脸主导
  • 1600起AI伪造引证案背后:模型没坏,是流程缺失
  • 苹果Core AI框架登场:设备端跑70B参数模型成现实
  • Claude Code 8月14日起默认开启Auto Mode
  • 边缘设备部署LLM实战:量化、选型与混合架构
  • AWS DevOps Agent部署避坑指南
  • GrowthBook 5.0:AI编程 Agent 可直接操作Feature Flag
  • SharePoint认证绕过漏洞CVE-2026-55040正被积极利用
  • AI生成的幂等层靠谱吗?用重放请求来压力测试
  • AI补丁评测应检查文件系统而非diff大小
  • 免费模型重试前必须先幂等:防重复写入
  • Prompt缓存的盈亏平衡点:22%命中
  • NTT DATA用OpenAI Codex将故障分析从数小时缩短至30分钟
  • OpenAI发布GPT-5.6,主打性价比优于前代
  • SharePoint JWT认证绕过漏洞CVE-2026-55040爆发
  • TraceMotive v0.3:AI Agent 执行轨迹的结构化比对调试工具
  • OpenAI裁撤安全风险评估团队,安全工作分散至其他组
  • 让 AI Agent 发邮件前必须人工审批的工程实现
  • Cursor 修复命令注入漏洞后仍可被绕过(CWE-78)
  • LLM调用生产API的工程教训:别做快乐演示
  • 已加载 51 / 9294
8.0
热点
AI SCORE
编程提效2026-08-16 19:35

LLM应用CI/CD pipeline完整构建教程

dev.to · AI#LLM#CI/CD#自动化
Editor brief · 编辑速览

详细教程演示用Python脚本+GitHub Actions为LLM应用搭建自动code review流程,含完整代码和系统提示词设计。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

最近我上线了一个自动化代码审查 Agent,运行在 CI 流水线内部。它读取 Git diff,在人类审阅者打开 Pull Request 之前标记潜在的 Bug、缺失的测试和代码风格问题。在本教程中,我将分享我使用的完整 Python 脚本和 GitHub Actions 工作流,基于 Oxlo.ai 推理驱动。

前提条件:

  • 一个来自 https://portal.oxlo.ai 的 Oxlo.ai API Key
  • 至少有过一次提交记录的 Git 仓库
  • OpenAI SDK:pip install openai
  • 如需运行最终的 CI 步骤,还需要一个 GitHub 仓库

Step 1: 搭建审查脚本脚手架

我们从一个简单的 Python 文件开始,加载 Oxlo.ai 客户端并通过 stdin 接收 diff。这样做可以让 Agent 无状态,便于从任意 CI runner 调用。

import os
import sys
from openai import OpenAI

client = OpenAI(
    base_url="https://api.oxlo.ai/v1",
    api_key=os.environ["OXLO_API_KEY"]
)

def get_diff():
    return sys.stdin.read()

if __name__ == "__main__":
    diff = get_diff()
    if not diff.strip():
        print("No diff provided.")
        sys.exit(0)

Step 2: 编写 System Prompt

System Prompt 是 Agent 唯一需要的配置。我将它放在一个独立变量中,这样可以在不触碰逻辑的情况下调整它。

SYSTEM_PROMPT = """You are a senior staff engineer performing code review.
Review the provided git diff and output a JSON object with exactly two keys:
- "issues": a list of objects, each with "severity" (critical, warning, or note), "file", "line", and "message".
- "summary": a one-sentence overview of the change.

Be concise. Only flag real problems: logic errors, missing error handling, security risks, or unclear naming. Do not comment on formatting unless it hurts readability."""

Step 3: 调用 Oxlo.ai 并使用 JSON 模式

我使用 Llama 3.3 70B,因为它能可靠地遵循结构化指令,且在 Oxlo.ai 上运行无冷启动问题。我们启用 JSON 模式并解析响应,以便 CI runner 能够对其进行处理。

import json

def review_diff(diff_text: str):
    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": f"Review this diff:\n\n{diff_text}"},
        ],
        response_format={"type": "json_object"},
        temperature=0.2,
    )
    raw = response.choices[0].message.content
    return json.loads(raw)

if __name__ == "__main__":
    diff = get_diff()
    result = review_diff(diff)
    print(json.dumps(result, indent=2))

Step 4: 添加对 CI 友好的退出码

流水线步骤需要通过或失败。我统计 critical 级别的问题数量,当发现任何 critical 问题时返回非零退出码,这将阻止合并,直到人类手动覆盖。

def report_and_exit(result: dict):
    issues = result.get("issues", [])
    critical_count = sum(1 for i in issues if i.get("severity") == "critical")

    for issue in issues:
        icon = {"critical": "❌", "warning": "⚠️", "note": "ℹ️"}.get(issue["severity"], "•")
        print(f"{icon} [{issue['severity'].upper()}] {issue['file']}:{issue.get('line', '?')} - {issue['message']}")

    print(f"\nSummary: {result.get('summary', 'No summary provided.')}")
    print(f"Found {critical_count} critical issue(s).")

    if critical_count > 0:
        sys.exit(1)
    sys.exit(0)

if __name__ == "__main__":
    diff = get_diff()
    result = review_diff(diff)
    report_and_exit(result)

Step 5: 容器化以确保 CI 运行可复现

CI runner 不应依赖宿主机的 Python 环境。一个极简的 Dockerfile 允许我们固定 OpenAI SDK 版本,并在本地和云端运行相同的镜像。

FROM python:3.11-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY review.py .
ENTRYPOINT ["python", "review.py"]

在同目录下保存以下 requirements 文件。

openai>=1.0

在推送之前先在本地构建和测试。

docker build -t llm-review-agent .
git diff HEAD~1 | docker run --rm -e OXLO_API_KEY=$OXLO_API_KEY -i llm-review-agent

Step 6: 接入 GitHub Actions 工作流

最后一步是一个工作流,它在 Pull Request 触发时运行,将 diff 发送给 Oxlo.ai 驱动的 Agent,并将结果以内联方式发布。由于 Oxlo.ai 采用按请求计费的扁平定价策略,审查大尺寸 diff 的成本是可预测的,这在每次 push 都会触发流水线的场景下尤为重要。

name: LLM Code Review

on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Build review agent
        run: docker build -t llm-review-agent .

      - name: Run Oxlo.ai review on PR diff
        env:
          OXLO_API_KEY: ${{ secrets.OXLO_API_KEY }}
        run: |
          git diff origin/${{ github.base_ref }}...HEAD | \
            docker run --rm -e OXLO_API_KEY -i llm-review-agent

以下是整合了上述所有步骤的完整 review.py。导出你的 Oxlo.ai Key,然后将任意 git diff 管道给它。

import os
import sys
import json
from openai import OpenAI

client = OpenAI(
    base_url="https://api.oxlo.ai/v1",
    api_key=os.environ["OXLO_API_KEY"]
)

SYSTEM_PROMPT = """You are a senior staff engineer performing code review.
Review the provided git diff and output a JSON object with exactly two keys:
- "issues": a list of objects, each with "severity" (critical, warning, or note), "file", "line", and "message".
- "summary": a one-sentence overview of the change.

Be concise. Only flag real problems: logic errors, missing error handling, security risks, or unclear naming. Do not comment on formatting unless it hurts readability."""

def get_diff():
    return sys.stdin.read()

def review_diff(diff_text: str):
    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": f"Review this diff:\n\n{diff_text}"},
        ],
        response_format={"type": "json_object"},
        temperature=0.2,
    )
    raw = response.choices[0].message.content
    return json.loads(raw)

def report_and_exit(result: dict):
    issues = result.get("issues", [])
    critical_count = sum(1 for i in issues if i.get("severity") == "critical")

    for issue in issues:
        icon = {"critical": "❌", "warning": "⚠️", "note": "ℹ️"}.get(issue["severity"], "•")
        print(f"{icon} [{issue['severity'].upper()}] {issue['file']}:{issue.get('line', '?')} - {issue['message']}")

    print(f"\nSummary: {result.get('summary', 'No summary provided.')}")
    print(f"Found {critical_count} critical issue(s).")

    if critical_count > 0:
        sys.exit(1)
    sys.exit(0)

if __name__ == "__main__":
    diff = get_diff()
    if not diff.strip():
        print("No diff provided.")
        sys.exit(0)
    result = review_diff(diff)
    report_and_exit(result)

针对最近一次提交进行测试。

export OXLO_API_KEY="sk-oxlo.ai-..."
git diff HEAD~1 | python review.py

一次真实审查的示例输出。

⚠️ [WARNING] auth.py:42 - Hardcoded timeout may cause flaky tests under high load.
ℹ️ [NOTE] auth.py:55 - Consider renaming `do_thing` to `validate_token`.

Summary: Adds bearer token validation to the auth middleware but introduces a hardcoded timeout.
Found 0 critical issue(s).

你可以通过将大尺寸 diff 拆分成文件块并并行调用 Oxlo.ai 来扩展这个 Agent。扁平化的按请求计费意味着同时向十个文件发起的请求成本与向一个文件发起的请求相同,这保证了流水线的经济性。另一个不错的后续步骤是将结果以 commit SHA 为 key 缓存到 Redis 中,这样相同 diff 的重复运行就不会消耗请求额度。

Original source

本文由 AI 翻译整理自 dev.to · AI,原文版权归原作者所有。

阅读英文原文
上一篇
Anthropic 披露生物武器过滤器失效近一年安全漏洞
下一篇
研究:禁止 AI 自述有意识,会改变它对动物权利和宗教的立场