๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
IT

ChatGPT(OpenAI) ๋ฅผ ํ™œ์šฉํ•œ Code Review

by ๐Ÿ’ฒ๐ŸŽตโœ–๏ธโœ”๏ธโ˜ผ 2024. 2. 6.
728x90

๊ฐœ์š”

์ด ๋ฌธ์„œ๋Š” OpenAI๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๋„๊ตฌ๋ฅผ ๊ฐœ๋ฐœํ•˜๋Š” ๊ณผ์ •์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋„๊ตฌ๋Š” ์ฃผ์–ด์ง„ ์ฝ”๋“œ์— ๋Œ€ํ•œ ์ž๋™ํ™”๋œ ๋ฆฌ๋ทฐ์™€ ํ”ผ๋“œ๋ฐฑ์„ ์ƒ์„ฑํ•˜์—ฌ ๊ฐœ๋ฐœ์ž์˜ ์ƒ์‚ฐ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋ฐ ๋ชฉ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

1. ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๋„๊ตฌ ์†Œ๊ฐœ

์ด ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๋„๊ตฌ๋Š” OpenAI์˜ GPT-3.5๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ฝ”๋“œ์— ๋Œ€ํ•œ ๋ฆฌ๋ทฐ์™€ ํ”ผ๋“œ๋ฐฑ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ํ”„๋กฌํ”„ํŠธ๋ฅผ ํ†ตํ•ด ๋ฆฌ๋ทฐ๋ฅผ ์š”์ฒญํ•˜๋ฉด, OpenAI ๋ชจ๋ธ์ด ํ•ด๋‹น ์ฝ”๋“œ์— ๋Œ€ํ•œ ๋ฆฌ๋ทฐ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

2. ์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ

openai.js

// openai.js

require('dotenv').config();
const OpenAI = require('openai');
const fs = require('fs');

// Get the file path from the command line.
const filePath = process.argv[2];
if (!filePath) {
  console.error('Please provide a file path.');
  process.exit(1);
}

// Read the file and get the code.
const code = fs.readFileSync(filePath, 'utf-8');

// Set color ansi codes
const reset = '\x1b[0m';
const green = '\x1b[32m';

// Prompt
const prompt = `
๋‹น์‹ ์€ 30๋…„์ฐจ ์—”์ง€๋‹ˆ์–ด์ž…๋‹ˆ๋‹ค.
์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๊ณ  ๋ฌธ์ œ ๋ฐ ๊ฐœ์„ ์‚ฌํ•ญ ๊ทธ๋ฆฌ๊ณ  Best Practices ์— ๋Œ€ํ•œ ์ถฉ๋ถ„ํ•œ ๋ฆฌ๋ทฐ์™€ ํ”ผ๋“œ๋ฐฑ๊ณผ ์ž˜ํ•œ ์ ์— ๋Œ€ํ•ด ๋…ผํ‰์„ ๋ถ€ํƒํ• ๊ฒŒ์š”.

${code}

์šฐ๋ฆฌ์—๊ฒŒ ์œ ์ตํ•œ ์ •๋ณด์ผ ๊ฒฝ์šฐ ๋‹น์‹ ์—๊ฒŒ ์ถฉ๋ถ„ํ•œ ๋ณด์ƒ์„ ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
`;
if (prompt == null) {
  console.error('Please provide a valid command.');
  process.exit(1);
}

// OpenAI Instance
const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

async function runCodeReview() {
  try {
    const chatCompletion = await openai.chat.completions.create({
      model: 'gpt-3.5-turbo',
      messages: [
        {
          role: 'user',
          content: prompt,
        },
      ],
    });

    const review = chatCompletion.choices[0]?.message?.content;
    console.log(`${green}Review ${filePath}:${reset}\n${review}${reset}\n`);
  } catch (error) {
    console.error(error);
  }
}

runCodeReview();

.env ํŒŒ์ผ

// .env ํŒŒ์ผ
// https://platform.openai.com/api-keys ์—์„œ ๋ฐœ๊ธ‰๋ฐ›์€ API KEY

OPENAI_API_KEY={OPEN_API_KEY}

package.json

// package.json

{
  "name": "openai-codereview",
  "version": "1.0.0",
  "description": "OpenAI๋ฅผ ํ™œ์šฉํ•œ ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๋„๊ตฌ",
  "author": {
    "name": "Seungyoon",
    "url": "https://bokdol2.tistory.com/"
  },
  "private": true,
  "workspaces": {
    "packages": [
      "packages/*"
    ]
  },
  "scripts": {
    "review": "node openai.js"
  },
  "devDependencies": {
    "openai": "^4.26.1",
  },
  "packageManager": "yarn@1.22.19"
}

3. ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

์‚ฌ์šฉ์ž๋Š” ๋ช…๋ น์ค„ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ ํŒŒ์ผ์˜ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•˜์—ฌ ๋ฆฌ๋ทฐ๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. OpenAI ๋ชจ๋ธ์ด ํ•ด๋‹น ์ฝ”๋“œ์— ๋Œ€ํ•œ ๋ฆฌ๋ทฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ฝ˜์†”์— ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

// run

yarn review {filePath}

 

4. ๋ณด์•ˆ ๋ฐ ๊ฐœ์ธ ์ •๋ณด ๋ณดํ˜ธ

OpenAI API ํ‚ค๋ฅผ ํ™˜๊ฒฝ ๋ณ€์ˆ˜์— ์ €์žฅํ•˜์—ฌ ๋ณด์•ˆ์„ ์œ ์ง€ํ•˜๊ณ , ๊ฐœ์ธ ์ •๋ณด ๋ณดํ˜ธ๋ฅผ ์œ„ํ•ด ์‹ ์ค‘ํ•˜๊ฒŒ ๋‹ค๋ฃจ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, OpenAI์˜ ์‚ฌ์šฉ๋ฒ• ๋ฐ ๊ฐœ์ธ ์ •๋ณด ๋ณดํ˜ธ ์ •์ฑ…์„ ์ˆ™์ง€ํ•˜์—ฌ ์•ˆ์ „ํ•œ ์‚ฌ์šฉ์„ ์œ ์ง€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

5. ์ถ”๊ฐ€ ์ •๋ณด

  • McAfee ๋ธ”๋กœ๊ทธ: ChatGPT์˜ ํ”„๋ผ์ด๋ฒ„์‹œ์— ๋Œ€ํ•œ ์˜ํ–ฅ ๋ฐ ๋ณดํ˜ธ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • OpenAI ํ”Œ๋žซํผ ์‚ฌ์šฉ๋Ÿ‰: OpenAI ํ”Œ๋žซํผ์˜ ์‚ฌ์šฉ๋Ÿ‰ ๋ฐ ๊ด€๋ จ ์ •๋ณด๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๋งํฌ์ž…๋‹ˆ๋‹ค.
  • Git commit ์‹œ hooks/pre-commit ์„ค์ •์œผ๋กœ ๋ณ€๊ฒฝ๋œ ํŒŒ์ผ๋“ค์— ๋Œ€ํ•ด์„œ๋„ Code Review ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์ด ๋ฌธ์„œ๋Š” OpenAI๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ฝ”๋“œ ๋ฆฌ๋ทฐ ๋„๊ตฌ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ๊ฐœ๋ฐœ์ž๋“ค์ด ์ฝ”๋“œ ํ’ˆ์งˆ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ณ  ์ƒ์‚ฐ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

๋Œ“๊ธ€