当前,DSPy 在全球引起了轰动。它是斯坦福最受欢迎的开源项目,并且正在改变人们在大语言模型上构建应用的方式。然而,它的入门以及理解都存在一定的困难性,尤其是对于小白用户。本文旨在提供一个 DSPy 的易于理解的入门介绍。本文参考 YouTube 视频系列 Learn By Building AI[1],以及翻译自文章《A gentle introduction to DSPy
》。
import requestsfrom bs4 import BeautifulSoupimport dspy res = requests.get("https://grugbrain.dev/")soup = BeautifulSoup(res.text, 'html.parser')raw_text = [p.text for p in soup.find_all('p') if p.text] raw_text[:10]
from openai import OpenAIclient = OpenAI()openai_model_name= "gpt-3.5-turbo" class BuildMessages:def __init__(self, system_prompt, user_prompt):self.system_prompt = system_promptself.user_prompt = user_promptdef render(self, **kwargs):sys = self.system_prompt.format(**kwargs)user = self.user_prompt.format(**kwargs)return [{"role":"system", "content":sys},{"role":"user", "content":user},]from functools import cache@cachedef translate_grug(grug_text):prompt = BuildMessages("You are an expert in deciphering strange text. The user will provide text written by someone named Grug and you will provide the translation.","""Translate the following text into plain english: '{text}'. Do not respond with any other text. Only provide that text. Now take a deep breath and begin.""")result = client.chat.completions.create(messages=prompt.render(text=grug_text), model=openai_model_name)return result.choices[0].message.content
import dspy class GrugTranslation(dspy.Signature):"Translate plain english to Grug text."plain_english = dspy.InputField()grug_text = dspy.OutputField()
# https://apps.dtic.mil/sti/tr/pdf/AD0667273.pdfdef automated_readability_index(text):import recharacters = len(re.sub(r'\s+', '', text)) # Count characters (ignoring whitespace)words = len(text.split()) # Count words by splitting the text# Count sentences by finding period, exclamation, or question marksentences = len(re.findall(r'[.!?\n]', text))# small change is to add a new line character as grug doesn't seem to use punctuation.if words == 0 or sentences == 0:# Prevent division by zeroreturn 0# Calculate the Automated Readability Index (ARI)ari = (4.71 * (characters / words)) + (0.5 * (words / sentences)) - 21.43 return round(ari, 2)
# https://dspy-docs.vercel.app/docs/building-blocks/metrics#intermediate-using-ai-feedback-for-your-metricclass AssessBasedOnQuestion(dspy.Signature):"""Given the assessed text provide a yes or no to the assessment question."""assessed_text = dspy.InputField(format=str)assessment_question = dspy.InputField(format=str)assessment_answer = dspy.OutputField(desc="Yes or No") example_question_assessment = dspy.Example(assessed_text="This is a test.", assessment_question="Is this a test?", assessment_answer="Yes").with_inputs("assessed_text", "assessment_question") print(signature_to_template(AssessBasedOnQuestion).query(example_question_assessment))
gpt4T = dspy.OpenAI(model='gpt-4-turbo', max_tokens=500) def similarity_metric(truth, pred, trace=None):truth_grug_text = truth.grug_textproposed_grug_text = pred.grug_textsimilarity_question = f"""Does the assessed text have the same meaning as the gold_standard text provided?Gold Standard: "{truth_grug_text}"Provide only a yes or no answer."""with dspy.context(lm=gpt4T):assessor = dspy.Predict(AssessBasedOnQuestion)raw_similarity_result = assessor(assessed_text=proposed_grug_text, assessment_question=similarity_question)print(raw_similarity_result) # for debuggingraw_similarity = raw_similarity_result.assessment_answer.lower().strip()same_meaning = raw_similarity == 'yes'return same_meaning