함수 호출을 사용하여 구조화된 데이터 추출

Google AI에서 보기 Google Colab에서 실행 GitHub에서 소스 보기

이 튜토리얼에서는 Gemini API를 사용하여 스토리에서 캐릭터, 관계, 사물, 장소의 목록을 추출하는 구조화된 데이터 추출 예시를 살펴봅니다.

설정

pip install -U -q google-generativeai
import pathlib
import textwrap

import google.generativeai as genai


from IPython.display import display
from IPython.display import Markdown

from google.api_core import retry

def to_markdown(text):
  text = text.replace('•', '  *')
  return Markdown(textwrap.indent(text, '> ', predicate=lambda _: True))

API 키를 확보하면 이를 SDK에 전달합니다. 여기에는 두 가지 방법이 있습니다.

  • 키를 GOOGLE_API_KEY 환경 변수에 입력합니다. SDK가 이 환경 변수에서 키를 자동으로 선택합니다.
  • 키를 genai.configure(api_key=...)에 전달
try:
    # Used to securely store your API key
    from google.colab import userdata

    # Or use `os.getenv('API_KEY')` to fetch an environment variable.
    GOOGLE_API_KEY=userdata.get('GOOGLE_API_KEY')
except ImportError:
    import os
    GOOGLE_API_KEY = os.environ['GOOGLE_API_KEY']

genai.configure(api_key=GOOGLE_API_KEY)

예시 태스크

이 튜토리얼에서는 자연어 스토리에서 항목을 추출합니다. 예를 들어 아래는 Gemini가 작성한 사례입니다.

new_story = False

if new_story:
  model = genai.GenerativeModel(model_name='models/gemini-1.5-pro-latest')

  response = model.generate_content("""
      Write a long story about a girl with magic backpack, her family, and at
      least one other charater. Make sure everyone has names. Don't forget to
      describe the contents of the backpack, and where everyone and everything
      starts and ends up.""", request_options={'retry': retry.Retry()})
  story = response.text
  print(response.candidates[0].citation_metadata)
else:
  story = """In the quaint town of Willow Creek, nestled amidst rolling hills and whispering willows, resided a young girl named Anya. As she stepped out of the creaky wooden door of her modest cottage, her heart skipped a beat with excitement and anticipation. Today was her first day of school, and she couldn't wait to show off her prized possession - a magical backpack.\n\nHanded down to her from her grandmother, the backpack was no ordinary satchel. Its soft, emerald-green fabric shimmered with an ethereal glow, and its leather straps held secrets that only Anya knew. Within its capacious interior lay an enchanted world, filled with wonders that would ignite her imagination and change her life forever.\n\nAnya's parents, kind-hearted Elise and wise-bearded Edward, bid her farewell with warm embraces. "Remember, my dear," whispered her mother, "use your magic wisely and for good." Her father added, "Always seek knowledge, and let the backpack be your trusted companion."\n\nWith a skip in her step, Anya set off towards the town's only schoolhouse. On her way, she passed her best friend, Samuel, a curious and adventurous boy with a mischievous grin. "Hey, Anya," he called out. "Can I see your backpack?"\n\nAnya hesitated for a moment before unzipping the flap and revealing its contents. Samuel's eyes widened in amazement as he peered inside. There, nestled amidst pencils and notebooks, were a shimmering sword, a book of ancient spells, a tiny compass that always pointed north, and a magical key that could open any lock.\n\nTogether, they marveled at the backpack's wonders, promising to keep its secrets safe. As they approached the schoolhouse, Anya noticed a group of older children huddled together, their faces etched with fear. Curiosity getting the better of her, she cautiously approached.\n\n"What's wrong?" she asked.\n\nA tall, lanky boy stepped forward. "There's a monster in the forest," he stammered. "It's been terrorizing the town, attacking animals and even people."\n\nAnya's heart sank. The town of Willow Creek was small and peaceful, and the thought of a monster brought a shiver down her spine. She knew she had to do something to protect her family and friends.\n\nWithout a moment's hesitation, Anya opened her backpack and retrieved the shimmering sword. With a determined gleam in her eye, she turned to her terrified peers. "Don't worry," she said, her voice steady. "I'll take care of it."\n\nWith Samuel close behind her, Anya ventured into the shadowy depths of the forest. The trees seemed to whisper secrets as she passed, and the undergrowth rustled with unseen creatures. As they walked deeper into the forest, the air grew heavy and the ground beneath their feet trembled.\n\nSuddenly, they came to a clearing, and there before their eyes was the monster - a massive beast with sharp teeth, glowing red eyes, and claws that could crush a human with ease. The creature roared, a thunderous sound that shook the forest to its core.\n\nFear surged through Anya, but she refused to let it consume her. She drew the sword from its sheath and charged towards the monster. The blade shimmered in the sunlight, and as it struck the beast's hide, a blinding light erupted, enveloping everything in its radiance.\n\nWhen the light faded, the monster was gone, and in its place was a pile of shattered crystals. Anya had defeated the creature with the magic of her backpack, proving that even the smallest of objects could hold the greatest of powers.\n\nAs she and Samuel returned to the town, they were greeted as heroes. The people of Willow Creek rejoiced, and the legend of Anya, the girl with the magic backpack, was passed down through generations. And so, Anya continued her adventures, using the backpack's wonders to make the world a better place, one magical step at a time."""
