클래스 기반 시그니처 작성하기
클래스 기반 시그니처 작성하기
문자열 시그니처 "a, b -> c"는 한 줄로 빠르게 작업을 정의할 때 좋아요. 하지만 필드에 설명을 붙이거나, 작업 지시를 문장으로 남기고 싶다면 클래스 기반 시그니처로 옮겨가야 해요. 같은 구조를 잡으면서도 추가적인 제어 레버 몇 개를 얻을 수 있죠.
출처: 공식문서
클래스 기반 시그니처로 지시의 뉘앙스 더하기
클래스 기반 시그니처는 문자열 시그니처가 기술하는 구조를 동일하게 담으면서, 뉘앙스를 더할 수 있는 레버를 추가해요. 하이쿠 작성기 시그니처를 클래스 기반으로 다시 쓰면 이렇게 됩니다.
class HaikuBot(dspy.Signature):
"""
Write a classical haiku given the provided inputs.
"""
location: str = dspy.InputField(desc="The setting of the poem")
mood: str = dspy.InputField()
haiku: str = dspy.OutputField()
필드(location, mood, 그리고 출력 haiku)는 이전과 같이 문자열로 타입이 붙어 있어요. 하지만 이제 각 필드에 설명(desc) 을 추가할 수 있게 됐지요. 필드 설명은 필드 이름 안에 담기 어려운 뉘앙스를 더할 수 있게 해줍니다.
클래스 기반 시그니처는 독스트링도 작성할 수 있어요. 클래스 시작 부분의 이 문자열은 프롬프트를 준비할 때 DSPy가 작업 지시로 사용합니다.
클래스 기반 시그니처도 문자열 시그니처처럼 모듈에 넘기면 돼요.
haiku_bot = dspy.Predict(HaikuBot)
result = haiku_bot(location="a quiet library", mood="mysterious")
print(result.haiku)
이 호출은 LM에 비슷한 지시를 렌더링하고 보내지만, 두 가지가 달라요. 독스트링과 필드 설명이 시스템 지시를 만들 때 사용된다는 점입니다.
Your input fields are:
1. `location` (str): The setting of the poem
2. `mood` (str):
Your output fields are:
1. `haiku` (str):
All interactions will be structured in the following way, with the appropriate values filled in.
[[ ## location ## ]]
{location}
[[ ## mood ## ]]
{mood}
[[ ## haiku ## ]]
{haiku}
[[ ## completed ## ]]
In adhering to this structure, your objective is:
Write a classical haiku given the provided inputs.
시그니처 독스트링과 필드 설명은 선택 사항이에요. 하지만 필드 이름만으로 작업 맥락이 충분히 전달되지 않을 때 유용한 레버가 됩니다. 다만 시그니처가 이미 말하는 내용을 되풀이하거나, 처방적인 튜토리얼을 쓰고 싶은 충동은 참아야 해요. 광범위한 규칙·주의사항·지침은 옵티마이저가 다룰 몫입니다(이건 나중에 더 다룰게요).
한 가지 기억해 둘 점: 필드 설명은 옵티마이저가 건드리지 않아요. 그래서 이름을 잘 지어야 합니다. 잘못 고른 필드 이름은 옵티마이저가 고쳐줄 수 없어요.
더 풍부한 타입으로 시그니처 필드 다듬기
때로는 평범한 str이 너무 느슨할 때가 있어요. 값이 작은 고정 집합에서 나와야 한다면, LM(그리고 호출하는 쪽)이 그 바깥으로 벗어나지 않도록 꽉 잠가두고 싶을 거예요. 3장의 유닛 테스트 프레이밍을 더 엄격하게 만든 셈입니다. 어떤 문자열이 아니라 이 특정 문자열들 중 하나여야 하는 거죠.
Python 표준 라이브러리인 typing을 쓰면 더 풍부한 타입을 추가할 수 있어요.
season을 Literal["spring", "summer", "autumn", "winter"]로 타입 지정하면 정확히 그 동작을 해요. DSPy는 이제 호출 시점과 LM 응답 파싱 시점 모두에서 그 네 값만 받아들입니다.
from typing import Literal
Season = Literal[
"spring", "summer", "autumn", "winter",
]
class HaikuBot(dspy.Signature):
"""
Write a classical haiku given the provided inputs.
"""
location: str = dspy.InputField()
mood: str = dspy.InputField()
season: Season = dspy.InputField()
haiku: str = dspy.OutputField()
haiku_bot = dspy.Predict(HaikuBot)
result = haiku_bot(location="Bodega Bay", mood="mysterious", season="autumn")
print(result.haiku)
그러면 이런 결과가 나와요.
Fog drifts over waves,
Crimson leaves swirl by the pier—
Night whispers secrets.
하지만 season="fall"을 넘기면 불일치를 알리는 경고가 나옵니다.
WARNING dspy.predict.predict: Type mismatch for field 'season': expected Literal['spring', 'summer', 'autumn', 'winter'] based on given Signature, but the provided value is incompatible: fall.
출력 검증기, 다중 출력 조합, 더 풍부한 Pydantic 패턴 등 나머지 표면은 Signatures in depth에서 다뤄요.
더 알아보기 (Learn more)
- 시그니처 확장하기 — 입력·출력 추가와 타입 지정의 기초.
- Signatures in depth — 클래스 기반 시그니처의 전체 표면.