개발자를 위한 고급 ChatGPT 프롬프트 기술

안녕하세요, 개발자 여러분! 💫

ChatGPT가 등장한 이후 많은 개발자들이 이를 활용하고 있습니다. 이미 수많은 프롬프트 엔지니어링에 대한 튜토리얼이 쏟아지고 있는데요, 이번 글은 그런 일반적인 가이드가 아닙니다.

AI를 일상에서 활용한 개인적인 경험을 공유하려 합니다. AI가 어떻게 저에게 도움을 주고, 왜 매우 유용하다고 생각하는지 설명하겠습니다. 또한, 이 글은 친구 개발자와의 대화에서 영감을 얻었는데요, 그는 AI가 별로 도움이 안 된다고 느꼈지만, 저는 AI를 통해 많은 이점을 얻고 있습니다. 그가 왜 실패했고, 제가 왜 성공했는지도 함께 이야기해 보겠습니다.

AI는 인간이 아닙니다!

무엇보다 먼저 명심할 것이 있습니다. ChatGPT가 때로는 인간처럼 느껴질 수 있지만, AI는 인간이 아닙니다. AI는 생각하지 않으며, 인간이 본질적으로 이해하는 맥락을 인식하지 못합니다. AI의 답변은 단지 데이터를 수학적 공식으로 처리한 결과일 뿐입니다.

다시 한 번 강조하겠습니다:

  • AI는 생각하지 않습니다.
  • AI에게 의식은 없습니다.
  • AI는 단지 예측 가능한 수학적 결과를 생성할 뿐입니다.

이 점을 명확히 이해하는 것이 중요합니다. 이 사실을 깨닫고 나면 많은 프롬프트 엔지니어링 튜토리얼이 더 의미 있게 다가올 것입니다. AI를 도구로 간주하고 다룬다면, 그 도구는 여러분의 손에서 강력한 무기가 될 것입니다.

데이터 모델과 프롬프트 엔지니어링

AI는 복잡한 알고리즘과 방대한 데이터 세트를 기반으로 수학적 공식을 사용하여 답변을 생성합니다. AI가 답변을 생성하는 과정은 인간의 사고와 다르며, 제공하는 변수(입력)가 명확할수록 더 정확한 결과를 얻을 수 있습니다.

이제 많은 프롬프트 엔지니어링 강좌가 왜 중요한지 더 이해가 될 것입니다.
OpenAI 공식 문서에서도 이런 내용을 다루고 있으며, 아래에 중요한 내용을 요약해 보았습니다.

명확한 지침을 작성하세요!

프롬프트 작성 시, 명확하게 지침을 주어야 합니다.

예를 들어, 동료 개발자에게 "for 문을 어떻게 사용하나요?"라고 묻는다면 동료는 어느 정도 관련성 있는 답변을 줄 것입니다. 왜냐하면 동료는 같은 환경에서 작업하고 있으며, 여러분이 Java에 대해 묻고 있다고 짐작할 수 있기 때문입니다.

하지만 동일한 질문을 인터넷 상의 무작위 개발자에게 묻는다면, 그들은 혼란스러울 수 있습니다. 질문에 어떤 언어를 사용하는지, 구체적인 상황이 무엇인지, 데이터를 변환해야 하는지 등 아무것도 알 수 없기 때문입니다.

AI도 마찬가지입니다.
만약 모든 변수(조건)를 명확하게 지정하지 않으면, 예측 불가능한 답변을 받을 가능성이 높습니다.

첫 번째 메시지: AI의 역할 지정

첫 번째 메시지는 AI가 여러분과 상호작용하는 방식을 조정하는 시스템 메시지입니다. AI에게 특정 역할(페르소나)을 부여하면 더 적절한 답변을 얻을 수 있습니다.

페르소나 설정 예시:

1
2
10년 이상의 경력을 가진 전문 Kotlin 개발자로 행동하세요.
당신은 깨끗하고, 유지보수 가능하며, 가독성과 확장성이 뛰어난 코드를 작성하는 전문가입니다.

이 프롬프트는 제가 코딩 질문을 할 때 매우 유용했으며, 답변의 질을 크게 향상시켰습니다.
여러분도 사용해 보세요. 차이를 직접 느낄 수 있을 것입니다.

모든 요구 사항을 명확하게 명시하기

프롬프트에 명확한 지침을 포함하면 더 나은 결과를 얻을 수 있습니다.

예시 프롬프트:

1
2
3
4
5
6
JSON 파일이 주어졌습니다. 각 줄은 다음과 같이 구성됩니다:
- 따옴표로 묶인 매개변수 이름
- 콜론(:) 기호
- 따옴표로 묶인 값(영어로 작성됨)

이 JSON에서 값만 스페인어로 번역해 주세요. 매개변수 이름은 번역하지 마세요. 답변에는 번역된 JSON만 포함되어야 합니다.

이 프롬프트를 사용하면 AI는 매개변수 이름은 그대로 두고, 값만 스페인어로 번역된 JSON 파일을 반환합니다.

코드 리뷰 요청하기

프롬프트 예시:

1
이 코드를 SOLID 원칙, 클린 코드, 유지보수성, 확장성, 가독성 기준에 따라 검토해 주세요.