to_markdown(story)

구불구불한 언덕과 속삭이는 버드나무 사이에 자리한 고풍스러운 윌로 크릭 마을에는 안야라는 어린 소녀가 살았습니다. 소박한 작은 집의 이상한 나무로 덮인 문을 열고 나오자 신나고 기대감이 떨어졌다. 오늘은 개학 첫날인 그녀는 소중한 소중한 소지품을 한껏 자랑스럽게 여기며 마법 같은 배낭을 갖고 있습니다.

할머니로부터 물려받은 배낭은 평범한 가방이 아니었습니다. 부드러운 에메랄드색을 띤 초록색 직물이 초현실적인 빛으로 반짝이고, 가죽 스트랩에는 안야만이 알고 있던 비밀이 담겨 있었습니다. 드넓은 실내에는 마법과도 같은 세계가 펼쳐져 있습니다. 상상력을 자극하고 인생을 영원히 바꿔놓을 기적의 세계로 가득 차 있습니다.

안야의 부모님, 친절한 엘리스, 현명한 수염을 가진 에드워드는 따뜻하게 맞이하며 작별을 고합니다. "기억해, 안녕"이라고 어머니가 속삭였다. "네 마법을 현명하게, 그리고 선을 위해 사용해." 아버지는 "항상 지식을 찾고, 배낭은 믿을 수 있는 동반자가 되어주세요."라고 덧붙였습니다.

안야는 걸음을 건너 뛰고 마을의 유일한 학교로 향했습니다. 가는 길에 그녀는 장난기 가득한 미소를 지으며 호기심이 많고 모험적인 소년인 사무엘을 지나쳤습니다. "Hey, Anya"라고 외쳤습니다. "배낭 보이시나요?"

안야는 잠시 망설이다가 덮개를 열고 내용물을 보여줬습니다. 사무엘은 안을 들여다보는 동안 놀라서 눈이 커졌습니다. 그곳에는 반짝이는 검, 고대 주문서, 항상 북쪽을 향한 작은 나침반, 모든 자물쇠를 열 수 있는 마법의 열쇠가 그 안에 연필과 공책 사이에 자리해 있었다.

그들은 함께 배낭의 경이로움에 감탄하며 백팩의 비밀을 안전하게 지키겠다고 약속했다. 학교에 다가오자 안야는 한 무리의 아이들이 서로 옹기종기 모였고 그들의 얼굴에 두려움이 새겨져 있었습니다. 호기심이 점점 높아지자 조심스럽게 다가갔습니다.

"뭐가 문제인가요?" 그녀가 물었습니다.

키 큰, 뚱뚱한 소년이 앞으로 나갔습니다. "숲에 괴물이 있다"고 말했다. "마을을 공포에 빠뜨리고 동물은 물론 사람까지 공격하고 있습니다."

Anya의 심장이 가라앉았다. 윌로 크릭 마을은 작고 평화로웠습니다. 괴물이 떠오른다는 생각에 몸이 덜덜 떨리곤 했습니다. 그녀는 가족과 친구를 보호하기 위해 무언가를 해야 한다는 것을 알고 있었습니다.

안야는 망설이지 않고 배낭을 열고 반짝이는 검을 되찾았습니다. 맹렬한 눈빛으로 그녀는 겁에 질린 동료들에게 몸을 돌렸다. "걱정하지 마." 목소리는 변함없이 말했다. "내가 다룰게."

