CI/CD에서 배포 게이트 걸기
CI/CD에서 배포 게이트 걸기 (Gate Deployments in CI/CD)
할당된 거버넌스 폴리시를 충족하지 못하는 배포를 막는 방법을 설명하는 문서예요. 이 문서에서는 deepeval CLI와 공개 API로 배포 게이트를 실행하는 방법, 응답 해석, 그리고 GitHub Actions 워크플로 예시를 다뤄요.
출처: 문서
본문
거버넌스 폴리시를 배포 게이트(deployment gate) 로 사용해서, 프로젝트가 조직의 요구사항을 충족하지 못할 때 릴리스를 막을 수 있어요.
게이트는 프로젝트의 할당된 폴리시의 모든 컨트롤을 평가해요. 여기에는 기본 폴리시에서 상속받은 컨트롤도 포함돼요. Low 중요도보다 높은 모든 컨트롤이 통과하면 게이트도 통과해요.
Low 중요도 컨트롤은 실패하거나, 오류가 나거나, 데이터가 없어도 배포를 막지 않아요.
시작하기 전에
게이트를 실행하기 전에 프로젝트를 거버넌스 폴리시에 할당해 두어야 해요. 프로젝트가 폴리시에 속하지 않으면 assess 엔드포인트가 오류를 반환해요.
배포 게이트 실행
deepeval CLI(Python과 TypeScript 모두 제공)로 CI/CD 파이프라인에서 게이트를 실행하거나, 공개 API를 직접 호출할 수 있어요.
Python
deepeval gate
TypeScript
npx deepeval gate
cURL
요청 (POST /v1/governance/assess) — API 레퍼런스
curl -X POST "https://api.confident-ai.com/v1/governance/assess" \
-H "CONFIDENT_API_KEY: <PROJECT-API-KEY>"
import requests
response = requests.post(
"https://api.confident-ai.com/v1/governance/assess",
headers={
"CONFIDENT_API_KEY": "<PROJECT-API-KEY>",
},
)
print(response.json())
const response = await fetch("https://api.confident-ai.com/v1/governance/assess", {
method: "POST",
headers: {
"CONFIDENT_API_KEY": "<PROJECT-API-KEY>",
},
});
const data = await response.json();
console.log(data);
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
req, err := http.NewRequest("POST", "https://api.confident-ai.com/v1/governance/assess", nil)
if err != nil {
panic(err)
}
req.Header.Set("CONFIDENT_API_KEY", "<PROJECT-API-KEY>")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
out, err := io.ReadAll(res.Body)
if err != nil {
panic(err)
}
fmt.Println(string(out))
}
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.confident-ai.com/v1/governance/assess"))
.header("CONFIDENT_API_KEY", "<PROJECT-API-KEY>")
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let response = reqwest::Client::new()
.post("https://api.confident-ai.com/v1/governance/assess")
.header("CONFIDENT_API_KEY", "<PROJECT-API-KEY>")
.send()
.await?;
println!("{}", response.text().await?);
Ok(())
}
CLI는 폴리시가 통과하면 코드 0으로, 실패하면 0이 아닌 코드로 종료해서, 실패하는 폴리시가 파이프라인을 멈추게 해요.
세 가지 방식 모두 프로젝트의 API 키로 POST /v1/governance/assess 엔드포인트를 호출해요. 응답은 폴리시가 통과했는지, 평가된 폴리시를 식별하고, 모든 컨트롤의 상태를 보고해요:
{
"success": true,
"data": {
"passed": false,
"governancePolicy": {
"id": "GOVERNANCE-POLICY-ID",
"name": "EU AI Act"
},
"governanceControls": [
{
"id": "GOVERNANCE-CONTROL-ID",
"name": "No user data vulnerabilities",
"type": "PRE_DEPLOYMENT_RED_TEAMING",
"severity": "HIGH",
"status": "FAIL"
},
{
"id": "GOVERNANCE-CONTROL-ID",
"name": "Nightly evals pass rate",
"type": "PRE_DEPLOYMENT_EVALS",
"severity": "LOW",
"status": "NO_DATA"
}
]
},
"deprecated": false
}
컨트롤은 status가 PASS가 아니면서 그리고 severity가 LOW가 아닐 때 passed를 false로 만들어요. 위 예시에서 레드팀 컨트롤은 게이트를 실패시키고, Low 중요도 컨트롤은 보고만 되고 무시돼요.
예시: 프로젝트 평가, 레드팀, 게이팅
다음 GitHub Actions 워크플로는 DeepEval과 DeepTeam을 설치하고, 코드 기반 평가를 실행하고, 코드 기반 레드팀을 실행한 뒤 프로젝트의 배포 게이트를 평가해요:
name: Governance deployment gate
on:
pull_request:
push:
branches:
- main
jobs:
governance:
runs-on: ubuntu-latest
env:
CONFIDENT_API_KEY: ${{ secrets.CONFIDENT_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install DeepEval and DeepTeam
run: pip install -U deepeval deepteam
- name: Run code-based evaluations
continue-on-error: true
# test_llm_app.py uses DeepEval to define and run evaluation tests.
run: deepeval test run tests/test_llm_app.py
- name: Run code-based red teaming
continue-on-error: true
# red_team.py uses DeepTeam to define and run a risk assessment.
run: python tests/red_team.py
- name: Run governance deployment gate
run: deepeval gate
tests/test_llm_app.py를 여러분의 DeepEval 테스트 파일로, tests/red_team.py를 DeepTeam의 red_team() 함수를 호출하는 Python 파일로 바꿔 주세요.
GitHub Actions는 잡 안의 스텝을 순차적으로 실행하기 때문에, 배포 게이트는 평가와 레드팀 결과가 업로드된 뒤에 실행돼요. 검증 스텝은 continue-on-error를 사용해서, 두 평가 중 하나가 실패를 보고해도 최종 게이트가 여전히 실행되도록 보장해요. 그러면 게이트가 폴리시의 컨트롤로 최종 배포 결정을 내려요.