> ## Documentation Index
> Fetch the complete documentation index at: https://wb-21fd5541-feature-automate-reference-docs-generation.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Dspy prompt optimization

<Note>
  이것은 인터랙티브 노트북입니다. 로컬에서 실행하거나 아래 링크를 사용할 수 있습니다:

  * [Google Colab에서 열기](https://colab.research.google.com/github/wandb/weave/blob/master/docs/notebooks/dspy_prompt_optimization.ipynb)
  * [GitHub에서 소스 보기](https://github.com/wandb/weave/blob/master/docs/notebooks/dspy_prompt_optimization.ipynb)
</Note>

# DSPy와 Weave를 사용한 LLM 워크플로우 최적화

The [BIG-bench (Beyond the Imitation Game Benchmark)](https://github.com/google/BIG-bench)는 대규모 언어 모델을 테스트하고 미래 기능을 추론하기 위한 200개 이상의 작업으로 구성된 협업 벤치마크입니다. [BIG-Bench Hard (BBH)](https://github.com/suzgunmirac/BIG-Bench-Hard)는 현재 세대의 언어 모델로 해결하기 매우 어려울 수 있는 23개의 가장 도전적인 BIG-Bench 작업 모음입니다.

이 튜토리얼은 BIG-bench Hard 벤치마크의 **causal judgement task**에서 구현된 LLM 워크플로우의 성능을 향상시키고 프롬프팅 전략을 평가하는 방법을 보여줍니다. 우리는 [DSPy](https://dspy-docs.vercel.app/) LLM 워크플로우를 구현하고 프롬프트 전략을 최적화하기 위해 사용할 것입니다. 또한 [Weave](../../introduction.md)를 사용하여 LLM 워크플로우를 추적하고 프롬프트 전략을 평가할 것입니다.

## 의존성 설치하기

이 튜토리얼에는 다음 라이브러리가 필요합니다:

* [DSPy](https://dspy-docs.vercel.app/) - LLM 워크플로우를 구축하고 최적화하기 위해 사용합니다.
* [Weave](../../introduction.md) - LLM 워크플로우를 추적하고 프롬프트 전략을 평가하기 위해 사용합니다.
* [datasets](https://huggingface.co/docs/datasets/index) - HuggingFace Hub에서 Big-Bench Hard 데이터셋에 접근하기 위해 사용합니다.

```python
!pip install -qU dspy-ai weave datasets
```

우리는 [OpenAI API](https://openai.com/index/openai-api/)를 LLM 공급자로 사용할 것이기 때문에 OpenAI API 키도 필요합니다. OpenAI 플랫폼에서 [가입](https://platform.openai.com/signup)하여 자신만의 API 키를 얻을 수 있습니다.

```python
import os
from getpass import getpass

api_key = getpass("Enter you OpenAI API key: ")
os.environ["OPENAI_API_KEY"] = api_key
```

## Weave를 사용한 추적 활성화

Weave는 현재 DSPy와 통합되어 있으며, 코드 시작 부분에 [`weave.init`](../../reference/python-sdk/weave/index.md)를 포함하면 DSPy 함수를 자동으로 추적할 수 있으며 이는 Weave UI에서 탐색할 수 있습니다. 자세한 내용은 [Weave integration docs for DSPy](../../guides/integrations/dspy.md)를 확인하세요.

```python
import weave

weave.init(project_name="dspy-bigbench-hard")
```

이 튜토리얼에서는 [`weave.Object`](../../guides/tracking/objects.md)에서 상속받은 메타데이터 클래스를 사용하여 메타데이터를 관리합니다.

```python
class Metadata(weave.Object):
    dataset_address: str = "maveriq/bigbenchhard"
    big_bench_hard_task: str = "causal_judgement"
    num_train_examples: int = 50
    openai_model: str = "gpt-3.5-turbo"
    openai_max_tokens: int = 2048
    max_bootstrapped_demos: int = 8
    max_labeled_demos: int = 8

metadata = Metadata()
```

<Tip>
  **객체 버전 관리**: `Metadata` 객체는 이를 사용하는 함수가 추적될 때 자동으로 버전 관리되고 추적됩니다
</Tip>

## BIG-Bench Hard 데이터셋 로드하기

HuggingFace Hub에서 이 데이터셋을 로드하고, 훈련 및 검증 세트로 분할한 다음, [publish](../../guides/core-types/datasets.md)를 통해 Weave에 게시할 것입니다. 이를 통해 데이터셋의 버전을 관리하고 [`weave.Evaluation`](../../guides/core-types/evaluations.md)를 사용하여 프롬프트 전략을 평가할 수 있습니다.

```python
import dspy
from datasets import load_dataset

@weave.op()
def get_dataset(metadata: Metadata):
    # load the BIG-Bench Hard dataset corresponding to the task from Huggingface Hug
    dataset = load_dataset(metadata.dataset_address, metadata.big_bench_hard_task)[
        "train"
    ]

    # create the training and validation datasets
    rows = [{"question": data["input"], "answer": data["target"]} for data in dataset]
    train_rows = rows[0 : metadata.num_train_examples]
    val_rows = rows[metadata.num_train_examples :]

    # create the training and validation examples consisting of `dspy.Example` objects
    dspy_train_examples = [
        dspy.Example(row).with_inputs("question") for row in train_rows
    ]
    dspy_val_examples = [dspy.Example(row).with_inputs("question") for row in val_rows]

    # publish the datasets to the Weave, this would let us version the data and use for evaluation
    weave.publish(
        weave.Dataset(
            name=f"bigbenchhard_{metadata.big_bench_hard_task}_train", rows=train_rows
        )
    )
    weave.publish(
        weave.Dataset(
            name=f"bigbenchhard_{metadata.big_bench_hard_task}_val", rows=val_rows
        )
    )

    return dspy_train_examples, dspy_val_examples

dspy_train_examples, dspy_val_examples = get_dataset(metadata)
```

![](https://mintlify.s3.us-west-1.amazonaws.com/wb-21fd5541-feature-automate-reference-docs-generation/media/dspy_optimization/1.png)

## DSPy 프로그램

[DSPy](https://dspy-docs.vercel.app)는 자유 형식의 문자열을 조작하는 것에서 벗어나 프로그래밍(모듈식 연산자를 구성하여 텍스트 변환 그래프 구축)에 가까운 새로운 LM 파이프라인 구축을 추진하는 프레임워크로, 컴파일러가 프로그램에서 최적화된 LM 호출 전략과 프롬프트를 자동으로 생성합니다.

우리는 [`dspy.OpenAI`](https://dspy-docs.vercel.app/api/language_model_clients/OpenAI) 추상화를 사용하여 [GPT3.5 Turbo](https://platform.openai.com/docs/models/gpt-3-5-turbo)에 LLM 호출을 할 것입니다.

```python
system_prompt = """
You are an expert in the field of causal reasoning. You are to analyze the a given question carefully and answer in `Yes` or `No`.
You should also provide a detailed explanation justifying your answer.
"""

llm = dspy.OpenAI(model="gpt-3.5-turbo", system_prompt=system_prompt)
dspy.settings.configure(lm=llm)
```

### 인과 추론 시그니처 작성하기

[signature](https://dspy-docs.vercel.app/docs/building-blocks/signatures)는 [DSPy module](https://dspy-docs.vercel.app/docs/building-blocks/modules)의 입력/출력 동작에 대한 선언적 명세로, 이는 특정 텍스트 변환을 추상화하는 작업 적응형 컴포넌트(신경망 레이어와 유사)입니다.

```python
from pydantic import BaseModel, Field

class Input(BaseModel):
    query: str = Field(description="The question to be answered")

class Output(BaseModel):
    answer: str = Field(description="The answer for the question")
    confidence: float = Field(
        ge=0, le=1, description="The confidence score for the answer"
    )
    explanation: str = Field(description="The explanation for the answer")

class QuestionAnswerSignature(dspy.Signature):
    input: Input = dspy.InputField()
    output: Output = dspy.OutputField()

class CausalReasoningModule(dspy.Module):
    def __init__(self):
        self.prog = dspy.TypedPredictor(QuestionAnswerSignature)

    @weave.op()
    def forward(self, question) -> dict:
        return self.prog(input=Input(query=question)).output.dict()
```

Big-Bench Hard의 인과 추론 하위 집합에서 예제를 통해 우리의 LLM 워크플로우, 즉 `CausalReasoningModule`를 테스트해 봅시다.

```python
import rich

baseline_module = CausalReasoningModule()

prediction = baseline_module(dspy_train_examples[0]["question"])
rich.print(prediction)
```

![](https://mintlify.s3.us-west-1.amazonaws.com/wb-21fd5541-feature-automate-reference-docs-generation/media/dspy_optimization/2.png)

## DSPy 프로그램 평가하기

이제 기본 프롬프트 전략이 있으니, [`weave.Evaluation`](../../guides/core-types/evaluations.md)를 사용하여 예측된 답변과 실제 정답을 비교하는 간단한 메트릭으로 검증 세트에서 평가해 봅시다. Weave는 각 예제를 가져와 애플리케이션을 통과시키고 여러 사용자 정의 점수 함수로 출력을 평가합니다. 이를 통해 애플리케이션의 성능을 볼 수 있고, 개별 출력과 점수를 자세히 살펴볼 수 있는 풍부한 UI를 갖게 됩니다.

먼저, 기준 모듈의 출력에서 나온 답변이 실제 정답과 동일한지 여부를 알려주는 간단한 weave 평가 점수 함수를 만들어야 합니다. 점수 함수는 `model_output` 키워드 인수가 필요하지만, 다른 인수는 사용자 정의이며 데이터셋 예제에서 가져옵니다. 인수 이름을 기반으로 한 사전 키를 사용하여 필요한 키만 가져올 것입니다.

```python
@weave.op()
def weave_evaluation_scorer(answer: str, output: Output) -> dict:
    return {"match": int(answer.lower() == output["answer"].lower())}
```

다음으로, 평가를 정의하고 실행할 수 있습니다.

```python
validation_dataset = weave.ref(
    f"bigbenchhard_{metadata.big_bench_hard_task}_val:v0"
).get()

evaluation = weave.Evaluation(
    name="baseline_causal_reasoning_module",
    dataset=validation_dataset,
    scorers=[weave_evaluation_scorer],
)

await evaluation.evaluate(baseline_module.forward)
```

![](https://mintlify.s3.us-west-1.amazonaws.com/wb-21fd5541-feature-automate-reference-docs-generation/media/dspy_optimization/3.png)

<Note>
  Python 스크립트에서 실행하는 경우, 다음 코드를 사용하여 평가를 실행할 수 있습니다:

  ```python
  import asyncio
  asyncio.run(evaluation.evaluate(baseline_module.forward))
  ```
</Note>

<Warning>
  인과 추론 데이터셋에 대한 평가를 실행하면 OpenAI 크레딧으로 약 \$0.24가 소요됩니다.
</Warning>

## DSPy 프로그램 최적화하기

이제 기본 DSPy 프로그램이 있으니, [DSPy teleprompter](https://dspy-docs.vercel.app/docs/building-blocks/optimizers)를 사용하여 인과 추론에 대한 성능을 향상시켜 보겠습니다. 이는 지정된 메트릭을 최대화하기 위해 DSPy 프로그램의 매개변수를 조정할 수 있습니다. 이 튜토리얼에서는 [BootstrapFewShot](https://dspy-docs.vercel.app/api/category/optimizers) 텔레프롬프터를 사용합니다.

```python
from dspy.teleprompt import BootstrapFewShot

@weave.op()
def get_optimized_program(model: dspy.Module, metadata: Metadata) -> dspy.Module:
    @weave.op()
    def dspy_evaluation_metric(true, prediction, trace=None):
        return prediction["answer"].lower() == true.answer.lower()

    teleprompter = BootstrapFewShot(
        metric=dspy_evaluation_metric,
        max_bootstrapped_demos=metadata.max_bootstrapped_demos,
        max_labeled_demos=metadata.max_labeled_demos,
    )
    return teleprompter.compile(model, trainset=dspy_train_examples)

optimized_module = get_optimized_program(baseline_module, metadata)
```

![](https://mintlify.s3.us-west-1.amazonaws.com/wb-21fd5541-feature-automate-reference-docs-generation/media/dspy_optimization/4.png)

<Warning>
  인과 추론 데이터셋에 대한 평가를 실행하면 OpenAI 크레딧으로 약 \$0.04가 소요됩니다.
</Warning>

이제 최적화된 프로그램(최적화된 프롬프트 전략)이 있으니, 검증 세트에서 다시 한 번 평가하고 기본 DSPy 프로그램과 비교해 봅시다.

```python
evaluation = weave.Evaluation(
    name="optimized_causal_reasoning_module",
    dataset=validation_dataset,
    scorers=[weave_evaluation_scorer],
)

await evaluation.evaluate(optimized_module.forward)
```

![](https://mintlify.s3.us-west-1.amazonaws.com/wb-21fd5541-feature-automate-reference-docs-generation/media/dspy_optimization/5.png)

기본 프로그램과 최적화된 프로그램의 평가를 비교해보면, 최적화된 프로그램이 인과 추론 질문에 훨씬 더 정확하게 답변하는 것을 볼 수 있습니다.

## 결론

이 튜토리얼에서는 DSPy를 사용하여 프롬프트를 최적화하고 Weave를 사용하여 추적 및 평가를 통해 원래 프로그램과 최적화된 프로그램을 비교하는 방법을 배웠습니다.
