LangChain(0.0.339) 공식 문서 4: 프롬프트 아래 - 프롬프트 템플릿의 저장, 로딩, 조합 및 부분 서식 지정

LangChain 관관,LangChain 관방 문관 ,langchain Github ,langchain API 문관,llm-universe

1. 부분 프롬프트 템플릿

参考 《부분 프롬프트 템플릿》

  부분 프롬프트 템플릿 형식(Partial prompt templates)은 LangChain에서 지원하는 프롬프트 템플릿 사용 방법입니다. 이를 통해 사용자는 프롬프트 템플릿의 필요한 일부 변수만 형식화할 수 있습니다. 그런 다음 사용자는 누락된 나머지 변수를 전달하여 프롬프트 템플릿의 이 부분을 추가로 형식화하고 최종적으로 전체 프롬프트를 완전히 렌더링할 수 있습니다. Partial prompt templates다음과 같은 적용 시나리오가 있습니다:

  1. 단계별 구축 팁. 일부 시나리오에서는 프롬프트를 여러 단계로 구성해야 하므로 변수를 얻는 시간이나 순서가 고정되지 않을 수 있습니다. 부분 서식을 사용하면 각 단계에서 해당 단계와 관련된 변수만 전달할 수 있으므로 프롬프트 템플릿이 점차 개선됩니다.

  2. 프롬프트 템플릿을 재사용하세요. 부분 서식을 통해 동일한 프롬프트 템플릿을 기반으로 다양한 시나리오에 적합한 사용자 정의 프롬프트 템플릿을 구축할 수 있습니다. 부분 서식을 통해 다양한 사용자 정의 요구 사항이 구현되므로 프롬프트 템플릿이 더욱 다양해집니다.

  3. 조합 팁. 부분 포맷을 사용하면 변수 획득 프로세스와 프롬프트 템플릿 조립 프로세스를 분리할 수 있습니다. 변수는 최종적으로 함께 요약되는 한 다양한 방법으로 얻을 수 있습니다.

  일반적으로 일부 프롬프트 템플릿 형식은 프롬프트 템플릿을 사용하는 보다 유연하고 창의적인 방법을 지원하여 프롬프트 기능의 구성 및 사용을 보다 효율적으로 만듭니다.

LangChain에는 부분 프롬프트 템플릿에 대한 두 가지 지원 방법이 있습니다.

  • 문자열 값을 사용한 부분 형식 지정
  • 부분 서식 지정에 함수(문자열 값 반환) 사용

1.1 문자열 값을 사용한 부분 서식 지정(문자열을 사용한 부분)

  Partial prompt templates일반적인 시나리오는 템플릿 변수를 얻는 시간적 순서가 일관성이 없다는 것입니다. 프롬프트 템플릿에 두 개의 변수 foo와 baz가 필요하다고 가정하면 작업 체인에서 foo를 먼저 얻고 baz를 나중에 얻습니다. 일반적인 접근 방식은 두 변수를 프롬프트 템플릿 어딘가에 전달하기 전에 가져올 때까지 기다리는 것입니다. 이제 먼저 foo 값 부분으로 프롬프트 템플릿의 형식을 지정한 다음 프롬프트 템플릿의 해당 부분을 사용하여 후속 단계에서 baz 값을 전달할 수 있습니다.

  1. 부분적으로 서식이 지정된 PromptTemplate 예
    먼저 PromptTemplate을 인스턴스화한 다음 부분 메서드를 호출하여 부분 서식을 수행하고 부분적으로 서식이 지정된 PromptTemplate 개체(partial_prompt)를 가져옵니다.
from langchain.prompts import PromptTemplate

prompt = PromptTemplate(template="{foo}{bar}", input_variables=["foo", "bar"])
partial_prompt = prompt.partial(foo="foo");
print(partial_prompt.format(bar="baz"))
foobaz
  1. 부분 변수를 사용하여 PromptTemplate 초기화
    PromptTemplate을 초기화할 때 부분 변수tial_variables를 직접 전달하여 인스턴스화 시 부분 서식 지정이 완료되도록 합니다.
prompt = PromptTemplate(template="{foo}{bar}", input_variables=["bar"], partial_variables={
    
    "foo": "foo"})