Anya는 뒤에서 사무엘을 가까이 둔 채 어둠 속으로 깊은 숲 속으로 모험을 떠났습니다. 메릴이 지나가면서 나무들이 비밀을 속삭이는 것 같았고 덤불은 보이지 않는 생물들로 바스락거리는 것처럼 보였다. 그들이 숲 속으로 깊숙이 들어오자 땅이 떨렸다.

갑자기 숲속의 공터에 와서 눈앞에 괴물이 나타났다. 날카로운 이, 빛이 도는 붉은 눈, 발톱을 가진 거대한 괴물은 인간을 쉽게 부러뜨릴 수 있다. 생명체가 울려 퍼졌고, 우레와 같은 소리는 숲을 마음속까지 흔들어 왔다.

안야를 통해 두려움이 치열했지만, 안야는 그것이 자신을 먹어 치우지 않도록 하기를 거부했습니다. 그녀는 칼집에서 칼을 뽑아 몬스터를 향해 돌렸다. 칼날이 햇빛에 빛나고 사슴의 몸을 덮쳤을 때 눈부신 빛이 뿜어져 나오며 모든 것을 빛나게 덮었다.

빛이 서서히 사라지자 괴물은 사라졌고 그 대신 산산조각난 수정 더미가 되어 있었다. 안야는 배낭의 마법으로 이 생명체를 물리쳤고, 아주 작은 물체도 가장 위대한 힘을 지니고 있음을 증명했습니다.

그녀와 사무엘이 마을로 돌아왔을 때, 두 사람은 영웅으로 맞이했습니다. 윌로 크릭의 사람들은 기뻐했고 마법의 배낭을 든 소녀의 전설은 수 세대에 걸쳐 전해졌습니다. 그래서 Anya는 백팩의 경이로움을 활용하여 세상을 더 나은 곳으로 만들기 위해 마법 같은 걸음을 하나씩 계속하며 모험을 이어갔습니다.

자연어 사용

대규모 언어 모델은 강력한 멀티태스킹 도구입니다. 종종 Gemini에 원하는 것을 물어보면 괜찮아집니다.

Gemini API에는 JSON 모드가 없으므로 이러한 방식으로 데이터 구조를 생성할 때는 몇 가지 사항을 주의해야 합니다.

  • 파싱이 실패하는 경우도 있습니다.
  • 스키마를 엄격하게 적용할 수는 없습니다.

다음 섹션에서 이러한 문제를 해결할 것입니다. 먼저 스키마를 텍스트로 작성한 간단한 자연어 프롬프트를 사용해 봅니다. 다음과 같이 최적화되지 않았습니다.

model = model = model = genai.GenerativeModel(
    model_name='models/gemini-1.5-pro-latest')

