ChatGPT에서 JSON 출력하기

ChatGPT에서의 프롬프트 엔지니어링

ChatGPT에서 원하는 출력을 얻기 위해서는 시행착오가 필요합니다. 원하는 출력을 얻는 프롬프트를 찾아내는 과정을 프롬프트 엔지니어링이라고 하죠. 문자열을 해석해서 컴퓨터에서 작업하기 좋도록 json 형식으로 만들고 싶습니다. 그래서 ChatGPT에게 다음과 같이 요청했습니다. One-shot learning을 위한 예시도 넣었죠.

문자열에서 정보를 추출해서 json으로 바꿔줘.

## 예시
“수연이는 파란색을 좋아하고, 철호는 빨간색을 좋아한다” => {“수연”: “blue”,”철호”: “red”}

## 입력
“영희는 노란색을 좋아하고, 민수는 초록색을 좋아한다” =>

그랬더니 직접 json을 만들어주는 대신 json으로 변환하는 코드를 만들어 줬습니다.(결과는 물어볼 때마다 달라질 수 있습니다.)

입력된 문자열에서 정보를 추출하고 JSON 형식으로 바꾸려면 Python 프로그래밍 언어를 사용하여 다음과 같이 할 수 있습니다.

import re
import json

# 입력 문자열
input_string = "영희는 노란색을 좋아하고, 민수는 초록색을 좋아한다"

# 이름과 색상 정보 추출
name_color_pattern = r'(\w+)는\s(\w+)색을\s좋아한다'
matches = re.findall(name_color_pattern, input_string)

# 결과를 JSON 형식으로 변환
result = {name: color for name, color in matches}

# JSON 문자열로 변환
json_result = json.dumps(result, ensure_ascii=False)

print(json_result)


위 코드는 입력된 문자열에서 이름과 색상 정보를 추출하고 이를 JSON 형식으로 변환합니다. 코드를 실행하면 원하는 결과가 출력됩니다.

그러나 이 코드는 예시에서 보여준 것처럼 색깔을 영어로 만들지 못하죠. 그래서 “키는 이름, 값은 색깔을 영어로” 만들어 달라고 프롬프트에 추가했는데 앞에서와 비슷한 대답을 했습니다. 이번엔 코드를 작성하지 말고 직접 바꿔달라고 했습니다.

입력 문자열에서 정보를 추출해서 아래와 같이 json으로 바꿔줘. 키는 이름, 값은 색깔을 영어로. 코드를 작성하지 말고 직접 바꿔서 결과를 보여줘.

## 예시
“수연이는 파란색을 좋아하고, 철호는 빨간색을 좋아한다” => {“수연”: “blue”,”철호”: “red”}

## 입력
“영희는 노란색을 좋아하고, 민수는 초록색을 좋아한다” =>

그랬더니 아래와 같이 대답했습니다.

입력 문자열을 파싱하여 아래와 같이 JSON 형식으로 변환합니다.

입력 문자열:
"영희는 노란색을 좋아하고, 민수는 초록색을 좋아한다"

JSON 결과:
{
"영희": "yellow",
"민수": "green"
}

원하는 결과가 마지막에 나오긴 했지만 앞에 불필요한 설명이 들어가 있습니다. 그래서 다시 프롬프트를 수정했습니다.

당신은 json 변환기입니다. 보기처럼 문장을 입력 받으면 json 형식으로 출력하세요. 설명 없이 json만 출력하세요.

## 보기
“수연이는 파란색을 좋아하고, 철호는 빨간색을 좋아한다” => {“수연”: “blue”, “철호”: “red”}

## 문장
“민수는 노란색을 좋아하고, 은정이는 분홍색을 좋아한다”

이제 원하는 답이 나옵니다.

{"민수": "yellow", "은정이": "pink"}

입력 문장을 바꿔가며 실행해봐도 결과가 잘 나옵니다. 몇 번 실행해봤을 때 결과가 잘 나왔으나 항상 잘 나온다는 보장은 없습니다. 응답이 확률적으로 나오므로 언제 부연 설명이 들어가게 될지 알 수 없죠. 앞에 설명이 들어가면 {} 기호를 이용해 json 부분만 추출할 수도 있으나 결과가 항상 json 형식으로 나온다면 더 좋겠죠?

사실 json 출력은 ChatGPT에서 대화할 때 보다는 API를 사용할 때 더 유용합니다. LLM의 응답을 바로 파이썬에서 딕셔너리로 바꿔서 사용할 수 있기 때문이죠. 위의 프롬프트를 가지고 API를 사용할 수도 있지만, 함수 호출 기능을 이용하면 더 확실하게 부연 설명 없는 json 결과물을 얻을 수 있습니다.

API에서 function_call을 이용해 json 출력하기

OpenAI API 호출시 functions 인자를 이용해 함수 사용법을 알려줄 수 있습니다. LLM은 필요하다고 판단될 경우 응답의 function_call을 통해 호출할 함수 이름과 호출할 때 사용할 인자(arguments)를 알려줍니다. 이 때 인자를 json object 형식(파이썬 딕셔너리에 해당)으로 받아서 출력하면 됩니다. 이를 위해 사용할 functions 인자는 다음과 같습니다.

functions = [
    {
        "name": "name_and_color",
        "description": "사람 이름과 좋아하는 색깔의 영어 이름을 매칭시킴",
        "parameters": {
            "type":"object",
            "properties": {
                "match": {
                    "type": "object",
                    "description": "key=name, value=color"
                }
            },
            "required": ["match"]
        }
    }
]

위에서 함수 이름은 중요하지 않습니다. 실제로는 존재하지 않는 함수입니다. 중요한 것은 함수 설명과 함수 인자 설명입니다. 함수 설명에는 우리의 목적에 대한 설명을 넣어서 LLM에서 호출해야 하는 함수로 판단할 수 있도록 합니다. 인자는 object 형식으로 만들고 인자 설명에 key는 사람 이름, value는 색깔을 넣도록 했습니다.

messages = [{"role": "system", "content": "You are a helpful assistant."},
           {"role": "user", "content": "수연이는 파란색을 좋아하고 철호는 빨간색을 좋아한다."}]
response = openai.ChatCompletion.create(
    model="gpt-3.5-turbo",
    messages=messages,
    functions=functions
)
print(response["choices"][0]['message']["function_call"]["arguments"])

### 결과
{
  "수연": "blue",
  "철호": "red"
}

원하는대로 json 문자열이 결과로 나왔습니다. 문장을 바꿔도 잘 나옵니다. 이제 부연 설명이 나올지 안 나올지 걱정할 필요가 없죠. json.loads 함수를 이용해 파이썬 딕셔너리로 바꿔서 사용하면 이후 과정을 편리하게 진행할 수 있습니다.

댓글 남기기