본문으로 건너뛰기

© 2026 Molayo

GitHub요약2026. 06. 01. 02:15

symflower/eval-dev-quality

요약

LLM의 코드 생성 품질을 평가하기 위한 벤치마크 프레임워크인 DevQualityEval을 소개합니다. Claude 3.7 Sonnet, OpenAI o1 등 주요 모델의 코드 생성 성능을 비교 분석하며, 개발자가 모델의 실질적인 유용성을 검증할 수 있는 지표를 제공합니다.

핵심 포인트

  • LLM 코드 생성 품질 측정을 위한 표준화된 벤치마크 제공
  • Claude 3.7 Sonnet이 코드 생성 분야에서 우수한 성능 기록
  • Docker를 활용한 격리된 샌드박스 환경에서의 실행 권장
  • OpenRouter를 통한 간편한 LLM 프로바이더 연결 지원

LLM(대규모 언어 모델)의 코드 생성 품질을 비교하고 발전시키기 위한 평가 벤치마크(Benchmark) 📈 및 프레임워크입니다.

이 저장소는 LLM(및 기타 코드 생성 도구) 개발자에게 소프트웨어 개발 영역에서의 실제 사용성을 개선할 수 있는 표준화된 벤치마크와 프레임워크를 제공하며, LLM 사용자에게는 특정 LLM이 자신의 작업에 유용한지 확인할 수 있는 지표(Metrics)와 비교 데이터를 제공합니다.

최신 결과는 심층 분석(Deep dive)에서 다룹니다: Anthropic의 Claude 3.7 Sonnet이 코드 생성의 새로운 왕 👑입니다 (단, 도움을 받았을 때만 해당), 그리고 DeepSeek R1은 실망스러운 결과를 보였습니다 (DevQualityEval v1.0 심층 분석).

💰🍻 이 구매를 통해 귀하는 주로 DevQualityEval을 지원하게 되며, 귀하의 Google 계정을 통해 DevQualityEval v1.0의 상세 결과에 대한 접근 권한을 받게 됩니다. 여기에는 다음이 포함됩니다: 리더보드(Leaderboard) 요약, 그래프 및 내보낸 지표(Metrics)가 포함된 Google Sheet 문서에 대한 접근 권한.

모든 심층 분석은 서로를 기반으로 구축되므로, 이전 분석들을 살펴보는 것도 가치가 있습니다:

  • OpenAI의 o1-preview는 코드 생성의 왕 👑이지만 매우 느리고 비용이 많이 듭니다 (DevQualityEval v0.6 심층 분석)
  • DeepSeek v2 Coder와 Claude 3.5 Sonnet은 코드 생성 시 GPT-4o보다 비용 효율적입니다! (DevQualityEval v0.5.0 심층 분석)
  • 테스트 생성에 있어 Llama-3가 GPT-4보다 나은가? 그리고 DevQualityEval v0.4.0의 기타 심층 분석
  • LLM이 아무것도 하지 않는 Go 함수를 테스트할 수 있을까?

Git을 설치하고, Go를 설치한 다음, 다음 명령어를 실행하십시오:

git clone https://github.com/symflower/eval-dev-quality.git
cd eval-dev-quality
go install -v github.com/symflower/eval-dev-quality/cmd/eval-dev-quality

이제 eval-dev-quality 바이너리를 사용하여 벤치마크를 실행할 수 있습니다.

참고: 이 프로젝트는 기본적으로 LLM이 생성한 코드를 샌드박스(Sandbox)에서 실행하지 않습니다. 반드시 --runtime docker를 사용하는 것과 같이 격리된 환경 내에서만 벤치마크를 실행하고 있는지 확인하십시오.

가장 사용하기 쉬운 LLM 프로바이더 (provider)는 openrouter.ai입니다. 액세스 키 (access key)를 생성하고 이를 환경 변수 (environment variable)에 저장해야 합니다:

export PROVIDER_TOKEN=openrouter:${your-key}

그 다음, 모든 모델 (models)과 리포지토리 (repositories)에 대해 모든 벤치마크 (benchmark) 작업을 실행할 수 있습니다:

eval-dev-quality evaluate

명령어의 출력 결과는 모델에 대한 모든 요청 (requests)과 응답 (responses), 그리고 실행된 모든 명령어에 대한 상세한 로그 (log)입니다. 실행이 완료되면 최종 결과가 evaluation.csv 파일에 저장된 것을 확인할 수 있습니다.

