[DSPy] 05.Signatures :Programming—not prompting—Language Models

DSPy

Table of Contents

    DSPy에서 LM에 작업을 할당할 때 필요한 동작을 Signature로 지정합니다.

    Signature는 DSPy 모듈의 입출력 동작에 대한 선언적 사양입니다. Signature를 사용하면 LM에 작업을 요청하는 방법을 지정하는 대신 LM이 수행해야 할 작업을 알려줄 수 있습니다.

    입력 및 출력 인자와 그 유형을 지정하는 함수 Signature에 익숙하실 것입니다. DSPy Signature은 비슷하지만 차이점이 있습니다:

    일반적인 함수 Signature는 사물을 설명하는 데 그치지만, DSPy Signature는 모듈의 동작을 정의하고 제어합니다.

    DSPy Signature에서는 필드 이름이 중요합니다. 질문은 답변과 다르고, sql_쿼리는 python_code와 다르듯이 의미적 역할을 일반 영어로 표현합니다.

    DSPy Signature를 사용해야 하는 이유는 무엇인가요?

    LM 호출을 고품질 프롬프트(또는 자동 미세 조정)로 최적화할 수 있는 모듈식 및 깔끔한 코드의 경우.

    긴 답변: 대부분의 사람들은 길고 깨지기 쉬운 프롬프트를 해킹하여 LM에게 작업을 수행하도록 강요합니다. 또는 미세 조정을 위해 데이터를 수집/생성하는 방식으로요.

    서명을 작성하는 것은 프롬프트나 미세 조정에서 해킹하는 것보다 훨씬 더 모듈적이고 적응적이며 재현성이 뛰어납니다. DSPy 컴파일러는 데이터와 파이프라인 내에서 서명을 위해 고도로 최적화된 프롬프트를 작성하는 방법(또는 작은 LM을 미세 조정하는 방법)을 알아냅니다. 많은 경우 컴파일을 통해 사람이 작성하는 것보다 더 나은 프롬프트가 생성된다는 사실을 발견했습니다. DSPy 최적화 도구가 사람보다 더 창의적이기 때문이 아니라 단순히 더 많은 것을 시도하고 메트릭을 직접 조정할 수 있기 때문입니다.

    Inline DSPy Signatures

    서명은 입력/출력의 시맨틱 역할을 정의하는 인수 이름과 함께 짧은 문자열로 정의할 수 있습니다.

    1. Question Answering: "question -> answer"
    2. Sentiment Classification: "sentence -> sentiment"
    3. Summarization: "document -> summary"

    서명은 여러 입력/출력 필드를 가질 수도 있습니다.

    1. Retrieval-Augmented Question Answering: "context, question -> answer"
    2. Multiple-Choice Question Answering with Reasoning: "question, choices -> reasoning, selection"

    Tip: 필드의 경우 유효한 변수 이름이면 무엇이든 가능합니다! 필드 이름은 의미론적으로 의미가 있어야 하지만 간단하게 시작하고 키워드를 미리 최적화하지 마세요! 그런 종류의 해킹은 DSPy 컴파일러에 맡기세요. 예를 들어 요약의 경우 “document -> summary”, “text -> gist” 또는 “long_context -> tldr”이라고 하는 것이 좋습니다.

    Example A: Sentiment Classification

    sentence = "it's a charming and often affecting journey." # example from the SST-2 dataset.
    
    classify = dspy.Predict('sentence -> sentiment')
    classify(sentence=sentence).sentiment

    Output:

    'Positive'

    Example B: Summarization

    # Example from the XSum dataset.
    document = """The 21-year-old made seven appearances for the Hammers and netted his only goal for them in a Europa League qualification round match against Andorran side FC Lustrains last season. Lee had two loan spells in League One last term, with Blackpool and then Colchester United. He scored twice for the U's but was unable to save them from relegation. The length of Lee's contract with the promoted Tykes has not been revealed. Find all the latest football transfers on our dedicated page."""
    
    summarize = dspy.ChainOfThought('document -> summary')
    response = summarize(document=document)
    
    print(response.summary)

    Output:

    The 21-year-old Lee made seven appearances and scored one goal for West Ham last season. He had loan spells in League One with Blackpool and Colchester United, scoring twice for the latter. He has now signed a contract with Barnsley, but the length of the contract has not been revealed.

    많은 DSPy 모듈(dspy.Predict 제외)은 내부적으로 서명을 확장하여 보조 정보를 반환합니다.

    예를 들어, dspy.ChainOfThought는 summary를 생성하기 전에 LM의 추론이 포함된 rationale field를 추가합니다.

    print("Rationale:", response.rationale)

    Class-based DSPy Signatures

    Class-based일부 고급 작업의 경우 더 자세한 서명이 필요합니다. 일반적으로 다음과 같은 경우입니다:

    작업의 성격에 대해 명확히 설명합니다(아래에서 문서 문자열로 표현).

    입력 필드의 특성에 대한 힌트를 제공하며, dspy.InputField의 desc 키워드 인수로 표현됩니다.

    출력 필드에 대한 제약 조건을 dspy.OutputField의 desc 키워드 인자로 표현합니다.

    Example C: Classification

    이 경우 완전히 정의된 작업을 수행하는 데 필요한 (최소한의) 지침이 문서 문자열에 어떻게 포함되어 있는지 확인하세요.

    COPRO와 같은 DSPy의 일부 옵티마이저는 이 간단한 문서 문자열을 가져와서 필요한 경우 더 효과적인 변형을 생성할 수 있습니다.

    class Emotion(dspy.Signature):
    """Classify emotion among sadness, joy, love, anger, fear, surprise."""
    
       sentence = dspy.InputField()
       sentiment = dspy.OutputField()
    
    sentence = "i started feeling a little vulnerable when the giant spotlight started blinding me" # from dair-ai/emotion
    
    classify = dspy.Predict(Emotion)
    classify(sentence=sentence)

    Output:

    Prediction(
    sentiment='Fear'
    )

    Tip: LM에 요청을 좀 더 명확하게 명시하는 것은 잘못된 것이 아닙니다. 클래스 기반 서명이 이를 도와줍니다. 하지만 서명의 키워드를 손으로 직접 조정하지 마세요. DSPy 최적화 도구가 더 나은 작업을 수행할 가능성이 높으며 LM 간에 더 잘 전송될 것입니다.

    Example D: A metric that evaluates faithfulness to citations

    class CheckCitationFaithfulness(dspy.Signature):
    """Verify that the text is based on the provided context."""
    
        context = dspy.InputField(desc="facts here are assumed to be true")
        text = dspy.InputField()
        faithfulness = dspy.OutputField(desc="True/False indicating if text is faithful to context")
    
    context = "The 21-year-old made seven appearances for the Hammers and netted his only goal for them in a Europa League qualification round match against Andorran side FC Lustrains last season. Lee had two loan spells in League One last term, with Blackpool and then Colchester United. He scored twice for the U's but was unable to save them from relegation. The length of Lee's contract with the promoted Tykes has not been revealed. Find all the latest football transfers on our dedicated page."
    
    text = "Lee scored 3 goals for Colchester United."
    
    faithfulness = dspy.ChainOfThought(CheckCitationFaithfulness)
    faithfulness(context=context, text=text)

    Output:

    Prediction(
    rationale="produce the faithfulness. We know that Lee had two loan spells in League One last term, with Blackpool and then Colchester United. He scored twice for the U's but was unable to save them from relegation. However, there is no mention of him scoring three goals for Colchester United.",
    faithfulness='False'
    )

    Signatures를 사용하여 모듈 빌드 및 컴파일하기

    서명은 구조화된 입력/출력으로 프로토타입을 제작할 때 편리하지만, 이것이 서명을 사용하는 주된 이유는 아닙니다!

    여러 서명을 더 큰 DSPy 모듈로 구성하고 이러한 모듈을 최적화된 프롬프트와 미세 조정으로 컴파일해야 합니다.