mirror of
https://github.com/deepset-ai/haystack.git
synced 2025-08-27 01:46:33 +00:00
Update prompt builders examples (#6681)
This commit is contained in:
parent
d61ac9e6ae
commit
1336456b4f
@ -26,13 +26,13 @@ class DynamicChatPromptBuilder:
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
from haystack.components.builders import DynamicChatPromptBuilder
|
from haystack.components.builders import DynamicChatPromptBuilder
|
||||||
from haystack.components.generators.chat import GPTChatGenerator
|
from haystack.components.generators.chat import OpenAIChatGenerator
|
||||||
from haystack.dataclasses import ChatMessage
|
from haystack.dataclasses import ChatMessage
|
||||||
from haystack import Pipeline
|
from haystack import Pipeline
|
||||||
|
|
||||||
# no parameter init, we don't use any runtime template variables
|
# no parameter init, we don't use any runtime template variables
|
||||||
prompt_builder = DynamicChatPromptBuilder()
|
prompt_builder = DynamicChatPromptBuilder()
|
||||||
llm = GPTChatGenerator(api_key="<your-api-key>", model_name="gpt-3.5-turbo")
|
llm = OpenAIChatGenerator(api_key="<your-api-key>", model_name="gpt-3.5-turbo")
|
||||||
|
|
||||||
pipe = Pipeline()
|
pipe = Pipeline()
|
||||||
pipe.add_component("prompt_builder", prompt_builder)
|
pipe.add_component("prompt_builder", prompt_builder)
|
||||||
@ -66,7 +66,6 @@ class DynamicChatPromptBuilder:
|
|||||||
closer to your visit.", role=<ChatRole.ASSISTANT: 'assistant'>, name=None, meta={'model': 'gpt-3.5-turbo-0613',
|
closer to your visit.", role=<ChatRole.ASSISTANT: 'assistant'>, name=None, meta={'model': 'gpt-3.5-turbo-0613',
|
||||||
'index': 0, 'finish_reason': 'stop', 'usage': {'prompt_tokens': 37, 'completion_tokens': 201,
|
'index': 0, 'finish_reason': 'stop', 'usage': {'prompt_tokens': 37, 'completion_tokens': 201,
|
||||||
'total_tokens': 238}})]}}
|
'total_tokens': 238}})]}}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The primary advantage of using DynamicChatPromptBuilder is showcased in the examples provided above.
|
The primary advantage of using DynamicChatPromptBuilder is showcased in the examples provided above.
|
||||||
@ -75,10 +74,9 @@ class DynamicChatPromptBuilder:
|
|||||||
|
|
||||||
In the example above, the first query asks for general information about Berlin, and the second query requests
|
In the example above, the first query asks for general information about Berlin, and the second query requests
|
||||||
the weather forecast for Berlin in the next few days. DynamicChatPromptBuilder efficiently handles these distinct
|
the weather forecast for Berlin in the next few days. DynamicChatPromptBuilder efficiently handles these distinct
|
||||||
prompt structures by adjusting pipeline run parameters invocations, as opposed to a
|
prompt structures by adjusting pipeline run parameters invocations, as opposed to a regular PromptBuilder, which
|
||||||
regular PromptBuilder, which would require recreating or reloading the pipeline for each distinct type of query,
|
would require recreating or reloading the pipeline for each distinct type of query, leading to inefficiency and
|
||||||
leading to inefficiency and potential service disruptions, especially in server environments where continuous
|
potential service disruptions, especially in server environments where continuous service is vital.
|
||||||
service is vital.
|
|
||||||
|
|
||||||
Note that the weather forecast in the example above is fictional, but it can be easily connected to a weather
|
Note that the weather forecast in the example above is fictional, but it can be easily connected to a weather
|
||||||
API to provide real weather forecasts.
|
API to provide real weather forecasts.
|
||||||
|
@ -17,22 +17,21 @@ class DynamicPromptBuilder:
|
|||||||
The following example demonstrates how to use the DynamicPromptBuilder:
|
The following example demonstrates how to use the DynamicPromptBuilder:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
from typing import List
|
||||||
from haystack.components.builders import DynamicPromptBuilder
|
from haystack.components.builders import DynamicPromptBuilder
|
||||||
from haystack.components.generators.chat import GPTChatGenerator
|
from haystack.components.generators import OpenAIGenerator
|
||||||
from haystack.dataclasses import ChatMessage
|
from haystack import Pipeline, component, Document
|
||||||
from haystack import Pipeline
|
|
||||||
|
|
||||||
|
|
||||||
prompt_builder = DynamicPromptBuilder(runtime_variables=["documents"])
|
prompt_builder = DynamicPromptBuilder(runtime_variables=["documents"])
|
||||||
llm = GPTGenerator(api_key="<your-api-key>", model_name="gpt-3.5-turbo")
|
llm = OpenAIGenerator(api_key="<your-api-key>", model_name="gpt-3.5-turbo")
|
||||||
|
|
||||||
|
|
||||||
@component
|
@component
|
||||||
class DocumentProducer:
|
class DocumentProducer:
|
||||||
|
|
||||||
@component.output_types(documents=List[Document])
|
@component.output_types(documents=List[Document])
|
||||||
def run(self, doc_input: str):
|
def run(self, doc_input: str):
|
||||||
return {"documents": [Document(content=doc_input)]}
|
return {"documents": [Document(content=doc_input)]}
|
||||||
|
|
||||||
|
|
||||||
pipe = Pipeline()
|
pipe = Pipeline()
|
||||||
@ -43,9 +42,16 @@ class DynamicPromptBuilder:
|
|||||||
pipe.connect("prompt_builder.prompt", "llm.prompt")
|
pipe.connect("prompt_builder.prompt", "llm.prompt")
|
||||||
|
|
||||||
template = "Here is the document: {{documents[0].content}} \\n Answer: {{query}}"
|
template = "Here is the document: {{documents[0].content}} \\n Answer: {{query}}"
|
||||||
pipe.run(data={"doc_producer": {"doc_input": "Hello world, I live in Berlin"},
|
result = pipe.run(
|
||||||
"prompt_builder": {"prompt_source": template,
|
data={
|
||||||
"template_variables":{"query": "Where does the speaker live?"}}})
|
"doc_producer": {"doc_input": "Hello world, I live in Berlin"},
|
||||||
|
"prompt_builder": {
|
||||||
|
"prompt_source": template,
|
||||||
|
"template_variables": {"query": "Where does the speaker live?"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
print(result)
|
||||||
|
|
||||||
>> {'llm': {'replies': ['The speaker lives in Berlin.'],
|
>> {'llm': {'replies': ['The speaker lives in Berlin.'],
|
||||||
>> 'meta': [{'model': 'gpt-3.5-turbo-0613',
|
>> 'meta': [{'model': 'gpt-3.5-turbo-0613',
|
||||||
@ -118,8 +124,8 @@ class DynamicPromptBuilder:
|
|||||||
"Please provide an appropriate template variable to enable prompt generation."
|
"Please provide an appropriate template variable to enable prompt generation."
|
||||||
)
|
)
|
||||||
|
|
||||||
template = self._validate_template(prompt_source, set(template_variables.keys()))
|
template = self._validate_template(prompt_source, set(template_variables_combined.keys()))
|
||||||
result = template.render(template_variables)
|
result = template.render(template_variables_combined)
|
||||||
return {"prompt": result}
|
return {"prompt": result}
|
||||||
|
|
||||||
def _validate_template(self, template_text: str, provided_variables: Set[str]):
|
def _validate_template(self, template_text: str, provided_variables: Set[str]):
|
||||||
|
@ -2,6 +2,7 @@ from typing import List
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from haystack import Pipeline
|
||||||
from haystack.components.builders import DynamicChatPromptBuilder
|
from haystack.components.builders import DynamicChatPromptBuilder
|
||||||
from haystack.dataclasses import ChatMessage
|
from haystack.dataclasses import ChatMessage
|
||||||
|
|
||||||
@ -90,3 +91,50 @@ class TestDynamicChatPromptBuilder:
|
|||||||
|
|
||||||
# provided variables are a superset of the required variables
|
# provided variables are a superset of the required variables
|
||||||
prompt_builder._validate_template("Hello, I'm {{ name }}, and I live in {{ city }}.", {"name", "city", "age"})
|
prompt_builder._validate_template("Hello, I'm {{ name }}, and I live in {{ city }}.", {"name", "city", "age"})
|
||||||
|
|
||||||
|
def test_example_in_pipeline(self):
|
||||||
|
# no parameter init, we don't use any runtime template variables
|
||||||
|
prompt_builder = DynamicChatPromptBuilder()
|
||||||
|
|
||||||
|
pipe = Pipeline()
|
||||||
|
pipe.add_component("prompt_builder", prompt_builder)
|
||||||
|
|
||||||
|
location = "Berlin"
|
||||||
|
system_message = ChatMessage.from_system(
|
||||||
|
"You are a helpful assistant giving out valuable information to tourists."
|
||||||
|
)
|
||||||
|
messages = [system_message, ChatMessage.from_user("Tell me about {{location}}")]
|
||||||
|
|
||||||
|
res = pipe.run(
|
||||||
|
data={"prompt_builder": {"template_variables": {"location": location}, "prompt_source": messages}}
|
||||||
|
)
|
||||||
|
assert res == {
|
||||||
|
"prompt_builder": {
|
||||||
|
"prompt": [
|
||||||
|
ChatMessage.from_system("You are a helpful assistant giving out valuable information to tourists."),
|
||||||
|
ChatMessage.from_user("Tell me about Berlin"),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
messages = [
|
||||||
|
system_message,
|
||||||
|
ChatMessage.from_user("What's the weather forecast for {{location}} in the next {{day_count}} days?"),
|
||||||
|
]
|
||||||
|
|
||||||
|
res = pipe.run(
|
||||||
|
data={
|
||||||
|
"prompt_builder": {
|
||||||
|
"template_variables": {"location": location, "day_count": "5"},
|
||||||
|
"prompt_source": messages,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
assert res == {
|
||||||
|
"prompt_builder": {
|
||||||
|
"prompt": [
|
||||||
|
ChatMessage.from_system("You are a helpful assistant giving out valuable information to tourists."),
|
||||||
|
ChatMessage.from_user("What's the weather forecast for Berlin in the next 5 days?"),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
|
from typing import List
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from jinja2 import TemplateSyntaxError
|
from jinja2 import TemplateSyntaxError
|
||||||
|
|
||||||
|
from haystack import component, Document, Pipeline
|
||||||
from haystack.components.builders import DynamicPromptBuilder
|
from haystack.components.builders import DynamicPromptBuilder
|
||||||
|
|
||||||
|
|
||||||
@ -74,3 +77,34 @@ class TestDynamicPromptBuilder:
|
|||||||
|
|
||||||
# provided variables are a superset of the required variables
|
# provided variables are a superset of the required variables
|
||||||
prompt_builder._validate_template("Hello, I'm {{ name }}, and I live in {{ city }}.", {"name", "city", "age"})
|
prompt_builder._validate_template("Hello, I'm {{ name }}, and I live in {{ city }}.", {"name", "city", "age"})
|
||||||
|
|
||||||
|
def test_example_in_pipeline(self):
|
||||||
|
prompt_builder = DynamicPromptBuilder(runtime_variables=["documents"])
|
||||||
|
|
||||||
|
@component
|
||||||
|
class DocumentProducer:
|
||||||
|
@component.output_types(documents=List[Document])
|
||||||
|
def run(self, doc_input: str):
|
||||||
|
return {"documents": [Document(content=doc_input)]}
|
||||||
|
|
||||||
|
pipe = Pipeline()
|
||||||
|
pipe.add_component("doc_producer", DocumentProducer())
|
||||||
|
pipe.add_component("prompt_builder", prompt_builder)
|
||||||
|
pipe.connect("doc_producer.documents", "prompt_builder.documents")
|
||||||
|
|
||||||
|
template = "Here is the document: {{documents[0].content}} \\n Answer: {{query}}"
|
||||||
|
result = pipe.run(
|
||||||
|
data={
|
||||||
|
"doc_producer": {"doc_input": "Hello world, I live in Berlin"},
|
||||||
|
"prompt_builder": {
|
||||||
|
"prompt_source": template,
|
||||||
|
"template_variables": {"query": "Where does the speaker live?"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result == {
|
||||||
|
"prompt_builder": {
|
||||||
|
"prompt": "Here is the document: Hello world, I live in Berlin \\n Answer: Where does the speaker live?"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user