옵션 (options)에 대해서는 eval-dev-quality --help 및 특히 eval-dev-quality evaluate --help를 참조하십시오.

하나 이상의 모델만 평가하고 싶은 경우에는 --model 옵션을 사용하여 사용하려는 모델을 정의할 수 있습니다. 이 옵션은 원하는 만큼 여러 모델과 함께 사용할 수 있습니다.

다음 출력을 실행하면:

eval-dev-quality evaluate --model=openrouter/meta-llama/llama-3-70b-instruct

이와 유사한 평가 로그 (evaluation log)가 반환되어야 합니다:

위 명령어에 대한 로그.

2024/05/02 10:01:58 Writing results to evaluation-2024-05-02-10:01:58
2024/05/02 10:01:58 Checking that models and languages can be used for evaluation
2024/05/02 10:01:58 Evaluating model "openrouter/meta-llama/llama-3-70b-instruct" using language "golang" and repository "golang/plain"
...
```golang
package plain
func plain() {
return // This does not do anything but it gives us a line to cover.
}

2024/05/02 10:02:00 Model "openrouter/meta-llama/llama-3-70b-instruct" responded with:

package plain
import "testing"
func TestPlain(t *testing.T) {
plain()
}

2024/05/02 10:02:00 $ symflower test --language golang --workspace /tmp/eval-dev-quality2330727502/plain
Checking for updates
There is a new version of symflower available! Please run symflower update.
...


패키지 com.eval;
클래스 Plain {
static void plain() {
}
}

2024/05/02 10:02:02 Model "openrouter/meta-llama/llama-3-70b-instruct" responded with:

package com.eval;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class PlainTest {
@Test
void testPlain() {
Plain.plain();
// Since the method is empty, we can only assert that it doesn't throw an exception
true;
}
}

2024/05/02 10:02:02 $ symflower test --language java --workspace /tmp/eval-dev-quality1094965069/plain
Total coverage 100.000000%
2024/05/02 10:02:09 Evaluated model "openrouter/meta-llama/llama-3-70b-instruct" using language "java" and repository "java/plain": encountered 0 problems: []
...


기본적으로 실행하면 추가적인 평가 결과와 개별 결과 파일에 대한 링크가 포함된 `REPORT.md` 보고서 파일을 생성합니다.

다음 매개변수들은 컨테이너화된 런타임을 사용할 때 특별한 동작을 합니다.

`--configuration`
: Docker 런타임에 설정 파일을 전달하는 것은 현재 지원되지 않습니다.`--testdata`
: 호스트 시스템에서 경로 존재 여부를 확인하는 것은 무시되지만, 호스트와 컨테이너 내부의 경로가 다를 수 있으므로 컨테이너 내부에서는 여전히 강제됩니다.

시스템에 docker가 설치되어 있는지 확인하십시오.

`docker build . -t eval-dev-quality:dev`

`docker pull ghcr.io/symflower/eval-dev-quality:main`

다음 명령어는 모델 `symflower/symbolic-execution`을 실행하고 그 결과를 로컬 디렉토리 `evaluation`에 저장합니다.

`eval-dev-quality evaluate --runtime docker --runtime-image eval-dev-quality:dev --model symflower/symbolic-execution`

`--runtime-image` 매개변수를 생략하면 기본적으로 `main` 브랜치의 이미지인 `ghcr.io/symflower/eval-dev-quality:main`을 사용합니다.

`eval-dev-quality evaluate --runtime docker --model symflower/symbolic-execution

Kubernetes 문서를 확인해 주세요.

현재 다음과 같은 제공자(Providers, 모델 추론용)를 지원합니다:

- OpenRouter
  - API 키 등록 방법:
    `--tokens=openrouter:${key}`
  - 또는 환경 변수 사용: `PROVIDER_TOKEN=openrouter:${key}`
  - `openrouter` 접두사(prefix)를 통해 모델 선택, 예: `--model openrouter/meta-llama/llama-3.1-8b-instruct`

- Ollama
  - API 키 등록 방법:
  - 평가는 기본 Ollama 포트(`11434`)를 리스닝(listening)하거나, 경로(path)에 `ollama` 바이너리가 있는 경우 Ollama 서버를 시작하려고 시도합니다.
  - `ollama` 접두사를 통해 모델 선택, 예: `--model ollama/llama3.1:8b`
  - 평가는 기본 Ollama 포트를 리스닝합니다.