print(prompt.format(bar="baz"))

  두 코드로 얻은 최종 효과는 동일하며, 부분 서식 지정 시점에 차이가 있습니다. 첫 번째 방법은 더 유연하며 필요한 만큼 부분적으로 형식을 지정할 수 있습니다.

1.2 부분 서식에 함수 사용(부분 포함 함수)

  Partial prompt templates또 다른 일반적인 용도는 부분 서식 지정 기능을 사용하는 것입니다. 이는 항상 일반적인 방식으로 액세스하려는 변수가 있는 경우 수행됩니다.

  전형적인 예는 날짜나 시간을 가져오는 것입니다. 항상 현재 날짜를 포함하려는 프롬프트 템플릿이 있다고 가정하면 템플릿에 날짜를 하드코딩할 수도 없고 매번 다른 입력 변수와 함께 날짜를 전달하는 것도 편리하지 않습니다. 이 경우 함수 부분을 사용하여 프롬프트 템플릿의 형식을 지정하는 것이 매우 편리하며 현재 날짜와 시간을 반환하는 함수를 쉽게 작성할 수 있습니다.

from datetime import datetime

def _get_datetime():
    now = datetime.now()
    return now.strftime("%m/%d/%Y, %H:%M:%S")
prompt = PromptTemplate(
    template="Tell me a {adjective} joke about the day {date}",
    input_variables=["adjective", "date"]
);
partial_prompt = prompt.partial(date=_get_datetime)
print(partial_prompt.format(adjective="funny"))
Tell me a funny joke about the day 02/27/2023, 22:15:16

또한 이 워크플로에 더 적합한 부분 변수 초기화 힌트를 사용할 수도 있습니다.

prompt = PromptTemplate(
    template="Tell me a {adjective} joke about the day {date}",
    input_variables=["adjective"],
    partial_variables={
    
    "date": _get_datetime}
);
print(prompt.format(adjective="funny"))
Tell me a funny joke about the day 02/27/2023, 22:15:16

  사용 _get_datetime 이 명명 방법은 Python의 개인 함수에 대한 일반적인 규칙 및 사양을 따릅니다. 일반적으로 외부 인터페이스가 아닌 클래스나 모듈 내부에 정의되며 일반적으로 구현에 사용됩니다. . 클래스나 모듈 내부의 일부 로직이 보조 역할을 합니다.

2, 신속한 파이프라이닝

参考 《신속한 파이프라인 》

  ˆ 프롬프트의 다양한 부분을 쉽게 결합할 수 있는 사용자 친화적인 인터페이스를 제공하도록 설계된 프롬프트 파이프라이닝 기술. 이 기술은 문자열 프롬프트와 채팅 프롬프트를 처리하는 데 사용할 수 있습니다.

2.1 문자열 프롬프트 파이프라이닝

  문자열 프롬프트를 사용하는 경우 프롬프트 또는 문자열을 직접 사용하여 프롬프트 템플릿을 결합할 수 있습니다(목록의 첫 번째 요소는 프롬프트여야 함).

from langchain.prompts import PromptTemplate

prompt = (
    PromptTemplate.from_template("Tell me a joke about {topic}")
    + ", make it funny"
    + "\n\nand in {language}"
)
prompt
PromptTemplate(input_variables=['language', 'topic'], output_parser=None, partial_variables={}, template='Tell me a joke about {topic}, make it funny\n\nand in {language}', template_format='f-string', validate_template=True)
prompt.format(topic="sports", language="spanish")
'Tell me a joke about sports, make it funny\n\nand in spanish'

이전과 마찬가지로 LLMChain에서도 사용할 수 있습니다.

from langchain.chains import LLMChain
from langchain.chat_models import ChatOpenAI

model = ChatOpenAI()
chain = LLMChain(llm=model, prompt=prompt)
chain.run(topic="sports", language="spanish")
'¿Por qué el futbolista llevaba un paraguas al partido?\n\nPorque pronosticaban lluvia de goles.'