AI는 이 요청에 따라 각 원칙에 맞게 답변을 구조화하고, 원칙별로 코드를 개선할 수 있는 방법을 제시합니다.

예시 코드와 결과

예를 보여드리겠습니다. 이것은 초기 코드의 일부입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class User {
private String name;
private int age;
private boolean connected = false;

public User(String name, int age) {
this.name = name;
this.age = age;
}

public void connectToDatabase() {
// 연결 설정
this.connected = true;
}

public void saveUserToDatabase() {
if (this.connected) {
System.out.println("Storing " + this.name + " into database...");
} else {
System.out.println("Not connected to database.");
}
}
}

다음은 ChatGPT에게 "이 코드를 검토해 주세요"라고 요청했을 반환된 리팩터링된 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class User {
private String name;
private int age;
private boolean connected = false;

public User(String name, int age) {
this.name = name;
this.age = age;
}

public void connect() {
this.connected = true;
}

public void save() {
if (this.connected) {
System.out.println("Saving " + this.name + "...");
} else {
System.out.println("Connect first.");
}
}
}

ChatGPT에 "이 코드를 SOLID 원칙, 클린 코드, 유지보수성, 확장성, 가독성 기준에 따라 검토해 주세요"라고 요청했을 때 반환된 리펙토링된 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class User {
private String name;
private int age;

public User(String name, int age) {
this.name = name;
this.age = age;
}

// name의 getter 메서드
public String getName() {
return this.name;
}
}

class Database {
private boolean connected = false;

public void connect() {
this.connected = true;
}

public void saveUser(User user) {
if (this.connected) {
System.out.println("Storing " + user.getName() + " into database...");
} else {
System.out.println("Not connected to database. Connect first.");
}
}
}

SOLID 원칙 적용 설명

  • 단일 책임 원칙(Single Responsibility Principle, SRP):
    User 클래스와 Database 클래스를 분리하여 각 클래스가 단일 책임만 가지도록 했습니다.
  • 개방/폐쇄 원칙(Open/Closed Principle):
    기존 코드를 변경하지 않고 새로운 기능을 추가할 수 있도록 구조를 개선했습니다.
  • 리스코프 치환 원칙(Liskov Substitution Principle):
    이 원칙은 더 복잡한 예제에서 설명될 수 있으며, 필요 시 인터페이스나 하위 클래스를 도입하여 적용할 수 있습니다.
  • 인터페이스 분리 원칙(Interface Segregation Principle)과 의존성 역전 원칙(Dependency Inversion Principle):
    더 큰 규모의 프로젝트나 인터페이스, 서브클래스를 사용할 때 설명할 수 있습니다.

이처럼 책임 분리와 메서드 단순화를 통해 코드가 더 깨끗하고 유지보수 가능하며, 확장 가능하고 가독성 높은 구조로 개선되었습니다.

문맥 인식: 한계와 해결 방법

ChatGPT는 고정된 문맥 길이가 있습니다. 즉, 사용자와 AI 간의 대화에서 모든 내용을 한 번에 기억하지 못합니다.

대화가 길어지면 초기에 설정했던 AI의 역할이나 작성했던 코드 일부를 잊어버릴 수 있습니다.

이를 해결하려면 AI에게 작업할 전체 코드를 반복해서 보여주고 맥락을 다시 제공해야 합니다.

ChatGPT가 작동하는 방식 이해하기

ChatGPT는 수학적으로 작동하는 도구이기 때문에 때로는 부정확하거나 누락된 답변을 줄 수 있습니다. 따라서 AI에게 답변의 근거를 설명하도록 요청하면 더 의미 있는 결과를 얻을 수 있습니다.

1
2
이 코드가 왜 맞는지 설명해 주세요.
각 줄에 주석을 달고 어떤 역할을 하는지 설명해 주세요.

프롬프트 테스트와 개선

프롬프트는 한 번에 완벽할 수 없습니다. 원하는 결과를 얻을 때까지 여러 번 테스트하고, 답변이 마음에 들지 않으면 프롬프트를 개선하세요.

프롬프트 개선 예시:

  • AI가 생성한 코드가 테스트 결과와 일치하지 않으면 AI의 코드, 테스트 케이스, 기대 결과, 실제 결과를 다시 보여주고 오류를 수정하도록 요청하세요.
  • 필요하다면 코드를 여러 단계로 나누어 요청하고, 각 단계별로 검토 및 개선하도록 지시하세요.

결론

ChatGPT는 올바르게 다루었을 때 일상적인 코딩 작업에서 매우 강력한 도구가 될 수 있습니다. 하지만 AI의 능력과 한계를 이해하고 적절히 활용해야 합니다.

ChatGPT는 개발자를 도와주고 가르치며 안내할 수 있지만, 인간 개발자를 대체할 수는 없습니다. 개발자의 직관과 예술적인 코딩 감각은 여전히 필수적이며, 우리는 이러한 도구를 잘 조율해 멋진 작품을 만들어야 합니다.

ChatGPT를 동료로 삼아 여러분의 코딩 여정을 더 즐겁고 생산적으로 만드세요.

Share