response = model.generate_content(
  textwrap.dedent("""\
    Please return JSON describing the the people, places, things and relationships from this story using the following schema:

    {"people": list[PERSON], "places":list[PLACE], "things":list[THING], "relationships": list[RELATIONSHIP]}

    PERSON = {"name": str, "description": str, "start_place_name": str, "end_place_name": str}
    PLACE = {"name": str, "description": str}
    THING = {"name": str, "description": str, "start_place_name": str, "end_place_name": str}
    RELATIONSHIP = {"person_1_name": str, "person_2_name": str, "relationship": str}

    All fields are required.

    Important: Only return a single piece of valid JSON text.

    Here is the story:

    """) + story,
  generation_config={'response_mime_type':'application/json'}
)
response.text
'{"people": [\n    {\n        "name": "Anya",\n        "description": "A young girl who lives in the town of Willow Creek with her parents, Elise and Edward. She possesses a magical backpack that was handed down to her from her grandmother.",\n        "start_place_name": "Willow Creek",\n        "end_place_name": "Willow Creek"\n    },\n    {\n        "name": "Elise",\n        "description": "Anya\'s kind-hearted mother",\n        "start_place_name": "Willow Creek",\n        "end_place_name": "Willow Creek"\n    },\n    {\n        "name": "Edward",\n        "description": "Anya\'s wise-bearded father",\n        "start_place_name": "Willow Creek",\n        "end_place_name": "Willow Creek"\n    },\n    {\n        "name": "Samuel",\n        "description": "Anya\'s best friend, a curious and adventurous boy with a mischievous grin.",\n        "start_place_name": "Willow Creek",\n        "end_place_name": "Willow Creek"\n    },\n    {\n        "name": "Monster",\n        "description": "A massive beast with sharp teeth, glowing red eyes, and claws that could crush a human with ease.",\n        "start_place_name": "Forest",\n        "end_place_name": "Forest"\n    }\n], "places": [\n    {\n        "name": "Willow Creek",\n        "description": "A quaint town nestled amidst rolling hills and whispering willows."\n    },\n    {\n        "name": "Forest",\n        "description": "A shadowy place with rustling undergrowth and whispering trees."\n    },\n    {\n        "name": "Schoolhouse",\n        "description": "The only school in the town of Willow Creek."\n    },\n    {\n        "name": "Anya\'s home",\n        "description": "A modest cottage with a creaky wooden door."\n    }\n], "things": [\n    {\n        "name": "Magic backpack",\n        "description": "A magical backpack that was handed down to Anya from her grandmother. Its soft, emerald-green fabric shimmered with an ethereal glow, and its leather straps held secrets that only Anya knew.",\n        "start_place_name": "Anya\'s home",\n        "end_place_name": "Forest"\n    },\n    {\n        "name": "Shimmering sword",\n        "description": "A sword that shimmered in the sunlight and could strike with blinding light.",\n        "start_place_name": "Magic backpack",\n        "end_place_name": "Forest"\n    },\n    {\n        "name": "Book of ancient spells",\n        "description": "A book that contained ancient spells.",\n        "start_place_name": "Magic backpack",\n        "end_place_name": "Forest"\n    },\n    {\n        "name": "Tiny compass",\n        "description": "A compass that always pointed north.",\n        "start_place_name": "Magic backpack",\n        "end_place_name": "Forest"\n    },\n    {\n        "name": "Magical key",\n        "description": "A key that could open any lock.",\n        "start_place_name": "Magic backpack",\n        "end_place_name": "Forest"\n    },\n    {\n        "name": "Shattered crystals",\n        "description": "The remains of the monster after it was defeated by Anya\'s magic backpack.",\n        "start_place_name": "Forest",\n        "end_place_name": "Forest"\n    }\n], "relationships": [\n    {\n        "person_1_name": "Anya",\n        "person_2_name": "Elise",\n        "relationship": "mother-daughter"\n    },\n    {\n        "person_1_name": "Anya",\n        "person_2_name": "Edward",\n        "relationship": "father-daughter"\n    },\n    {\n        "person_1_name": "Anya",\n        "person_2_name": "Samuel",\n        "relationship": "best friends"\n    }\n]}'

JSON 문자열이 반환되었습니다. 파싱해 보세요.

import json

print(json.dumps(json.loads(response.text), indent=4))
{
    "people": [
        {
            "name": "Anya",
            "description": "A young girl who lives in the town of Willow Creek with her parents, Elise and Edward. She possesses a magical backpack that was handed down to her from her grandmother.",
            "start_place_name": "Willow Creek",
            "end_place_name": "Willow Creek"
        },
        {
            "name": "Elise",
            "description": "Anya's kind-hearted mother",
            "start_place_name": "Willow Creek",
            "end_place_name": "Willow Creek"
        },
        {
            "name": "Edward",
            "description": "Anya's wise-bearded father",
            "start_place_name": "Willow Creek",
            "end_place_name": "Willow Creek"
        },
        {
            "name": "Samuel",
            "description": "Anya's best friend, a curious and adventurous boy with a mischievous grin.",
            "start_place_name": "Willow Creek",
            "end_place_name": "Willow Creek"
        },
        {
            "name": "Monster",
            "description": "A massive beast with sharp teeth, glowing red eyes, and claws that could crush a human with ease.",
            "start_place_name": "Forest",
            "end_place_name": "Forest"
        }
    ],
    "places": [
        {
            "name": "Willow Creek",
            "description": "A quaint town nestled amidst rolling hills and whispering willows."
        },
        {
            "name": "Forest",
            "description": "A shadowy place with rustling undergrowth and whispering trees."
        },
        {
            "name": "Schoolhouse",
            "description": "The only school in the town of Willow Creek."
        },
        {
            "name": "Anya's home",
            "description": "A modest cottage with a creaky wooden door."
        }
    ],
    "things": [
        {
            "name": "Magic backpack",
            "description": "A magical backpack that was handed down to Anya from her grandmother. Its soft, emerald-green fabric shimmered with an ethereal glow, and its leather straps held secrets that only Anya knew.",
            "start_place_name": "Anya's home",
            "end_place_name": "Forest"
        },
        {
            "name": "Shimmering sword",
            "description": "A sword that shimmered in the sunlight and could strike with blinding light.",
            "start_place_name": "Magic backpack",
            "end_place_name": "Forest"
        },
        {
            "name": "Book of ancient spells",
            "description": "A book that contained ancient spells.",
            "start_place_name": "Magic backpack",
            "end_place_name": "Forest"
        },
        {
            "name": "Tiny compass",
            "description": "A compass that always pointed north.",
            "start_place_name": "Magic backpack",
            "end_place_name": "Forest"
        },
        {
            "name": "Magical key",
            "description": "A key that could open any lock.",
            "start_place_name": "Magic backpack",
            "end_place_name": "Forest"
        },
        {
            "name": "Shattered crystals",
            "description": "The remains of the monster after it was defeated by Anya's magic backpack.",
            "start_place_name": "Forest",
            "end_place_name": "Forest"
        }
    ],
    "relationships": [
        {
            "person_1_name": "Anya",
            "person_2_name": "Elise",
            "relationship": "mother-daughter"
        },
        {
            "person_1_name": "Anya",
            "person_2_name": "Edward",
            "relationship": "father-daughter"
        },
        {
            "person_1_name": "Anya",
            "person_2_name": "Samuel",
            "relationship": "best friends"
        }
    ]
}