2.2 채팅 프롬프트 파이프라인

  채팅 프롬프트는 메시지 목록으로 구성되므로 채팅 프롬프트를 결합하는 편리한 방법은 채팅 프롬프트 파이프라인에 새 메시지를 추가하는 것입니다. 이 접근 방식을 사용하면 개발자가 완전한 대화 프롬프트를 형성하기 위해 새 메시지를 점진적으로 추가하기만 하면 되므로 채팅 대화 구축이 더욱 직관적이고 편리해집니다.

  일반적으로 시스템 메시지로 기본 ChatPromptTemplate을 먼저 초기화한 다음 새 메시지를 하나씩 추가합니다. 형식을 지정해야 하는 변수가 없으면 메시지를 사용할 수 있습니다. 그리고 형식을 지정해야 하는 변수가 있는 경우 MessageTemplate을 사용할 수 있습니다. 또는 문자열을 직접 사용할 수 있으며 이는 자동으로 HumanMessagePromptTemplate으로 유추됩니다.

from langchain.schema import AIMessage, HumanMessage, SystemMessage

prompt = SystemMessage(content="You are a nice pirate")

new_prompt = (
    prompt + HumanMessage(content="hi") + AIMessage(content="what?") + "{input}"
)

내부적으로는 ChatPromptTemplate 클래스의 인스턴스가 생성되므로 이전과 같이 사용할 수 있습니다.

new_prompt.format_messages(input="i said hi")
[SystemMessage(content='You are a nice pirate', additional_kwargs={}),
 HumanMessage(content='hi', additional_kwargs={}, example=False),
 AIMessage(content='what?', additional_kwargs={}, example=False),
 HumanMessage(content='i said hi', additional_kwargs={}, example=False)]

이전과 마찬가지로 LLMChain에서도 사용할 수 있습니다.

from langchain.chains import LLMChain
from langchain.chat_models import ChatOpenAI

model = ChatOpenAI()
chain = LLMChain(llm=model, prompt=new_prompt)
chain.run("i said hi")
'Oh, hello! How can I assist you today?'

3. PipelinePrompt를 사용하여 여러 파이프라인 프롬프트 결합

参考 《구성》

  여러 프롬프트는 PipelinePrompt를 통해 그룹화할 수 있으며, 이는 프롬프트의 일부를 재사용하려는 경우에 유용합니다. PipelinePrompt는 두 가지 주요 부분으로 구성됩니다.

  • Final prompt: 반환된 최종 프롬프트(예: 다음 예의 full_prompt;)
  • Pipeline prompts: 예제의 input_prompts과 같은 튜플 목록(문자열 이름, 프롬프트 템플릿)입니다. 각 프롬프트 템플릿의 형식이 지정된 다음 동일한 이름을 가진 변수로 향후 프롬프트 템플릿에 전달됩니다.

다음 예에서는 먼저 최종 프롬프트를 만듭니다.

from langchain.prompts.pipeline import PipelinePromptTemplate
from langchain.prompts.prompt import PromptTemplate

full_template = """{introduction}

{example}

{start}"""
full_prompt = PromptTemplate.from_template(full_template)

그런 다음 각각 세 개의 파이프라인 프롬프트를 만듭니다.

introduction_template = """You are impersonating {person}."""
introduction_prompt = PromptTemplate.from_template(introduction_template)
example_template = """Here's an example of an interaction:

Q: {example_q}
A: {example_a}"""
example_prompt = PromptTemplate.from_template(example_template)
start_template = """Now, do this for real!

Q: {input}
A:"""
start_prompt = PromptTemplate.from_template(start_template)

PipelinePromptTemplate을 사용하여 모든 프롬프트 템플릿을 결합합니다.

input_prompts = [
    ("introduction", introduction_prompt),
    ("example", example_prompt),
    ("start", start_prompt)
]
pipeline_prompt = PipelinePromptTemplate(final_prompt=full_prompt, pipeline_prompts=input_prompts)
pipeline_prompt.input_variables
['example_a', 'person', 'example_q', 'input']

이 파이프라인_프롬프트를 사용하세요.

print(pipeline_prompt.format(
    person="Elon Musk",
    example_q="What's your favorite car?",
    example_a="Tesla",
    input="What's your favorite social media site?"
))
You are impersonating Elon Musk.
Here's an example of an interaction:

Q: What's your favorite car?
A: Tesla
Now, do this for real!

Q: What's your favorite social media site?
A:

4. 저장 및 로딩 프롬프트

