mirror of
https://github.com/BerriAI/litellm.git
synced 2025-04-26 03:04:13 +00:00
add everyting for docs
This commit is contained in:
parent
de45a738ee
commit
0fe8799f94
1015 changed files with 185353 additions and 0 deletions
120
docs/snippets/modules/model_io/models/chat/get_started.mdx
Normal file
120
docs/snippets/modules/model_io/models/chat/get_started.mdx
Normal file
|
@ -0,0 +1,120 @@
|
|||
### Setup
|
||||
|
||||
To start we'll need to install the OpenAI Python package:
|
||||
|
||||
```bash
|
||||
pip install openai
|
||||
```
|
||||
|
||||
Accessing the API requires an API key, which you can get by creating an account and heading [here](https://platform.openai.com/account/api-keys). Once we have a key we'll want to set it as an environment variable by running:
|
||||
|
||||
```bash
|
||||
export OPENAI_API_KEY="..."
|
||||
```
|
||||
If you'd prefer not to set an environment variable you can pass the key in directly via the `openai_api_key` named parameter when initiating the OpenAI LLM class:
|
||||
|
||||
```python
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
|
||||
chat = ChatOpenAI(openai_api_key="...")
|
||||
```
|
||||
|
||||
otherwise you can initialize without any params:
|
||||
```python
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
|
||||
chat = ChatOpenAI()
|
||||
```
|
||||
|
||||
### Messages
|
||||
|
||||
The chat model interface is based around messages rather than raw text.
|
||||
The types of messages currently supported in LangChain are `AIMessage`, `HumanMessage`, `SystemMessage`, and `ChatMessage` -- `ChatMessage` takes in an arbitrary role parameter. Most of the time, you'll just be dealing with `HumanMessage`, `AIMessage`, and `SystemMessage`
|
||||
|
||||
### `__call__`
|
||||
#### Messages in -> message out
|
||||
|
||||
You can get chat completions by passing one or more messages to the chat model. The response will be a message.
|
||||
|
||||
```python
|
||||
from langchain.schema import (
|
||||
AIMessage,
|
||||
HumanMessage,
|
||||
SystemMessage
|
||||
)
|
||||
|
||||
chat([HumanMessage(content="Translate this sentence from English to French: I love programming.")])
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
AIMessage(content="J'aime programmer.", additional_kwargs={})
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
OpenAI's chat model supports multiple messages as input. See [here](https://platform.openai.com/docs/guides/chat/chat-vs-completions) for more information. Here is an example of sending a system and user message to the chat model:
|
||||
|
||||
|
||||
```python
|
||||
messages = [
|
||||
SystemMessage(content="You are a helpful assistant that translates English to French."),
|
||||
HumanMessage(content="I love programming.")
|
||||
]
|
||||
chat(messages)
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
AIMessage(content="J'aime programmer.", additional_kwargs={})
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
### `generate`
|
||||
#### Batch calls, richer outputs
|
||||
|
||||
You can go one step further and generate completions for multiple sets of messages using `generate`. This returns an `LLMResult` with an additional `message` parameter.
|
||||
|
||||
```python
|
||||
batch_messages = [
|
||||
[
|
||||
SystemMessage(content="You are a helpful assistant that translates English to French."),
|
||||
HumanMessage(content="I love programming.")
|
||||
],
|
||||
[
|
||||
SystemMessage(content="You are a helpful assistant that translates English to French."),
|
||||
HumanMessage(content="I love artificial intelligence.")
|
||||
],
|
||||
]
|
||||
result = chat.generate(batch_messages)
|
||||
result
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
LLMResult(generations=[[ChatGeneration(text="J'aime programmer.", generation_info=None, message=AIMessage(content="J'aime programmer.", additional_kwargs={}))], [ChatGeneration(text="J'aime l'intelligence artificielle.", generation_info=None, message=AIMessage(content="J'aime l'intelligence artificielle.", additional_kwargs={}))]], llm_output={'token_usage': {'prompt_tokens': 57, 'completion_tokens': 20, 'total_tokens': 77}})
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
You can recover things like token usage from this LLMResult
|
||||
|
||||
|
||||
```python
|
||||
result.llm_output
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
{'token_usage': {'prompt_tokens': 57,
|
||||
'completion_tokens': 20,
|
||||
'total_tokens': 77}}
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
```python
|
||||
import langchain
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
|
||||
llm = ChatOpenAI()
|
||||
```
|
||||
|
||||
## In Memory Cache
|
||||
|
||||
|
||||
```python
|
||||
from langchain.cache import InMemoryCache
|
||||
langchain.llm_cache = InMemoryCache()
|
||||
|
||||
# The first time, it is not yet in cache, so it should take longer
|
||||
llm.predict("Tell me a joke")
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
CPU times: user 35.9 ms, sys: 28.6 ms, total: 64.6 ms
|
||||
Wall time: 4.83 s
|
||||
|
||||
|
||||
"\n\nWhy couldn't the bicycle stand up by itself? It was...two tired!"
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
|
||||
```python
|
||||
# The second time it is, so it goes faster
|
||||
llm.predict("Tell me a joke")
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
CPU times: user 238 µs, sys: 143 µs, total: 381 µs
|
||||
Wall time: 1.76 ms
|
||||
|
||||
|
||||
'\n\nWhy did the chicken cross the road?\n\nTo get to the other side.'
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
## SQLite Cache
|
||||
|
||||
|
||||
```bash
|
||||
rm .langchain.db
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
# We can do the same thing with a SQLite cache
|
||||
from langchain.cache import SQLiteCache
|
||||
langchain.llm_cache = SQLiteCache(database_path=".langchain.db")
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
# The first time, it is not yet in cache, so it should take longer
|
||||
llm.predict("Tell me a joke")
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
CPU times: user 17 ms, sys: 9.76 ms, total: 26.7 ms
|
||||
Wall time: 825 ms
|
||||
|
||||
|
||||
'\n\nWhy did the chicken cross the road?\n\nTo get to the other side.'
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
|
||||
```python
|
||||
# The second time it is, so it goes faster
|
||||
llm.predict("Tell me a joke")
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
CPU times: user 2.46 ms, sys: 1.23 ms, total: 3.7 ms
|
||||
Wall time: 2.67 ms
|
||||
|
||||
|
||||
'\n\nWhy did the chicken cross the road?\n\nTo get to the other side.'
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
|
@ -0,0 +1,16 @@
|
|||
```python
|
||||
chain = LLMChain(llm=chat, prompt=chat_prompt)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
chain.run(input_language="English", output_language="French", text="I love programming.")
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
"J'adore la programmation."
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
|
@ -0,0 +1,47 @@
|
|||
You can make use of templating by using a `MessagePromptTemplate`. You can build a `ChatPromptTemplate` from one or more `MessagePromptTemplates`. You can use `ChatPromptTemplate`'s `format_prompt` -- this returns a `PromptValue`, which you can convert to a string or Message object, depending on whether you want to use the formatted value as input to an llm or chat model.
|
||||
|
||||
For convenience, there is a `from_template` method exposed on the template. If you were to use this template, this is what it would look like:
|
||||
|
||||
|
||||
```python
|
||||
from langchain import PromptTemplate
|
||||
from langchain.prompts.chat import (
|
||||
ChatPromptTemplate,
|
||||
SystemMessagePromptTemplate,
|
||||
AIMessagePromptTemplate,
|
||||
HumanMessagePromptTemplate,
|
||||
)
|
||||
|
||||
template="You are a helpful assistant that translates {input_language} to {output_language}."
|
||||
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
|
||||
human_template="{text}"
|
||||
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
|
||||
|
||||
# get a chat completion from the formatted messages
|
||||
chat(chat_prompt.format_prompt(input_language="English", output_language="French", text="I love programming.").to_messages())
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
AIMessage(content="J'adore la programmation.", additional_kwargs={})
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
If you wanted to construct the MessagePromptTemplate more directly, you could create a PromptTemplate outside and then pass it in, eg:
|
||||
|
||||
|
||||
```python
|
||||
prompt=PromptTemplate(
|
||||
template="You are a helpful assistant that translates {input_language} to {output_language}.",
|
||||
input_variables=["input_language", "output_language"],
|
||||
)
|
||||
system_message_prompt = SystemMessagePromptTemplate(prompt=prompt)
|
||||
```
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
```python
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
from langchain.schema import (
|
||||
HumanMessage,
|
||||
)
|
||||
|
||||
|
||||
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
|
||||
chat = ChatOpenAI(streaming=True, callbacks=[StreamingStdOutCallbackHandler()], temperature=0)
|
||||
resp = chat([HumanMessage(content="Write me a song about sparkling water.")])
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Verse 1:
|
||||
Bubbles rising to the top
|
||||
A refreshing drink that never stops
|
||||
Clear and crisp, it's pure delight
|
||||
A taste that's sure to excite
|
||||
|
||||
Chorus:
|
||||
Sparkling water, oh so fine
|
||||
A drink that's always on my mind
|
||||
With every sip, I feel alive
|
||||
Sparkling water, you're my vibe
|
||||
|
||||
Verse 2:
|
||||
No sugar, no calories, just pure bliss
|
||||
A drink that's hard to resist
|
||||
It's the perfect way to quench my thirst
|
||||
A drink that always comes first
|
||||
|
||||
Chorus:
|
||||
Sparkling water, oh so fine
|
||||
A drink that's always on my mind
|
||||
With every sip, I feel alive
|
||||
Sparkling water, you're my vibe
|
||||
|
||||
Bridge:
|
||||
From the mountains to the sea
|
||||
Sparkling water, you're the key
|
||||
To a healthy life, a happy soul
|
||||
A drink that makes me feel whole
|
||||
|
||||
Chorus:
|
||||
Sparkling water, oh so fine
|
||||
A drink that's always on my mind
|
||||
With every sip, I feel alive
|
||||
Sparkling water, you're my vibe
|
||||
|
||||
Outro:
|
||||
Sparkling water, you're the one
|
||||
A drink that's always so much fun
|
||||
I'll never let you go, my friend
|
||||
Sparkling
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
108
docs/snippets/modules/model_io/models/llms/get_started.mdx
Normal file
108
docs/snippets/modules/model_io/models/llms/get_started.mdx
Normal file
|
@ -0,0 +1,108 @@
|
|||
### Setup
|
||||
|
||||
To start we'll need to install the OpenAI Python package:
|
||||
|
||||
```bash
|
||||
pip install openai
|
||||
```
|
||||
|
||||
Accessing the API requires an API key, which you can get by creating an account and heading [here](https://platform.openai.com/account/api-keys). Once we have a key we'll want to set it as an environment variable by running:
|
||||
|
||||
```bash
|
||||
export OPENAI_API_KEY="..."
|
||||
```
|
||||
|
||||
If you'd prefer not to set an environment variable you can pass the key in directly via the `openai_api_key` named parameter when initiating the OpenAI LLM class:
|
||||
|
||||
```python
|
||||
from langchain.llms import OpenAI
|
||||
|
||||
llm = OpenAI(openai_api_key="...")
|
||||
```
|
||||
|
||||
otherwise you can initialize without any params:
|
||||
```python
|
||||
from langchain.llms import OpenAI
|
||||
|
||||
llm = OpenAI()
|
||||
```
|
||||
|
||||
### `__call__`: string in -> string out
|
||||
The simplest way to use an LLM is a callable: pass in a string, get a string completion.
|
||||
|
||||
```python
|
||||
llm("Tell me a joke")
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
'Why did the chicken cross the road?\n\nTo get to the other side.'
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
### `generate`: batch calls, richer outputs
|
||||
`generate` lets you can call the model with a list of strings, getting back a more complete response than just the text. This complete response can includes things like multiple top responses and other LLM provider-specific information:
|
||||
|
||||
```python
|
||||
llm_result = llm.generate(["Tell me a joke", "Tell me a poem"]*15)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
len(llm_result.generations)
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
30
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
|
||||
```python
|
||||
llm_result.generations[0]
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
[Generation(text='\n\nWhy did the chicken cross the road?\n\nTo get to the other side!'),
|
||||
Generation(text='\n\nWhy did the chicken cross the road?\n\nTo get to the other side.')]
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
|
||||
```python
|
||||
llm_result.generations[-1]
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
[Generation(text="\n\nWhat if love neverspeech\n\nWhat if love never ended\n\nWhat if love was only a feeling\n\nI'll never know this love\n\nIt's not a feeling\n\nBut it's what we have for each other\n\nWe just know that love is something strong\n\nAnd we can't help but be happy\n\nWe just feel what love is for us\n\nAnd we love each other with all our heart\n\nWe just don't know how\n\nHow it will go\n\nBut we know that love is something strong\n\nAnd we'll always have each other\n\nIn our lives."),
|
||||
Generation(text='\n\nOnce upon a time\n\nThere was a love so pure and true\n\nIt lasted for centuries\n\nAnd never became stale or dry\n\nIt was moving and alive\n\nAnd the heart of the love-ick\n\nIs still beating strong and true.')]
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
You can also access provider specific information that is returned. This information is NOT standardized across providers.
|
||||
|
||||
|
||||
```python
|
||||
llm_result.llm_output
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
{'token_usage': {'completion_tokens': 3903,
|
||||
'total_tokens': 4023,
|
||||
'prompt_tokens': 120}}
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
|
@ -0,0 +1,177 @@
|
|||
```python
|
||||
import langchain
|
||||
from langchain.llms import OpenAI
|
||||
|
||||
# To make the caching really obvious, lets use a slower model.
|
||||
llm = OpenAI(model_name="text-davinci-002", n=2, best_of=2)
|
||||
```
|
||||
|
||||
## In Memory Cache
|
||||
|
||||
|
||||
```python
|
||||
from langchain.cache import InMemoryCache
|
||||
langchain.llm_cache = InMemoryCache()
|
||||
|
||||
# The first time, it is not yet in cache, so it should take longer
|
||||
llm.predict("Tell me a joke")
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
CPU times: user 35.9 ms, sys: 28.6 ms, total: 64.6 ms
|
||||
Wall time: 4.83 s
|
||||
|
||||
|
||||
"\n\nWhy couldn't the bicycle stand up by itself? It was...two tired!"
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
|
||||
```python
|
||||
# The second time it is, so it goes faster
|
||||
llm.predict("Tell me a joke")
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
CPU times: user 238 µs, sys: 143 µs, total: 381 µs
|
||||
Wall time: 1.76 ms
|
||||
|
||||
|
||||
'\n\nWhy did the chicken cross the road?\n\nTo get to the other side.'
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
## SQLite Cache
|
||||
|
||||
|
||||
```bash
|
||||
rm .langchain.db
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
# We can do the same thing with a SQLite cache
|
||||
from langchain.cache import SQLiteCache
|
||||
langchain.llm_cache = SQLiteCache(database_path=".langchain.db")
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
# The first time, it is not yet in cache, so it should take longer
|
||||
llm.predict("Tell me a joke")
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
CPU times: user 17 ms, sys: 9.76 ms, total: 26.7 ms
|
||||
Wall time: 825 ms
|
||||
|
||||
|
||||
'\n\nWhy did the chicken cross the road?\n\nTo get to the other side.'
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
|
||||
```python
|
||||
# The second time it is, so it goes faster
|
||||
llm.predict("Tell me a joke")
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
CPU times: user 2.46 ms, sys: 1.23 ms, total: 3.7 ms
|
||||
Wall time: 2.67 ms
|
||||
|
||||
|
||||
'\n\nWhy did the chicken cross the road?\n\nTo get to the other side.'
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
## Optional Caching in Chains
|
||||
You can also turn off caching for particular nodes in chains. Note that because of certain interfaces, its often easier to construct the chain first, and then edit the LLM afterwards.
|
||||
|
||||
As an example, we will load a summarizer map-reduce chain. We will cache results for the map-step, but then not freeze it for the combine step.
|
||||
|
||||
|
||||
```python
|
||||
llm = OpenAI(model_name="text-davinci-002")
|
||||
no_cache_llm = OpenAI(model_name="text-davinci-002", cache=False)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
from langchain.text_splitter import CharacterTextSplitter
|
||||
from langchain.chains.mapreduce import MapReduceChain
|
||||
|
||||
text_splitter = CharacterTextSplitter()
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
with open('../../../state_of_the_union.txt') as f:
|
||||
state_of_the_union = f.read()
|
||||
texts = text_splitter.split_text(state_of_the_union)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
from langchain.docstore.document import Document
|
||||
docs = [Document(page_content=t) for t in texts[:3]]
|
||||
from langchain.chains.summarize import load_summarize_chain
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
chain = load_summarize_chain(llm, chain_type="map_reduce", reduce_llm=no_cache_llm)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
chain.run(docs)
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
CPU times: user 452 ms, sys: 60.3 ms, total: 512 ms
|
||||
Wall time: 5.09 s
|
||||
|
||||
|
||||
'\n\nPresident Biden is discussing the American Rescue Plan and the Bipartisan Infrastructure Law, which will create jobs and help Americans. He also talks about his vision for America, which includes investing in education and infrastructure. In response to Russian aggression in Ukraine, the United States is joining with European allies to impose sanctions and isolate Russia. American forces are being mobilized to protect NATO countries in the event that Putin decides to keep moving west. The Ukrainians are bravely fighting back, but the next few weeks will be hard for them. Putin will pay a high price for his actions in the long run. Americans should not be alarmed, as the United States is taking action to protect its interests and allies.'
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
When we run it again, we see that it runs substantially faster but the final answer is different. This is due to caching at the map steps, but not at the reduce step.
|
||||
|
||||
|
||||
```python
|
||||
chain.run(docs)
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
CPU times: user 11.5 ms, sys: 4.33 ms, total: 15.8 ms
|
||||
Wall time: 1.04 s
|
||||
|
||||
|
||||
'\n\nPresident Biden is discussing the American Rescue Plan and the Bipartisan Infrastructure Law, which will create jobs and help Americans. He also talks about his vision for America, which includes investing in education and infrastructure.'
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
|
||||
```bash
|
||||
rm .langchain.db sqlite.db
|
||||
```
|
|
@ -0,0 +1,70 @@
|
|||
Currently, we support streaming for a broad range of LLM implementations, including but not limited to `OpenAI`, `ChatOpenAI`, `ChatAnthropic`, `Hugging Face Text Generation Inference`, and `Replicate`. This feature has been expanded to accommodate most of the models. To utilize streaming, use a [`CallbackHandler`](https://github.com/hwchase17/langchain/blob/master/langchain/callbacks/base.py) that implements `on_llm_new_token`. In this example, we are using `StreamingStdOutCallbackHandler`.
|
||||
```python
|
||||
from langchain.llms import OpenAI
|
||||
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
|
||||
|
||||
|
||||
llm = OpenAI(streaming=True, callbacks=[StreamingStdOutCallbackHandler()], temperature=0)
|
||||
resp = llm("Write me a song about sparkling water.")
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Verse 1
|
||||
I'm sippin' on sparkling water,
|
||||
It's so refreshing and light,
|
||||
It's the perfect way to quench my thirst
|
||||
On a hot summer night.
|
||||
|
||||
Chorus
|
||||
Sparkling water, sparkling water,
|
||||
It's the best way to stay hydrated,
|
||||
It's so crisp and so clean,
|
||||
It's the perfect way to stay refreshed.
|
||||
|
||||
Verse 2
|
||||
I'm sippin' on sparkling water,
|
||||
It's so bubbly and bright,
|
||||
It's the perfect way to cool me down
|
||||
On a hot summer night.
|
||||
|
||||
Chorus
|
||||
Sparkling water, sparkling water,
|
||||
It's the best way to stay hydrated,
|
||||
It's so crisp and so clean,
|
||||
It's the perfect way to stay refreshed.
|
||||
|
||||
Verse 3
|
||||
I'm sippin' on sparkling water,
|
||||
It's so light and so clear,
|
||||
It's the perfect way to keep me cool
|
||||
On a hot summer night.
|
||||
|
||||
Chorus
|
||||
Sparkling water, sparkling water,
|
||||
It's the best way to stay hydrated,
|
||||
It's so crisp and so clean,
|
||||
It's the perfect way to stay refreshed.
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
We still have access to the end `LLMResult` if using `generate`. However, `token_usage` is not currently supported for streaming.
|
||||
|
||||
|
||||
```python
|
||||
llm.generate(["Tell me a joke."])
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Q: What did the fish say when it hit the wall?
|
||||
A: Dam!
|
||||
|
||||
|
||||
LLMResult(generations=[[Generation(text='\n\nQ: What did the fish say when it hit the wall?\nA: Dam!', generation_info={'finish_reason': 'stop', 'logprobs': None})]], llm_output={'token_usage': {}, 'model_name': 'text-davinci-003'})
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
|
@ -0,0 +1,46 @@
|
|||
```python
|
||||
from langchain.output_parsers import CommaSeparatedListOutputParser
|
||||
from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate
|
||||
from langchain.llms import OpenAI
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
|
||||
output_parser = CommaSeparatedListOutputParser()
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
format_instructions = output_parser.get_format_instructions()
|
||||
prompt = PromptTemplate(
|
||||
template="List five {subject}.\n{format_instructions}",
|
||||
input_variables=["subject"],
|
||||
partial_variables={"format_instructions": format_instructions}
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
model = OpenAI(temperature=0)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
_input = prompt.format(subject="ice cream flavors")
|
||||
output = model(_input)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
output_parser.parse(output)
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
['Vanilla',
|
||||
'Chocolate',
|
||||
'Strawberry',
|
||||
'Mint Chocolate Chip',
|
||||
'Cookies and Cream']
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
|
@ -0,0 +1,76 @@
|
|||
---
|
||||
sidebar_position: 2
|
||||
---
|
||||
Below we go over the main type of output parser, the `PydanticOutputParser`.
|
||||
|
||||
```python
|
||||
from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate
|
||||
from langchain.llms import OpenAI
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
|
||||
from langchain.output_parsers import PydanticOutputParser
|
||||
from pydantic import BaseModel, Field, validator
|
||||
from typing import List
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
model_name = 'text-davinci-003'
|
||||
temperature = 0.0
|
||||
model = OpenAI(model_name=model_name, temperature=temperature)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
# Define your desired data structure.
|
||||
class Joke(BaseModel):
|
||||
setup: str = Field(description="question to set up a joke")
|
||||
punchline: str = Field(description="answer to resolve the joke")
|
||||
|
||||
# You can add custom validation logic easily with Pydantic.
|
||||
@validator('setup')
|
||||
def question_ends_with_question_mark(cls, field):
|
||||
if field[-1] != '?':
|
||||
raise ValueError("Badly formed question!")
|
||||
return field
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
# Set up a parser + inject instructions into the prompt template.
|
||||
parser = PydanticOutputParser(pydantic_object=Joke)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
prompt = PromptTemplate(
|
||||
template="Answer the user query.\n{format_instructions}\n{query}\n",
|
||||
input_variables=["query"],
|
||||
partial_variables={"format_instructions": parser.get_format_instructions()}
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
# And a query intended to prompt a language model to populate the data structure.
|
||||
joke_query = "Tell me a joke."
|
||||
_input = prompt.format_prompt(query=joke_query)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
output = model(_input.to_string())
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
parser.parse(output)
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Joke(setup='Why did the chicken cross the road?', punchline='To get to the other side!')
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
|
@ -0,0 +1,112 @@
|
|||
For this example, we'll use the above Pydantic output parser. Here's what happens if we pass it a result that does not comply with the schema:
|
||||
|
||||
```python
|
||||
from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate
|
||||
from langchain.llms import OpenAI
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
from langchain.output_parsers import PydanticOutputParser
|
||||
from pydantic import BaseModel, Field, validator
|
||||
from typing import List
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
class Actor(BaseModel):
|
||||
name: str = Field(description="name of an actor")
|
||||
film_names: List[str] = Field(description="list of names of films they starred in")
|
||||
|
||||
actor_query = "Generate the filmography for a random actor."
|
||||
|
||||
parser = PydanticOutputParser(pydantic_object=Actor)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
misformatted = "{'name': 'Tom Hanks', 'film_names': ['Forrest Gump']}"
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
parser.parse(misformatted)
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
JSONDecodeError Traceback (most recent call last)
|
||||
|
||||
File ~/workplace/langchain/langchain/output_parsers/pydantic.py:23, in PydanticOutputParser.parse(self, text)
|
||||
22 json_str = match.group()
|
||||
---> 23 json_object = json.loads(json_str)
|
||||
24 return self.pydantic_object.parse_obj(json_object)
|
||||
|
||||
|
||||
File ~/.pyenv/versions/3.9.1/lib/python3.9/json/__init__.py:346, in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
|
||||
343 if (cls is None and object_hook is None and
|
||||
344 parse_int is None and parse_float is None and
|
||||
345 parse_constant is None and object_pairs_hook is None and not kw):
|
||||
--> 346 return _default_decoder.decode(s)
|
||||
347 if cls is None:
|
||||
|
||||
|
||||
File ~/.pyenv/versions/3.9.1/lib/python3.9/json/decoder.py:337, in JSONDecoder.decode(self, s, _w)
|
||||
333 """Return the Python representation of ``s`` (a ``str`` instance
|
||||
334 containing a JSON document).
|
||||
335
|
||||
336 """
|
||||
--> 337 obj, end = self.raw_decode(s, idx=_w(s, 0).end())
|
||||
338 end = _w(s, end).end()
|
||||
|
||||
|
||||
File ~/.pyenv/versions/3.9.1/lib/python3.9/json/decoder.py:353, in JSONDecoder.raw_decode(self, s, idx)
|
||||
352 try:
|
||||
--> 353 obj, end = self.scan_once(s, idx)
|
||||
354 except StopIteration as err:
|
||||
|
||||
|
||||
JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
|
||||
|
||||
|
||||
During handling of the above exception, another exception occurred:
|
||||
|
||||
|
||||
OutputParserException Traceback (most recent call last)
|
||||
|
||||
Cell In[6], line 1
|
||||
----> 1 parser.parse(misformatted)
|
||||
|
||||
|
||||
File ~/workplace/langchain/langchain/output_parsers/pydantic.py:29, in PydanticOutputParser.parse(self, text)
|
||||
27 name = self.pydantic_object.__name__
|
||||
28 msg = f"Failed to parse {name} from completion {text}. Got: {e}"
|
||||
---> 29 raise OutputParserException(msg)
|
||||
|
||||
|
||||
OutputParserException: Failed to parse Actor from completion {'name': 'Tom Hanks', 'film_names': ['Forrest Gump']}. Got: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
Now we can construct and use a `OutputFixingParser`. This output parser takes as an argument another output parser but also an LLM with which to try to correct any formatting mistakes.
|
||||
|
||||
|
||||
```python
|
||||
from langchain.output_parsers import OutputFixingParser
|
||||
|
||||
new_parser = OutputFixingParser.from_llm(parser=parser, llm=ChatOpenAI())
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
new_parser.parse(misformatted)
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Actor(name='Tom Hanks', film_names=['Forrest Gump'])
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
93
docs/snippets/modules/model_io/output_parsers/structured.mdx
Normal file
93
docs/snippets/modules/model_io/output_parsers/structured.mdx
Normal file
|
@ -0,0 +1,93 @@
|
|||
```python
|
||||
from langchain.output_parsers import StructuredOutputParser, ResponseSchema
|
||||
from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate
|
||||
from langchain.llms import OpenAI
|
||||
from langchain.chat_models import ChatOpenAI
|
||||
```
|
||||
|
||||
Here we define the response schema we want to receive.
|
||||
|
||||
|
||||
```python
|
||||
response_schemas = [
|
||||
ResponseSchema(name="answer", description="answer to the user's question"),
|
||||
ResponseSchema(name="source", description="source used to answer the user's question, should be a website.")
|
||||
]
|
||||
output_parser = StructuredOutputParser.from_response_schemas(response_schemas)
|
||||
```
|
||||
|
||||
We now get a string that contains instructions for how the response should be formatted, and we then insert that into our prompt.
|
||||
|
||||
|
||||
```python
|
||||
format_instructions = output_parser.get_format_instructions()
|
||||
prompt = PromptTemplate(
|
||||
template="answer the users question as best as possible.\n{format_instructions}\n{question}",
|
||||
input_variables=["question"],
|
||||
partial_variables={"format_instructions": format_instructions}
|
||||
)
|
||||
```
|
||||
|
||||
We can now use this to format a prompt to send to the language model, and then parse the returned result.
|
||||
|
||||
|
||||
```python
|
||||
model = OpenAI(temperature=0)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
_input = prompt.format_prompt(question="what's the capital of france?")
|
||||
output = model(_input.to_string())
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
output_parser.parse(output)
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
{'answer': 'Paris',
|
||||
'source': 'https://www.worldatlas.com/articles/what-is-the-capital-of-france.html'}
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
And here's an example of using this in a chat model
|
||||
|
||||
|
||||
```python
|
||||
chat_model = ChatOpenAI(temperature=0)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
prompt = ChatPromptTemplate(
|
||||
messages=[
|
||||
HumanMessagePromptTemplate.from_template("answer the users question as best as possible.\n{format_instructions}\n{question}")
|
||||
],
|
||||
input_variables=["question"],
|
||||
partial_variables={"format_instructions": format_instructions}
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
_input = prompt.format_prompt(question="what's the capital of france?")
|
||||
output = chat_model(_input.to_messages())
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
output_parser.parse(output.content)
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
{'answer': 'Paris', 'source': 'https://en.wikipedia.org/wiki/Paris'}
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
|
@ -0,0 +1,10 @@
|
|||
```python
|
||||
class BaseExampleSelector(ABC):
|
||||
"""Interface for selecting examples to include in prompts."""
|
||||
|
||||
@abstractmethod
|
||||
def select_examples(self, input_variables: Dict[str, str]) -> List[dict]:
|
||||
"""Select which examples to use based on the inputs."""
|
||||
```
|
||||
|
||||
The only method it needs to expose is a ``select_examples`` method. This takes in the input variables and then returns a list of examples. It is up to each specific implementation as to how those examples are selected. Let's take a look at some below.
|
|
@ -0,0 +1,130 @@
|
|||
```python
|
||||
from langchain.prompts import PromptTemplate
|
||||
from langchain.prompts import FewShotPromptTemplate
|
||||
from langchain.prompts.example_selector import LengthBasedExampleSelector
|
||||
|
||||
|
||||
# These are a lot of examples of a pretend task of creating antonyms.
|
||||
examples = [
|
||||
{"input": "happy", "output": "sad"},
|
||||
{"input": "tall", "output": "short"},
|
||||
{"input": "energetic", "output": "lethargic"},
|
||||
{"input": "sunny", "output": "gloomy"},
|
||||
{"input": "windy", "output": "calm"},
|
||||
|
||||
example_prompt = PromptTemplate(
|
||||
input_variables=["input", "output"],
|
||||
template="Input: {input}\nOutput: {output}",
|
||||
)
|
||||
example_selector = LengthBasedExampleSelector(
|
||||
# These are the examples it has available to choose from.
|
||||
examples=examples,
|
||||
# This is the PromptTemplate being used to format the examples.
|
||||
example_prompt=example_prompt,
|
||||
# This is the maximum length that the formatted examples should be.
|
||||
# Length is measured by the get_text_length function below.
|
||||
max_length=25,
|
||||
# This is the function used to get the length of a string, which is used
|
||||
# to determine which examples to include. It is commented out because
|
||||
# it is provided as a default value if none is specified.
|
||||
# get_text_length: Callable[[str], int] = lambda x: len(re.split("\n| ", x))
|
||||
)
|
||||
dynamic_prompt = FewShotPromptTemplate(
|
||||
# We provide an ExampleSelector instead of examples.
|
||||
example_selector=example_selector,
|
||||
example_prompt=example_prompt,
|
||||
prefix="Give the antonym of every input",
|
||||
suffix="Input: {adjective}\nOutput:",
|
||||
input_variables=["adjective"],
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
# An example with small input, so it selects all examples.
|
||||
print(dynamic_prompt.format(adjective="big"))
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Give the antonym of every input
|
||||
|
||||
Input: happy
|
||||
Output: sad
|
||||
|
||||
Input: tall
|
||||
Output: short
|
||||
|
||||
Input: energetic
|
||||
Output: lethargic
|
||||
|
||||
Input: sunny
|
||||
Output: gloomy
|
||||
|
||||
Input: windy
|
||||
Output: calm
|
||||
|
||||
Input: big
|
||||
Output:
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
|
||||
```python
|
||||
# An example with long input, so it selects only one example.
|
||||
long_string = "big and huge and massive and large and gigantic and tall and much much much much much bigger than everything else"
|
||||
print(dynamic_prompt.format(adjective=long_string))
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Give the antonym of every input
|
||||
|
||||
Input: happy
|
||||
Output: sad
|
||||
|
||||
Input: big and huge and massive and large and gigantic and tall and much much much much much bigger than everything else
|
||||
Output:
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
|
||||
```python
|
||||
# You can add an example to an example selector as well.
|
||||
new_example = {"input": "big", "output": "small"}
|
||||
dynamic_prompt.example_selector.add_example(new_example)
|
||||
print(dynamic_prompt.format(adjective="enthusiastic"))
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Give the antonym of every input
|
||||
|
||||
Input: happy
|
||||
Output: sad
|
||||
|
||||
Input: tall
|
||||
Output: short
|
||||
|
||||
Input: energetic
|
||||
Output: lethargic
|
||||
|
||||
Input: sunny
|
||||
Output: gloomy
|
||||
|
||||
Input: windy
|
||||
Output: calm
|
||||
|
||||
Input: big
|
||||
Output: small
|
||||
|
||||
Input: enthusiastic
|
||||
Output:
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
|
@ -0,0 +1,112 @@
|
|||
```python
|
||||
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
|
||||
from langchain.vectorstores import Chroma
|
||||
from langchain.embeddings import OpenAIEmbeddings
|
||||
from langchain.prompts import FewShotPromptTemplate, PromptTemplate
|
||||
|
||||
example_prompt = PromptTemplate(
|
||||
input_variables=["input", "output"],
|
||||
template="Input: {input}\nOutput: {output}",
|
||||
)
|
||||
|
||||
# These are a lot of examples of a pretend task of creating antonyms.
|
||||
examples = [
|
||||
{"input": "happy", "output": "sad"},
|
||||
{"input": "tall", "output": "short"},
|
||||
{"input": "energetic", "output": "lethargic"},
|
||||
{"input": "sunny", "output": "gloomy"},
|
||||
{"input": "windy", "output": "calm"},
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
example_selector = SemanticSimilarityExampleSelector.from_examples(
|
||||
# This is the list of examples available to select from.
|
||||
examples,
|
||||
# This is the embedding class used to produce embeddings which are used to measure semantic similarity.
|
||||
OpenAIEmbeddings(),
|
||||
# This is the VectorStore class that is used to store the embeddings and do a similarity search over.
|
||||
Chroma,
|
||||
# This is the number of examples to produce.
|
||||
k=1
|
||||
)
|
||||
similar_prompt = FewShotPromptTemplate(
|
||||
# We provide an ExampleSelector instead of examples.
|
||||
example_selector=example_selector,
|
||||
example_prompt=example_prompt,
|
||||
prefix="Give the antonym of every input",
|
||||
suffix="Input: {adjective}\nOutput:",
|
||||
input_variables=["adjective"],
|
||||
)
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Running Chroma using direct local API.
|
||||
Using DuckDB in-memory for database. Data will be transient.
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
|
||||
```python
|
||||
# Input is a feeling, so should select the happy/sad example
|
||||
print(similar_prompt.format(adjective="worried"))
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Give the antonym of every input
|
||||
|
||||
Input: happy
|
||||
Output: sad
|
||||
|
||||
Input: worried
|
||||
Output:
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
|
||||
```python
|
||||
# Input is a measurement, so should select the tall/short example
|
||||
print(similar_prompt.format(adjective="fat"))
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Give the antonym of every input
|
||||
|
||||
Input: happy
|
||||
Output: sad
|
||||
|
||||
Input: fat
|
||||
Output:
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
|
||||
```python
|
||||
# You can add new examples to the SemanticSimilarityExampleSelector as well
|
||||
similar_prompt.example_selector.add_example({"input": "enthusiastic", "output": "apathetic"})
|
||||
print(similar_prompt.format(adjective="joyful"))
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Give the antonym of every input
|
||||
|
||||
Input: happy
|
||||
Output: sad
|
||||
|
||||
Input: joyful
|
||||
Output:
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
|
@ -0,0 +1,257 @@
|
|||
### Use Case
|
||||
|
||||
In this tutorial, we'll configure few shot examples for self-ask with search.
|
||||
|
||||
|
||||
## Using an example set
|
||||
|
||||
### Create the example set
|
||||
|
||||
To get started, create a list of few shot examples. Each example should be a dictionary with the keys being the input variables and the values being the values for those input variables.
|
||||
|
||||
```python
|
||||
from langchain.prompts.few_shot import FewShotPromptTemplate
|
||||
from langchain.prompts.prompt import PromptTemplate
|
||||
|
||||
examples = [
|
||||
{
|
||||
"question": "Who lived longer, Muhammad Ali or Alan Turing?",
|
||||
"answer":
|
||||
"""
|
||||
Are follow up questions needed here: Yes.
|
||||
Follow up: How old was Muhammad Ali when he died?
|
||||
Intermediate answer: Muhammad Ali was 74 years old when he died.
|
||||
Follow up: How old was Alan Turing when he died?
|
||||
Intermediate answer: Alan Turing was 41 years old when he died.
|
||||
So the final answer is: Muhammad Ali
|
||||
"""
|
||||
},
|
||||
{
|
||||
"question": "When was the founder of craigslist born?",
|
||||
"answer":
|
||||
"""
|
||||
Are follow up questions needed here: Yes.
|
||||
Follow up: Who was the founder of craigslist?
|
||||
Intermediate answer: Craigslist was founded by Craig Newmark.
|
||||
Follow up: When was Craig Newmark born?
|
||||
Intermediate answer: Craig Newmark was born on December 6, 1952.
|
||||
So the final answer is: December 6, 1952
|
||||
"""
|
||||
},
|
||||
{
|
||||
"question": "Who was the maternal grandfather of George Washington?",
|
||||
"answer":
|
||||
"""
|
||||
Are follow up questions needed here: Yes.
|
||||
Follow up: Who was the mother of George Washington?
|
||||
Intermediate answer: The mother of George Washington was Mary Ball Washington.
|
||||
Follow up: Who was the father of Mary Ball Washington?
|
||||
Intermediate answer: The father of Mary Ball Washington was Joseph Ball.
|
||||
So the final answer is: Joseph Ball
|
||||
"""
|
||||
},
|
||||
{
|
||||
"question": "Are both the directors of Jaws and Casino Royale from the same country?",
|
||||
"answer":
|
||||
"""
|
||||
Are follow up questions needed here: Yes.
|
||||
Follow up: Who is the director of Jaws?
|
||||
Intermediate Answer: The director of Jaws is Steven Spielberg.
|
||||
Follow up: Where is Steven Spielberg from?
|
||||
Intermediate Answer: The United States.
|
||||
Follow up: Who is the director of Casino Royale?
|
||||
Intermediate Answer: The director of Casino Royale is Martin Campbell.
|
||||
Follow up: Where is Martin Campbell from?
|
||||
Intermediate Answer: New Zealand.
|
||||
So the final answer is: No
|
||||
"""
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Create a formatter for the few shot examples
|
||||
|
||||
Configure a formatter that will format the few shot examples into a string. This formatter should be a `PromptTemplate` object.
|
||||
|
||||
|
||||
```python
|
||||
example_prompt = PromptTemplate(input_variables=["question", "answer"], template="Question: {question}\n{answer}")
|
||||
|
||||
print(example_prompt.format(**examples[0]))
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Question: Who lived longer, Muhammad Ali or Alan Turing?
|
||||
|
||||
Are follow up questions needed here: Yes.
|
||||
Follow up: How old was Muhammad Ali when he died?
|
||||
Intermediate answer: Muhammad Ali was 74 years old when he died.
|
||||
Follow up: How old was Alan Turing when he died?
|
||||
Intermediate answer: Alan Turing was 41 years old when he died.
|
||||
So the final answer is: Muhammad Ali
|
||||
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
### Feed examples and formatter to `FewShotPromptTemplate`
|
||||
|
||||
Finally, create a `FewShotPromptTemplate` object. This object takes in the few shot examples and the formatter for the few shot examples.
|
||||
|
||||
|
||||
```python
|
||||
prompt = FewShotPromptTemplate(
|
||||
examples=examples,
|
||||
example_prompt=example_prompt,
|
||||
suffix="Question: {input}",
|
||||
input_variables=["input"]
|
||||
)
|
||||
|
||||
print(prompt.format(input="Who was the father of Mary Ball Washington?"))
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Question: Who lived longer, Muhammad Ali or Alan Turing?
|
||||
|
||||
Are follow up questions needed here: Yes.
|
||||
Follow up: How old was Muhammad Ali when he died?
|
||||
Intermediate answer: Muhammad Ali was 74 years old when he died.
|
||||
Follow up: How old was Alan Turing when he died?
|
||||
Intermediate answer: Alan Turing was 41 years old when he died.
|
||||
So the final answer is: Muhammad Ali
|
||||
|
||||
|
||||
Question: When was the founder of craigslist born?
|
||||
|
||||
Are follow up questions needed here: Yes.
|
||||
Follow up: Who was the founder of craigslist?
|
||||
Intermediate answer: Craigslist was founded by Craig Newmark.
|
||||
Follow up: When was Craig Newmark born?
|
||||
Intermediate answer: Craig Newmark was born on December 6, 1952.
|
||||
So the final answer is: December 6, 1952
|
||||
|
||||
|
||||
Question: Who was the maternal grandfather of George Washington?
|
||||
|
||||
Are follow up questions needed here: Yes.
|
||||
Follow up: Who was the mother of George Washington?
|
||||
Intermediate answer: The mother of George Washington was Mary Ball Washington.
|
||||
Follow up: Who was the father of Mary Ball Washington?
|
||||
Intermediate answer: The father of Mary Ball Washington was Joseph Ball.
|
||||
So the final answer is: Joseph Ball
|
||||
|
||||
|
||||
Question: Are both the directors of Jaws and Casino Royale from the same country?
|
||||
|
||||
Are follow up questions needed here: Yes.
|
||||
Follow up: Who is the director of Jaws?
|
||||
Intermediate Answer: The director of Jaws is Steven Spielberg.
|
||||
Follow up: Where is Steven Spielberg from?
|
||||
Intermediate Answer: The United States.
|
||||
Follow up: Who is the director of Casino Royale?
|
||||
Intermediate Answer: The director of Casino Royale is Martin Campbell.
|
||||
Follow up: Where is Martin Campbell from?
|
||||
Intermediate Answer: New Zealand.
|
||||
So the final answer is: No
|
||||
|
||||
|
||||
Question: Who was the father of Mary Ball Washington?
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
## Using an example selector
|
||||
|
||||
### Feed examples into `ExampleSelector`
|
||||
|
||||
We will reuse the example set and the formatter from the previous section. However, instead of feeding the examples directly into the `FewShotPromptTemplate` object, we will feed them into an `ExampleSelector` object.
|
||||
|
||||
|
||||
In this tutorial, we will use the `SemanticSimilarityExampleSelector` class. This class selects few shot examples based on their similarity to the input. It uses an embedding model to compute the similarity between the input and the few shot examples, as well as a vector store to perform the nearest neighbor search.
|
||||
|
||||
|
||||
```python
|
||||
from langchain.prompts.example_selector import SemanticSimilarityExampleSelector
|
||||
from langchain.vectorstores import Chroma
|
||||
from langchain.embeddings import OpenAIEmbeddings
|
||||
|
||||
|
||||
example_selector = SemanticSimilarityExampleSelector.from_examples(
|
||||
# This is the list of examples available to select from.
|
||||
examples,
|
||||
# This is the embedding class used to produce embeddings which are used to measure semantic similarity.
|
||||
OpenAIEmbeddings(),
|
||||
# This is the VectorStore class that is used to store the embeddings and do a similarity search over.
|
||||
Chroma,
|
||||
# This is the number of examples to produce.
|
||||
k=1
|
||||
)
|
||||
|
||||
# Select the most similar example to the input.
|
||||
question = "Who was the father of Mary Ball Washington?"
|
||||
selected_examples = example_selector.select_examples({"question": question})
|
||||
print(f"Examples most similar to the input: {question}")
|
||||
for example in selected_examples:
|
||||
print("\n")
|
||||
for k, v in example.items():
|
||||
print(f"{k}: {v}")
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Running Chroma using direct local API.
|
||||
Using DuckDB in-memory for database. Data will be transient.
|
||||
Examples most similar to the input: Who was the father of Mary Ball Washington?
|
||||
|
||||
|
||||
question: Who was the maternal grandfather of George Washington?
|
||||
answer:
|
||||
Are follow up questions needed here: Yes.
|
||||
Follow up: Who was the mother of George Washington?
|
||||
Intermediate answer: The mother of George Washington was Mary Ball Washington.
|
||||
Follow up: Who was the father of Mary Ball Washington?
|
||||
Intermediate answer: The father of Mary Ball Washington was Joseph Ball.
|
||||
So the final answer is: Joseph Ball
|
||||
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
### Feed example selector into `FewShotPromptTemplate`
|
||||
|
||||
Finally, create a `FewShotPromptTemplate` object. This object takes in the example selector and the formatter for the few shot examples.
|
||||
|
||||
|
||||
```python
|
||||
prompt = FewShotPromptTemplate(
|
||||
example_selector=example_selector,
|
||||
example_prompt=example_prompt,
|
||||
suffix="Question: {input}",
|
||||
input_variables=["input"]
|
||||
)
|
||||
|
||||
print(prompt.format(input="Who was the father of Mary Ball Washington?"))
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Question: Who was the maternal grandfather of George Washington?
|
||||
|
||||
Are follow up questions needed here: Yes.
|
||||
Follow up: Who was the mother of George Washington?
|
||||
Intermediate answer: The mother of George Washington was Mary Ball Washington.
|
||||
Follow up: Who was the father of Mary Ball Washington?
|
||||
Intermediate answer: The father of Mary Ball Washington was Joseph Ball.
|
||||
So the final answer is: Joseph Ball
|
||||
|
||||
|
||||
Question: Who was the father of Mary Ball Washington?
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
|
@ -0,0 +1,140 @@
|
|||
Here's the simplest example:
|
||||
|
||||
```python
|
||||
from langchain import PromptTemplate
|
||||
|
||||
|
||||
template = """\
|
||||
You are a naming consultant for new companies.
|
||||
What is a good name for a company that makes {product}?
|
||||
"""
|
||||
|
||||
prompt = PromptTemplate.from_template(template)
|
||||
prompt.format(product="colorful socks")
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
You are a naming consultant for new companies.
|
||||
What is a good name for a company that makes colorful socks?
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
|
||||
## Create a prompt template
|
||||
|
||||
You can create simple hardcoded prompts using the `PromptTemplate` class. Prompt templates can take any number of input variables, and can be formatted to generate a prompt.
|
||||
|
||||
|
||||
```python
|
||||
from langchain import PromptTemplate
|
||||
|
||||
# An example prompt with no input variables
|
||||
no_input_prompt = PromptTemplate(input_variables=[], template="Tell me a joke.")
|
||||
no_input_prompt.format()
|
||||
# -> "Tell me a joke."
|
||||
|
||||
# An example prompt with one input variable
|
||||
one_input_prompt = PromptTemplate(input_variables=["adjective"], template="Tell me a {adjective} joke.")
|
||||
one_input_prompt.format(adjective="funny")
|
||||
# -> "Tell me a funny joke."
|
||||
|
||||
# An example prompt with multiple input variables
|
||||
multiple_input_prompt = PromptTemplate(
|
||||
input_variables=["adjective", "content"],
|
||||
template="Tell me a {adjective} joke about {content}."
|
||||
)
|
||||
multiple_input_prompt.format(adjective="funny", content="chickens")
|
||||
# -> "Tell me a funny joke about chickens."
|
||||
```
|
||||
|
||||
If you do not wish to specify `input_variables` manually, you can also create a `PromptTemplate` using `from_template` class method. `langchain` will automatically infer the `input_variables` based on the `template` passed.
|
||||
|
||||
```python
|
||||
template = "Tell me a {adjective} joke about {content}."
|
||||
|
||||
prompt_template = PromptTemplate.from_template(template)
|
||||
prompt_template.input_variables
|
||||
# -> ['adjective', 'content']
|
||||
prompt_template.format(adjective="funny", content="chickens")
|
||||
# -> Tell me a funny joke about chickens.
|
||||
```
|
||||
|
||||
You can create custom prompt templates that format the prompt in any way you want. For more information, see [Custom Prompt Templates](./custom_prompt_template.html).
|
||||
|
||||
|
||||
<!-- TODO(shreya): Add link to Jinja -->
|
||||
|
||||
## Chat prompt template
|
||||
|
||||
[Chat Models](../models/chat) take a list of chat messages as input - this list commonly referred to as a `prompt`.
|
||||
These chat messages differ from raw string (which you would pass into a [LLM](/docs/modules/model_io/models/llms) model) in that every message is associated with a `role`.
|
||||
|
||||
For example, in OpenAI [Chat Completion API](https://platform.openai.com/docs/guides/chat/introduction), a chat message can be associated with the AI, human or system role. The model is supposed to follow instruction from system chat message more closely.
|
||||
|
||||
LangChain provides several prompt templates to make constructing and working with prompts easily. You are encouraged to use these chat related prompt templates instead of `PromptTemplate` when querying chat models to fully exploit the potential of underlying chat model.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```python
|
||||
from langchain.prompts import (
|
||||
ChatPromptTemplate,
|
||||
PromptTemplate,
|
||||
SystemMessagePromptTemplate,
|
||||
AIMessagePromptTemplate,
|
||||
HumanMessagePromptTemplate,
|
||||
)
|
||||
from langchain.schema import (
|
||||
AIMessage,
|
||||
HumanMessage,
|
||||
SystemMessage
|
||||
)
|
||||
```
|
||||
|
||||
To create a message template associated with a role, you use `MessagePromptTemplate`.
|
||||
|
||||
For convenience, there is a `from_template` method exposed on the template. If you were to use this template, this is what it would look like:
|
||||
|
||||
|
||||
```python
|
||||
template="You are a helpful assistant that translates {input_language} to {output_language}."
|
||||
system_message_prompt = SystemMessagePromptTemplate.from_template(template)
|
||||
human_template="{text}"
|
||||
human_message_prompt = HumanMessagePromptTemplate.from_template(human_template)
|
||||
```
|
||||
|
||||
If you wanted to construct the `MessagePromptTemplate` more directly, you could create a PromptTemplate outside and then pass it in, eg:
|
||||
|
||||
|
||||
```python
|
||||
prompt=PromptTemplate(
|
||||
template="You are a helpful assistant that translates {input_language} to {output_language}.",
|
||||
input_variables=["input_language", "output_language"],
|
||||
)
|
||||
system_message_prompt_2 = SystemMessagePromptTemplate(prompt=prompt)
|
||||
|
||||
assert system_message_prompt == system_message_prompt_2
|
||||
```
|
||||
|
||||
After that, you can build a `ChatPromptTemplate` from one or more `MessagePromptTemplates`. You can use `ChatPromptTemplate`'s `format_prompt` -- this returns a `PromptValue`, which you can convert to a string or Message object, depending on whether you want to use the formatted value as input to an llm or chat model.
|
||||
|
||||
|
||||
```python
|
||||
chat_prompt = ChatPromptTemplate.from_messages([system_message_prompt, human_message_prompt])
|
||||
|
||||
# get a chat completion from the formatted messages
|
||||
chat_prompt.format_prompt(input_language="English", output_language="French", text="I love programming.").to_messages()
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
[SystemMessage(content='You are a helpful assistant that translates English to French.', additional_kwargs={}),
|
||||
HumanMessage(content='I love programming.', additional_kwargs={})]
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
|
@ -0,0 +1,92 @@
|
|||
## Partial With Strings
|
||||
|
||||
One common use case for wanting to partial a prompt template is if you get some of the variables before others. For example, suppose you have a prompt template that requires two variables, `foo` and `baz`. If you get the `foo` value early on in the chain, but the `baz` value later, it can be annoying to wait until you have both variables in the same place to pass them to the prompt template. Instead, you can partial the prompt template with the `foo` value, and then pass the partialed prompt template along and just use that. Below is an example of doing this:
|
||||
|
||||
|
||||
|
||||
|
||||
```python
|
||||
from langchain.prompts import PromptTemplate
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
prompt = PromptTemplate(template="{foo}{bar}", input_variables=["foo", "bar"])
|
||||
partial_prompt = prompt.partial(foo="foo");
|
||||
print(partial_prompt.format(bar="baz"))
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
foobaz
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
You can also just initialize the prompt with the partialed variables.
|
||||
|
||||
|
||||
```python
|
||||
prompt = PromptTemplate(template="{foo}{bar}", input_variables=["bar"], partial_variables={"foo": "foo"})
|
||||
print(prompt.format(bar="baz"))
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
foobaz
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
## Partial With Functions
|
||||
|
||||
The other common use is to partial with a function. The use case for this is when you have a variable you know that you always want to fetch in a common way. A prime example of this is with date or time. Imagine you have a prompt which you always want to have the current date. You can't hard code it in the prompt, and passing it along with the other input variables is a bit annoying. In this case, it's very handy to be able to partial the prompt with a function that always returns the current date.
|
||||
|
||||
|
||||
```python
|
||||
from datetime import datetime
|
||||
|
||||
def _get_datetime():
|
||||
now = datetime.now()
|
||||
return now.strftime("%m/%d/%Y, %H:%M:%S")
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
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"))
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Tell me a funny joke about the day 02/27/2023, 22:15:16
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
You can also just initialize the prompt with the partialed variables, which often makes more sense in this workflow.
|
||||
|
||||
|
||||
```python
|
||||
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"))
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
Tell me a funny joke about the day 02/27/2023, 22:15:16
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
|
@ -0,0 +1,88 @@
|
|||
```python
|
||||
from langchain.prompts.pipeline import PipelinePromptTemplate
|
||||
from langchain.prompts.prompt import PromptTemplate
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
full_template = """{introduction}
|
||||
|
||||
{example}
|
||||
|
||||
{start}"""
|
||||
full_prompt = PromptTemplate.from_template(full_template)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
introduction_template = """You are impersonating {person}."""
|
||||
introduction_prompt = PromptTemplate.from_template(introduction_template)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
example_template = """Here's an example of an interaction:
|
||||
|
||||
Q: {example_q}
|
||||
A: {example_a}"""
|
||||
example_prompt = PromptTemplate.from_template(example_template)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
start_template = """Now, do this for real!
|
||||
|
||||
Q: {input}
|
||||
A:"""
|
||||
start_prompt = PromptTemplate.from_template(start_template)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
input_prompts = [
|
||||
("introduction", introduction_prompt),
|
||||
("example", example_prompt),
|
||||
("start", start_prompt)
|
||||
]
|
||||
pipeline_prompt = PipelinePromptTemplate(final_prompt=full_prompt, pipeline_prompts=input_prompts)
|
||||
```
|
||||
|
||||
|
||||
```python
|
||||
pipeline_prompt.input_variables
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
['example_a', 'person', 'example_q', 'input']
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
||||
|
||||
|
||||
```python
|
||||
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?"
|
||||
))
|
||||
```
|
||||
|
||||
<CodeOutputBlock lang="python">
|
||||
|
||||
```
|
||||
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:
|
||||
|
||||
```
|
||||
|
||||
</CodeOutputBlock>
|
Loading…
Add table
Add a link
Reference in a new issue