이 방법은 비교적 간단하고 종종 효과가 있지만 API의 함수 호출 기능을 사용하여 스키마를 정의하여 더 엄격하고 강력하게 만들 수 있습니다.

함수 호출 사용

함수 호출 기본사항 튜토리얼을 아직 진행하지 않았다면 먼저 진행해야 합니다.

함수를 호출하는 함수와 함수의 매개변수는 API에 genai.protos.FunctionDeclaration로 설명됩니다. 기본적으로 SDK는 함수와 주석에서 FunctionDeclaration를 빌드할 수 있습니다. 따라서 지금은 명시적으로 정의해야 합니다.

스키마 정의

person를 문자열 필드가 name, description, start_place_name, end_place_name인 객체로 정의합니다.

person = genai.protos.Schema(
    type = genai.protos.Type.OBJECT,
    properties = {
        'name':  genai.protos.Schema(type=genai.protos.Type.STRING),
        'description':  genai.protos.Schema(type=genai.protos.Type.STRING),
        'start_place_name': genai.protos.Schema(type=genai.protos.Type.STRING),
        'end_place_name': genai.protos.Schema(type=genai.protos.Type.STRING)
    },
    required=['name', 'description', 'start_place_name', 'end_place_name']
)

그런 다음 사람을 person 객체의 ARRAY로 정의합니다.

people = genai.protos.Schema(
    type=genai.protos.Type.ARRAY,
    items=person
)

그런 다음 추출하려는 각 항목에 대해 동일한 작업을 수행합니다.

place = genai.protos.Schema(
    type = genai.protos.Type.OBJECT,
    properties = {
        'name':  genai.protos.Schema(type=genai.protos.Type.STRING),
        'description':  genai.protos.Schema(type=genai.protos.Type.STRING),
    }
)

places = genai.protos.Schema(
    type=genai.protos.Type.ARRAY,
    items=place
)
thing = genai.protos.Schema(
  type = genai.protos.Type.OBJECT,
  properties = {
      'name':  genai.protos.Schema(type=genai.protos.Type.STRING),
      'description':  genai.protos.Schema(type=genai.protos.Type.STRING),
  }
)

things = genai.protos.Schema(
    type=genai.protos.Type.ARRAY,
    items=thing
)
relationship = genai.protos.Schema(
    type = genai.protos.Type.OBJECT,
    properties = {
        'person_1_name':  genai.protos.Schema(type=genai.protos.Type.STRING),
        'person_2_name':  genai.protos.Schema(type=genai.protos.Type.STRING),
        'relationship':  genai.protos.Schema(type=genai.protos.Type.STRING),
    }
)

relationships = genai.protos.Schema(
    type=genai.protos.Type.ARRAY,
    items=relationship
)

이제 FunctionDeclaration를 빌드합니다.

add_to_database = genai.protos.FunctionDeclaration(
    name="add_to_database",
    description=textwrap.dedent("""\
        Adds entities to the database.
        """),
    parameters=genai.protos.Schema(
        type=genai.protos.Type.OBJECT,
        properties = {
            'people': people,
            'places': places,
            'things': things,
            'relationships': relationships
        }
    )
)