参考 《신속한 파이프라이닝》

  일반적으로 프롬프트를 Python 코드로 저장하는 것이 아니라 파일로 저장하는 것이 가장 좋습니다. 그러면 프롬프트의 관리, 공유, 버전 제어가 용이합니다. LangChain은 이를 달성하기 위해 강력한 프롬프트 직렬화 기능을 제공합니다.

  • LangChain은 JSON 및 YAML 직렬화 형식을 모두 지원합니다. JSON 및 YAML 형식은 디스크에서 사람이 읽을 수 있으며 매우 널리 사용되며 일반적으로 프롬프트를 저장하는 데 사용됩니다. 예제와 같은 다른 리소스의 경우 다양한 직렬화 방법이 지원될 수 있습니다.

  • LangChain은 단일 파일 저장과 다중 파일 저장을 지원합니다. 하나의 파일에 모든 것을 지정하거나 다른 파일에 다른 구성 요소를 저장하고 참조할 수 있습니다. 어떤 경우에는 모든 것을 단일 파일에 저장하는 것이 가장 적합할 수 있지만 다른 경우에는 특정 리소스(예: 긴 템플릿, 대규모 샘플, 재사용 가능한 구성 요소)를 분할하는 것이 더 나을 수 있습니다.

  • load_prompt: 모든 프롬프트는 간단하고 빠른 load_prompt를 통해 로드할 수 있습니다.

4.1 프롬프트 템플릿

먼저 PromptTemplate의 save 메소드를 사용하여 저장할 수 있습니다.

from langchain.prompts import PromptTemplate

prompt = (
    PromptTemplate.from_template("Tell me a joke about {topic}")
    + ", make it funny"
    + "\n\nand in {language}"
)

prompt.save("prompt.yaml")
cat prompt.yaml
_type: prompt
input_types: {}
input_variables:
- language
- topic
output_parser: null
partial_variables: {}
template: 'Tell me a joke about {topic}, make it funny


  and in {language}'
template_format: f-string
validate_template: false

  ChatPromptTemplate을 저장하기 위해 save 메소드를 사용하면 ChatPromptTemplate 오류가 보고되는데 아직 이 기능이 구현되지 않은 상태여야 합니다(0.0344 버전 기준).

4.1.1 YAML에서 로딩

노트북에 simple_prompt.yaml 파일을 만듭니다.

%%writefile simple_prompt.yaml
_type: prompt
input_variables:
    - adjective
    - content
template: Tell me a {
    
    adjective} joke about {
    
    content}.
cat simple_prompt.yaml
_type: prompt
input_variables:
    - adjective
    - content
template: Tell me a {adjective} joke about {content}.

이 yaml 파일을 로드합니다.

prompt = load_prompt("simple_prompt.yaml")
print(prompt.format(adjective="funny", content="chickens"))
Tell me a funny joke about chickens.
4.1.2 JSON에서 로딩
%%writefile simple_prompt.json

{
    
    
    "_type": "prompt",
    "input_variables": ["adjective", "content"],
    "template": "Tell me a {adjective} joke about {content}."
}
prompt = load_prompt("simple_prompt.json")
print(prompt.format(adjective="funny", content="chickens"))
Tell me a funny joke about chickens.
4.1.3 다중 파일 로딩

다음은 템플릿을 별도의 파일에 저장한 후 구성에서 참조하는 예를 보여줍니다.

%%writefile simple_template.txt

Tell me a {
    
    adjective} joke about {
    
    content}.
%%writefile simple_prompt_with_template_file.json

{
    
    
    "_type": "prompt",
    "input_variables": ["adjective", "content"],
    "template_path": "simple_template.txt"
}
prompt = load_prompt("simple_prompt_with_template_file.json")
print(prompt.format(adjective="funny", content="chickens"))
Tell me a funny joke about chickens.

4.2 FewShotPromptTemplate

4.2.1 예제가 포함된 단일 파일 로딩 프롬프트

전체 프롬프트 템플릿을 파일에 저장할 수 있습니다. 예를 들면 다음과 같습니다.

cat few_shot_prompt_examples_in.json
{
    "_type": "few_shot",
    "input_variables": ["adjective"],
    "prefix": "Write antonyms for the following words.",
    "example_prompt": {
        "_type": "prompt",
        "input_variables": ["input", "output"],
        "template": "Input: {input}\nOutput: {output}"
    },
    "examples": [
        {"input": "happy", "output": "sad"},
        {"input": "tall", "output": "short"}
    ],
    "suffix": "Input: {adjective}\nOutput:"
}   
prompt = load_prompt("few_shot_prompt_examples_in.json")
print(prompt.format(adjective="funny"))						
Write antonyms for the following words.