- OpenAI API
  - OpenAI 채팅 완성 API(chat completion API)를 준수하는 모든 추론 엔드포인트(inference endpoint)를 사용할 수 있습니다.
  - `--urls=custom-${name}:${endpoint-url}`를 사용하여 엔드포인트를 등록하거나( `custom-` 접두사에 유의하세요), 환경 변수 `PROVIDER_URL`을 사용하세요.
  - API 키를 동일한 `custom-${name}`에 등록해야 합니다.
  - `custom-${name}` 접두사를 통해 모델을 선택합니다. fireworks.ai의 예시:
    `eval-dev-quality evaluate --urls=custom-fw:https://api.fireworks.ai/inference/v1 --tokens=custom-fw:${your-api-token} --model custom-fw/accounts/fireworks/models/llama-v3p1-8b-instruct`

`DevQualityEval`을 통해 우리는 다음 질문에 답합니다:

- 어떤 LLM(Large Language Models)이 소프트웨어 개발 작업을 해결할 수 있는가?
- 그들의 결과물 품질은 얼마나 좋은가?

프로그래밍은 결코 간단하지 않은 직업입니다. 빈 함수에 대한 테스트를 작성하는 것조차 사용된 프로그래밍 언어와 그 관례(conventions)에 대한 상당한 지식을 요구합니다. 우리는 이미 첫 번째 `DevQualityEval` 보고서에서 이 과제와 얼마나 많은 LLM이 실패했는지 조사했습니다. 이는 **소프트웨어 개발 작업 해결에 대한 AI 성능을 평가하기 위한 벤치마킹 프레임워크(benchmarking framework)**의 필요성을 강조합니다.

`DevQualityEval`에서 평가된 모델들은

하나의 프로그래밍 언어가 아니라, 여러 프로그래밍 언어에서 프로그래밍 작업 (programming tasks)을 해결해야 합니다.
모든 작업은 모델이 완료해야 하는 잘 정의된 추상적 도전 과제입니다 (예를 들어: 주어진 함수에 대한 단위 테스트 (unit test) 작성).
주어진 작업에 대해 모델이 해결해야 하는 실제 현실 세계의 사례를 나타내는 여러 구체적인 케이스 (또는 후보군, candidates)가 존재합니다 (예: 함수 `abc() {...` 에 대해 단위 테스트 작성).

작업-케이스 (task-case)를 완료하면 결과의 품질에 따라 점수가 부여됩니다. 이는 물론 어떤 기준이 작업의 솔루션을 "좋은" 솔루션으로 만드는지에 따라 달라지지만, 일반적인 규칙은 점수가 높을수록 더 좋다는 것입니다. 예를 들어, 모델이 생성한 단위 테스트가 실제로 컴파일 (compiling)된다면, 컴파일되지 않는 코드만 생성하는 다른 모델들과 차별화되는 점수를 얻을 수 있습니다.

각 리포지토리 (repository)는 루트 디렉토리에 해당 리포지토리에서 실행되어야 할 작업 목록을 지정하는 `repository.json` 설정 파일을 포함할 수 있습니다.

{
"tasks": ["write-tests"]
}


리포지토리 평가 시에는 지정된 작업만 실행됩니다. 만약 `repository.json` 파일이 존재하지 않으면 모든 작업이 실행됩니다.

작업에 따라 리포지토리의 일부를 명시적 평가에서 제외하는 것이 유익할 수 있습니다. 구체적인 예를 들면: Spring 컨트롤러 테스트 (Spring controller tests)는 단독으로 실행될 수 없으며 지원하는 `Application` 클래스가 필요합니다. 하지만 그러한 파일 자체를 모델에게 테스트를 위한 프롬프트 (prompt)로 사용해서는 안 됩니다. 따라서 `repository.json` 설정을 통해 이를 제외할 수 있습니다:

{
"tasks": ["write-tests"],
"ignore": ["src/main/java/com/example/Application.java"]
...


이 `ignore` 설정은 현재 생성 작업인 `write-tests`에만 적용 가능합니다.

`repository.json`을 통해 일부 모델 프롬프트 파라미터 (model prompt parameters)를 구성할 수 있습니다:

{
"tasks": ["write-tests"],
"prompt": {
...


이 `prompt.test-framework` 설정은 현재 테스트 생성 작업인 `write-tests`에만 적용 가능합니다.

작업 결과가 검증될 때, 일부 저장소(repository)는 커스텀 로직을 필요로 할 수 있습니다. 예를 들어: Spring Boot 프로젝트를 위한 테스트를 생성할 때는 테스트가 실제 Spring 컨텍스트를 사용했는지(즉, 테스트가 실행될 때 Spring Boot가 초기화되었는지)를 확인해야 합니다. 따라서 `repository.json`은 다음과 같은 기본적인 커스텀 검증(custom validation) 추가를 지원합니다:

{
"tasks": ["write-tests"],
"validation": {
...


이 `validation.execution.stdout` 설정은 현재 테스트 생성 작업인 `write-tests`에만 적용 가능합니다.

테스트 생성(Test generation)은 주어진 소스 코드 예제에 대한 테스트 스위트(test suite)를 생성하는 작업입니다.

테스트 생성의 훌륭한 점은 결과가 올바른지 자동으로 확인하기 쉽다는 것입니다. 결과물은 컴파일되어야 하며 100% 커버리지(coverage)를 제공해야 합니다. 모델은 소스 코드를 이해해야만 이러한 테스트를 작성할 수 있으므로, 우리는 암묵적으로 LLM(Large Language Model)의 언어 이해 능력을 평가하고 있는 것입니다.

높은 수준(high level)에서 보면, `DevQualityEval`은 모델에게 예제 케이스에 대한 테스트를 생성하도록 요청하고, 응답을 파일로 저장한 뒤, 생성된 테스트를 원본 소스 코드와 함께 실행하려고 시도합니다.

현재 이 작업에 대해 다음과 같은 케이스를 사용할 수 있습니다:

- Java
- Go
- Ruby

코드 수정(Code repair)은 컴파일 에러가 있는 소스 코드를 수정하는 작업입니다.

이 작업을 위해 우리는 컴파일 에러가 포함된 소스 코드 예제들을 포함하는 `mistakes` 저장소를 도입했습니다. 각 예제는 유효한 테스트 스위트와 함께 각각의 패키지에 격리되어 있습니다. 우리는 `mistakes` 저장소의 각 패키지를 컴파일하고, LLM에게 소스 코드와 컴파일 에러 목록을 모두 제공합니다. 그 후 LLM의 응답을 미리 정의된 테스트 스위트로 검증합니다.

현재 이 작업에 대해 다음과 같은 케이스를 사용할 수 있습니다:

- Java
- Go
- Ruby

트랜스파일(Transpile)은 소스 코드를 한 언어에서 다른 언어로 변환하는 작업입니다.

이 작업을 위한 테스트 데이터 저장소는 여러 패키지로 구성됩니다. 각 패키지의 루트에는 `implementation`이라는 이름의 폴더가 반드시 있어야 합니다.

**구현 파일 (implementation files)** (원본 언어당 하나씩)을 포함하며, 이 파일들은 트랜스파일 (transpiled) 대상이 됩니다. 각 패키지는 또한 스텁 (stub, LLM이 코드를 생성해야 할 함수의 시그니처를 알 수 있도록 하는 함수 시그니처)이 포함된 소스 파일과 유효한 테스트 스위트 (test suite)를 반드시 포함해야 합니다. 그 후 LLM의 응답은 미리 정의된 테스트 스위트로 검증됩니다.

현재 이 작업에는 다음 케이스들을 사용할 수 있습니다:

- Java
- Go
- Ruby

현재 다음과 같은 항목들에 대해 점수가 부여됩니다:

`response-no-error` : `+1` (응답 과정에서 에러가 발생하지 않은 경우)

`response-not-empty` : `+1` (응답이 비어 있지 않은 경우)

`response-with-code` : `+1` (응답에 소스 코드가 포함된 경우)

`compiled` : `+1` (소스 코드가 컴파일된 경우)

`statement-coverage-reached` : `+10` (실행된 코드의 각 커버리지 객체당 부여. 단, `transpile` 및 `code-repair` 작업에서는 비활성화되어 있습니다. 모델이 구현 코드를 직접 작성하므로, 더 높은 점수를 받기 위해 임의의 문장을 추가할 수 있기 때문입니다)

`no-excess` : `+1` (응답이 요청된 것보다 더 많은 내용을 포함하지 않은 경우)

`passing-tests` : `+10`

AI 자동 생성 콘텐츠

본 콘텐츠는 GitHub Codex tools의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0