API 호출

함수 호출 기본사항에서 본 것처럼 이제 이 FunctionDeclarationgenai.GenerativeModel 생성자의 tools 인수에 전달할 수 있습니다. 생성자는 함수 선언의 동등한 JSON 표현도 허용합니다.

model = model = genai.GenerativeModel(
    model_name='models/gemini-1.5-pro-latest',
    tools = [add_to_database])

API를 호출할 때마다 SDK가 프롬프트와 함께 도구를 전송하며 모델은 정의된 함수를 호출해야 합니다.

result = model.generate_content(f"""
Please add the people, places, things, and relationships from this story to the database:

{story}
""",
# Force a function call
tool_config={'function_calling_config':'ANY'})

이제 파싱할 텍스트가 없습니다. 결과는 데이터 구조 입니다.

'text' in result.candidates[0].content.parts[0]
False
'function_call' in result.candidates[0].content.parts[0]
True
fc = result.candidates[0].content.parts[0].function_call
print(type(fc))
<class 'google.ai.generativelanguage_v1beta.types.content.FunctionCall'>

genai.protos.FunctionCall 클래스는 Google 프로토콜 버퍼를 기반으로 하므로 더 익숙한 JSON 호환 객체로 변환합니다.

print(json.dumps(type(fc).to_dict(fc), indent=4))
{
    "name": "add_to_database",
    "args": {
        "things": [
            {
                "name": "Magical Backpack",
                "description": "Anya's prized possession, the Magical Backpack, is no ordinary satchel. Its soft, emerald-green fabric shimmers with an ethereal glow, and its leather straps have secrets that only Anya knows. Within its capacious interior lay an enchanted world, filled with wonders that would ignite her imagination and change her life forever."
            },
            {
                "name": "Shimmering Sword",
                "description": "Among the wonders in Anya's Magical Backpack, lies a shimmering sword. With a determined gleam in her eye, she retrieved the shimmering sword and charged towards the monster."
            },
            {
                "description": "Residing within the Magical Backpack, the Book of Ancient Spells holds secrets untold.",
                "name": "Book of Ancient Spells"
            },
            {
                "description": "Tucked away in the Magical Backpack is a tiny compass that always points north.",
                "name": "Tiny Compass that Always Points North"
            },
            {
                "description": "Hidden within the Magical Backpack is a magical key that can open any lock.",
                "name": "Magical Key that Can Open Any Lock"
            }
        ],
        "relationships": [
            {
                "relationship": "Mother-Daughter",
                "person_1_name": "Anya",
                "person_2_name": "Elise"
            },
            {
                "person_2_name": "Edward",
                "relationship": "Father-Daughter",
                "person_1_name": "Anya"
            },
            {
                "person_2_name": "Samuel",
                "person_1_name": "Anya",
                "relationship": "Best Friends"
            }
        ],
        "people": [
            {
                "name": "Anya",
                "description": "Anya, the main character of the story, is a young girl with a magical backpack.",
                "start_place_name": "Willow Creek",
                "end_place_name": "Unknown"
            },
            {
                "name": "Elise",
                "description": "Anya's mother, Elise is a kind-hearted woman.",
                "end_place_name": "Unknown",
                "start_place_name": "Willow Creek"
            },
            {
                "start_place_name": "Willow Creek",
                "end_place_name": "Unknown",
                "name": "Edward",
                "description": "Anya's father, Edward is a wise-bearded man."
            },
            {
                "end_place_name": "Unknown",
                "start_place_name": "Willow Creek",
                "description": "Anya's best friend, Samuel is a curious and adventurous boy with a mischievous grin.",
                "name": "Samuel"
            }
        ],
        "places": [
            {
                "description": "The quaint town of Willow Creek is nestled amidst rolling hills and whispering willows.",
                "name": "Willow Creek"
            },
            {
                "description": "The town's only schoolhouse.",
                "name": "Schoolhouse"
            },
            {
                "description": "A shadowy place filled with secrets and dangers, the Forest is home to a terrifying monster.",
                "name": "Forest"
            }
        ]
    }
}

결론

API는 순수한 텍스트 입력 및 텍스트 출력으로 구조화된 데이터 추출 문제를 처리할 수 있지만 함수 호출을 사용하는 것이 더 안정적입니다. 엄격한 스키마를 정의할 수 있고 오류가 발생하기 쉬운 파싱 단계를 없앨 수 있기 때문입니다.