Input: happy
Output: sad

Input: tall
Output: short

Input: funny
Output:
4.2.2 다중 파일 저장

YAML 또는 JSON을 사용하여 특정 예제를 저장하는 것부터 시작하세요.

cat examples.json
[
    {"input": "happy", "output": "sad"},
    {"input": "tall", "output": "short"}
]
cat examples.yaml
- input: happy
  output: sad
- input: tall
  output: short
4.2.2.1 YAML을 사용한 로딩 예시
cat few_shot_prompt.yaml
_type: few_shot
input_variables:
    ["adjective"]
prefix: 
    Write antonyms for the following words.
example_prompt:
    _type: prompt
    input_variables:
        ["input", "output"]
    template:
        "Input: {input}\nOutput: {output}"
examples:
    examples.json
suffix:
    "Input: {adjective}\nOutput:"
prompt = load_prompt("few_shot_prompt.yaml")
print(prompt.format(adjective="funny"))
Write antonyms for the following words.

Input: happy
Output: sad

Input: tall
Output: short

Input: funny
Output:

  위의 few_shot_prompt.yaml에서 examples:examples.jsonexamples:examples.yaml으로 변경할 수도 있으며 결과는 같습니다.

4.2.2.2 JSON에서 로딩 예
cat few_shot_prompt.json
{
    "_type": "few_shot",
    "input_variables": ["adjective"],
    "prefix": "Write antonyms for the following words.",
    "example_prompt": {
        "_type": "prompt",
        "input_variables": ["input", "output"],
        "template": "Input: {input}\nOutput: {output}"
    },
    "examples": "examples.json",
    "suffix": "Input: {adjective}\nOutput:"
}   
prompt = load_prompt("few_shot_prompt.json")
print(prompt.format(adjective="funny"))
Write antonyms for the following words.

Input: happy
Output: sad

Input: tall
Output: short

Input: funny
Output:
4.2.2.3 단일 파일 로딩

  위 두 예시에서는 참고용으로 예시만 별도로 JSON 또는 YAML 파일로 작성하고, example_prompt(PromptTemplate)를 별도의 파일에 넣어도 되므로 FewShotPromptTemplate 전체가 3개의 파일에 저장됩니다.

새 example_prompt.json 만들기

cat example_prompt.json
{
    "_type": "prompt",
    "input_variables": ["input", "output"],
    "template": "Input: {input}\nOutput: {output}" 
}

FewShotPromptTemplate 구성:

cat few_shot_prompt_example_prompt.json
{
    "_type": "few_shot",
    "input_variables": ["adjective"],
    "prefix": "Write antonyms for the following words.",
    "example_prompt_path": "example_prompt.json",
    "examples": "examples.json",
    "suffix": "Input: {adjective}\nOutput:"
}   
prompt = load_prompt("few_shot_prompt_example_prompt.json")
print(prompt.format(adjective="funny"))							# 结果是一样的

4.3 OutputParser가 포함된 PromptTemplate

다음은 파일에서 OutputParser를 사용하여 PromptTemplate을 로드하는 방법을 보여줍니다.

cat prompt_with_output_parser.json
{
    "input_variables": [
        "question",
        "student_answer"
    ],
    "output_parser": {
        "regex": "(.*?)\\nScore: (.*)",
        "output_keys": [
            "answer",
            "score"
        ],
        "default_output_key": null,
        "_type": "regex_parser"
    },
    "partial_variables": {},
    "template": "Given the following question and student answer, provide a correct answer and score the student answer.\nQuestion: {question}\nStudent Answer: {student_answer}\nCorrect Answer:",
    "template_format": "f-string",
    "validate_template": true,
    "_type": "prompt"
}
prompt = load_prompt("prompt_with_output_parser.json")
prompt.output_parser.parse(
    "George Washington was born in 1732 and died in 1799.\nScore: 1/2"
)
{'answer': 'George Washington was born in 1732 and died in 1799.',
 'score': '1/2'}

Guess you like

Origin blog.csdn.net/qq_56591814/article/details/134736463