openai-cookbook/examples/data/oai_docs/text-generation.txt
Max Reid 5f552669f7
initial commit for Azure RAG cookbook (#1272)
Co-authored-by: juston <96567547+justonf@users.noreply.github.com>
2024-07-25 15:12:35 -04:00

566 lines
28 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Text generation models
OpenAI's text generation models (often called generative pre-trained transformers or large language models) have been trained to understand natural language, code, and images. The models provide text outputs in response to their inputs. The text inputs to these models are also referred to as "prompts". Designing a prompt is essentially how you “program” a large language model model, usually by providing instructions or some examples of how to successfully complete a task.
Using OpenAI's text generation models, you can build applications to:
- Draft documents
- Write computer code
- Answer questions about a knowledge base
- Analyze texts
- Give software a natural language interface
- Tutor in a range of subjects
- Translate languages
- Simulate characters for games
---
<IconItem
icon={}
color="green"
title="Try GPT-4o"
className="mt-6"
>
Try out GPT-4o in the playground.
<IconItem
icon={}
color="purple"
title="Explore GPT-4o with image inputs"
className="mt-6"
>
Check out the vision guide for more detail.
---
To use one of these models via the OpenAI API, youll send a request to the Chat Completions API containing the inputs and your API key, and receive a response containing the models output.
You can experiment with various models in the [chat playground](https://platform.openai.com/playground?mode=chat). If youre not sure which model to use then try `gpt-4o` if you need high intelligence or `gpt-3.5-turbo` if you need the fastest speed and lowest cost.
## Chat Completions API
Chat models take a list of messages as input and return a model-generated message as output. Although the chat format is designed to make multi-turn conversations easy, its just as useful for single-turn tasks without any conversation.
An example Chat Completions API call looks like the following:
<CodeSample
defaultLanguage="python"
code={{
python: `
from openai import OpenAI
client = OpenAI()\n
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Who won the world series in 2020?"},
{"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
{"role": "user", "content": "Where was it played?"}
]
)
`.trim(),
"node.js": `
import OpenAI from "openai";\n
const openai = new OpenAI();\n
async function main() {
const completion = await openai.chat.completions.create({
messages: [{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Who won the world series in 2020?"},
{"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
{"role": "user", "content": "Where was it played?"}],
model: "gpt-3.5-turbo",
});\n
console.log(completion.choices[0]);
}
main();
`.trim(),
curl: `
curl https://api.openai.com/v1/chat/completions \\
-H "Content-Type: application/json" \\
-H "Authorization: Bearer $OPENAI_API_KEY" \\
-d '{
"model": "gpt-3.5-turbo",
"messages": [
{
"role": "system",
"content": "You are a helpful assistant."
},
{
"role": "user",
"content": "Who won the world series in 2020?"
},
{
"role": "assistant",
"content": "The Los Angeles Dodgers won the World Series in 2020."
},
{
"role": "user",
"content": "Where was it played?"
}
]
}'
`.trim(),
}}
/>
To learn more, you can view the full [API reference documentation](https://platform.openai.com/docs/api-reference/chat) for the Chat API.
The main input is the messages parameter. Messages must be an array of message objects, where each object has a role (either "system", "user", or "assistant") and content. Conversations can be as short as one message or many back and forth turns.
Typically, a conversation is formatted with a system message first, followed by alternating user and assistant messages.
The system message helps set the behavior of the assistant. For example, you can modify the personality of the assistant or provide specific instructions about how it should behave throughout the conversation. However note that the system message is optional and the models behavior without a system message is likely to be similar to using a generic message such as "You are a helpful assistant."
The user messages provide requests or comments for the assistant to respond to. Assistant messages store previous assistant responses, but can also be written by you to give examples of desired behavior.
Including conversation history is important when user instructions refer to prior messages. In the example above, the users final question of "Where was it played?" only makes sense in the context of the prior messages about the World Series of 2020. Because the models have no memory of past requests, all relevant information must be supplied as part of the conversation history in each request. If a conversation cannot fit within the models token limit, it will need to be [shortened](/docs/guides/prompt-engineering/tactic-for-dialogue-applications-that-require-very-long-conversations-summarize-or-filter-previous-dialogue) in some way.
To mimic the effect seen in ChatGPT where the text is returned iteratively, set the{" "}
stream parameter to
true.
### Chat Completions response format
An example Chat Completions API response looks as follows:
```
{
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": {
"content": "The 2020 World Series was played in Texas at Globe Life Field in Arlington.",
"role": "assistant"
},
"logprobs": null
}
],
"created": 1677664795,
"id": "chatcmpl-7QyqpwdfhqwajicIEznoc6Q47XAyW",
"model": "gpt-3.5-turbo-0613",
"object": "chat.completion",
"usage": {
"completion_tokens": 17,
"prompt_tokens": 57,
"total_tokens": 74
}
}
```
The assistants reply can be extracted with:
<CodeSample
defaultLanguage="python"
code={{
python: `
completion.choices[0].message.content
`.trim(),
"node.js": `
completion.choices[0].message.content
`.trim(),
}}
/>
Every response will include a `finish_reason`. The possible values for `finish_reason` are:
- `stop`: API returned complete message, or a message terminated by one of the stop sequences provided via the [stop](/docs/api-reference/chat/create#chat/create-stop) parameter
- `length`: Incomplete model output due to [`max_tokens`](/docs/api-reference/chat/create#chat/create-max_tokens) parameter or token limit
- `function_call`: The model decided to call a function
- `content_filter`: Omitted content due to a flag from our content filters
- `null`: API response still in progress or incomplete
Depending on input parameters, the model response may include different information.
JSON mode
A common way to use Chat Completions is to instruct the model to always return a JSON object that makes sense for your use case, by specifying this in the system message. While this does work in some cases, occasionally the models may generate output that does not parse to valid JSON objects.
To prevent these errors and improve model performance, when using `gpt-4o`, `gpt-4-turbo`, or `gpt-3.5-turbo`, you can set [response_format](/docs/api-reference/chat/create#chat-create-response_format) to `{ "type": "json_object" }` to enable JSON mode. When JSON mode is enabled, the model is constrained to only generate strings that parse into valid JSON object.
Important notes:
- When using JSON mode, **always** instruct the model to produce JSON via some message in the conversation, for example via your system message. If you don't include an explicit instruction to generate JSON, the model may generate an unending stream of whitespace and the request may run continually until it reaches the token limit. To help ensure you don't forget, the API will throw an error if the string `"JSON"` does not appear somewhere in the context.
- The JSON in the message the model returns may be partial (i.e. cut off) if `finish_reason` is `length`, which indicates the generation exceeded `max_tokens` or the conversation exceeded the token limit. To guard against this, check `finish_reason` before parsing the response.
- JSON mode will not guarantee the output matches any specific schema, only that it is valid and parses without errors.
<CodeSample
defaultLanguage="python"
code={{
python: `
from openai import OpenAI
client = OpenAI()\n
response = client.chat.completions.create(
model="gpt-3.5-turbo-0125",
response_format={ "type": "json_object" },
messages=[
{"role": "system", "content": "You are a helpful assistant designed to output JSON."},
{"role": "user", "content": "Who won the world series in 2020?"}
]
)
print(response.choices[0].message.content)
`.trim(),
"node.js": `
import OpenAI from "openai";\n
const openai = new OpenAI();\n
async function main() {
const completion = await openai.chat.completions.create({
messages: [
{
role: "system",
content: "You are a helpful assistant designed to output JSON.",
},
{ role: "user", content: "Who won the world series in 2020?" },
],
model: "gpt-3.5-turbo-0125",
response_format: { type: "json_object" },
});
console.log(completion.choices[0].message.content);
}\n
main();
`.trim(),
curl: `
curl https://api.openai.com/v1/chat/completions \\
-H "Content-Type: application/json" \\
-H "Authorization: Bearer $OPENAI_API_KEY" \\
-d '{
"model": "gpt-3.5-turbo-0125",
"response_format": { "type": "json_object" },
"messages": [
{
"role": "system",
"content": "You are a helpful assistant designed to output JSON."
},
{
"role": "user",
"content": "Who won the world series in 2020?"
}
]
}'
`.trim(),
}}
/>
In this example, the response includes a JSON object that looks something like the following:
```json
"content": "{\"winner\": \"Los Angeles Dodgers\"}"`
```
Note that JSON mode is always enabled when the model is generating arguments as part of [function calling](/docs/guides/function-calling).
Reproducible outputs{" "}
Beta
Chat Completions are non-deterministic by default (which means model outputs may differ from request to request). That being said, we offer some control towards deterministic outputs by giving you access to the [seed](/docs/api-reference/chat/create#chat-create-seed) parameter and the [system_fingerprint](/docs/api-reference/completions/object#completions/object-system_fingerprint) response field.
To receive (mostly) deterministic outputs across API calls, you can:
- Set the [seed](/docs/api-reference/chat/create#chat-create-seed) parameter to any integer of your choice and use the same value across requests you'd like deterministic outputs for.
- Ensure all other parameters (like `prompt` or `temperature`) are the exact same across requests.
Sometimes, determinism may be impacted due to necessary changes OpenAI makes to model configurations on our end. To help you keep track of these changes, we expose the [system_fingerprint](/docs/api-reference/chat/object#chat/object-system_fingerprint) field. If this value is different, you may see different outputs due to changes we've made on our systems.
<a
href="https://cookbook.openai.com/examples/reproducible_outputs_with_the_seed_parameter"
target="_blank"
>
<IconItem
icon={}
color="purple"
title="Deterministic outputs"
className="mt-6"
>
Explore the new seed parameter in the OpenAI cookbook
## Managing tokens
Language models read and write text in chunks called tokens. In English, a token can be as short as one character or as long as one word (e.g., `a` or ` apple`), and in some languages tokens can be even shorter than one character or even longer than one word.
For example, the string `"ChatGPT is great!"` is encoded into six tokens: `["Chat", "G", "PT", " is", " great", "!"]`.
The total number of tokens in an API call affects:
- How much your API call costs, as you pay per token
- How long your API call takes, as writing more tokens takes more time
- Whether your API call works at all, as total tokens must be below the models maximum limit (4097 tokens for `gpt-3.5-turbo`)
Both input and output tokens count toward these quantities. For example, if your API call used 10 tokens in the message input and you received 20 tokens in the message output, you would be billed for 30 tokens. Note however that for some models the price per token is different for tokens in the input vs. the output (see the [pricing](https://openai.com/pricing) page for more information).
To see how many tokens are used by an API call, check the `usage` field in the API response (e.g., `response['usage']['total_tokens']`).
Chat models like `gpt-3.5-turbo` and `gpt-4-turbo-preview` use tokens in the same way as the models available in the completions API, but because of their message-based formatting, it's more difficult to count how many tokens will be used by a conversation.
Below is an example function for counting tokens for messages passed to `gpt-3.5-turbo-0613`.
The exact way that messages are converted into tokens may change from model to model. So when future model versions are released, the answers returned by this function may be only approximate.
```python
def num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613"):
"""Returns the number of tokens used by a list of messages."""
try:
encoding = tiktoken.encoding_for_model(model)
except KeyError:
encoding = tiktoken.get_encoding("cl100k_base")
if model == "gpt-3.5-turbo-0613": # note: future models may deviate from this
num_tokens = 0
for message in messages:
num_tokens += 4 # every message follows {role/name}\n{content}\n
for key, value in message.items():
num_tokens += len(encoding.encode(value))
if key == "name": # if there's a name, the role is omitted
num_tokens += -1 # role is always required and always 1 token
num_tokens += 2 # every reply is primed with assistant
return num_tokens
else:
raise NotImplementedError(f"""num_tokens_from_messages() is not presently implemented for model {model}.""")
```
Next, create a message and pass it to the function defined above to see the token count, this should match the value returned by the API usage parameter:
```python
messages = [
{"role": "system", "content": "You are a helpful, pattern-following assistant that translates corporate jargon into plain English."},
{"role": "system", "name":"example_user", "content": "New synergies will help drive top-line growth."},
{"role": "system", "name": "example_assistant", "content": "Things working well together will increase revenue."},
{"role": "system", "name":"example_user", "content": "Let's circle back when we have more bandwidth to touch base on opportunities for increased leverage."},
{"role": "system", "name": "example_assistant", "content": "Let's talk later when we're less busy about how to do better."},
{"role": "user", "content": "This late pivot means we don't have time to boil the ocean for the client deliverable."},
]
model = "gpt-3.5-turbo-0613"
print(f"{num_tokens_from_messages(messages, model)} prompt tokens counted.")
# Should show ~126 total_tokens
```
To confirm the number generated by our function above is the same as what the API returns, create a new Chat Completion:
```python
# example token count from the OpenAI API
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model=model,
messages=messages,
temperature=0,
)
print(f'{response.usage.prompt_tokens} prompt tokens used.')
```
To see how many tokens are in a text string without making an API call, use OpenAIs [tiktoken](https://github.com/openai/tiktoken) Python library. Example code can be found in the OpenAI Cookbooks guide on [how to count tokens with tiktoken](https://cookbook.openai.com/examples/how_to_count_tokens_with_tiktoken).
Each message passed to the API consumes the number of tokens in the content, role, and other fields, plus a few extra for behind-the-scenes formatting. This may change slightly in the future.
If a conversation has too many tokens to fit within a models maximum limit (e.g., more than 4097 tokens for `gpt-3.5-turbo` or more than 128k tokens for `gpt-4o`), you will have to truncate, omit, or otherwise shrink your text until it fits. Beware that if a message is removed from the messages input, the model will lose all knowledge of it.
Note that very long conversations are more likely to receive incomplete replies. For example, a `gpt-3.5-turbo` conversation that is 4090 tokens long will have its reply cut off after just 6 tokens.
## Parameter details
### Frequency and presence penalties
The frequency and presence penalties found in the [Chat Completions API](/docs/api-reference/chat/create) and [Legacy Completions API](/docs/api-reference/completions) can be used to reduce the likelihood of sampling repetitive sequences of tokens.
They work by directly modifying the logits (un-normalized log-probabilities) with an additive contribution.
```python
mu[j] -> mu[j] - c[j] * alpha_frequency - float(c[j] > 0) * alpha_presence
```
Where:
- `mu[j]` is the logits of the j-th token
- `c[j]` is how often that token was sampled prior to the current position
- `float(c[j] > 0)` is 1 if `c[j] > 0` and 0 otherwise
- `alpha_frequency` is the frequency penalty coefficient
- `alpha_presence` is the presence penalty coefficient
As we can see, the presence penalty is a one-off additive contribution that applies to all tokens that have been sampled at least once and the frequency penalty is a contribution that is proportional to how often a particular token has already been sampled.
Reasonable values for the penalty coefficients are around 0.1 to 1 if the aim is to just reduce repetitive samples somewhat. If the aim is to strongly suppress repetition, then one can increase the coefficients up to 2, but this can noticeably degrade the quality of samples. Negative values can be used to increase the likelihood of repetition.
### Token log probabilities
The [logprobs](/docs/api-reference/chat/create#chat-create-logprobs) parameter found in the [Chat Completions API](/docs/api-reference/chat/create) and [Legacy Completions API](/docs/api-reference/completions), when requested, provides the log probabilities of each output token, and a limited number of the most likely tokens at each token position alongside their log probabilities. This can be useful in some cases to assess the confidence of the model in its output, or to examine alternative responses the model might have given.
Completions API Legacy
The completions API endpoint received its final update in July 2023 and has a different interface than the new chat completions endpoint. Instead of the input being a list of messages, the input is a freeform text string called a `prompt`.
An example legacy Completions API call looks like the following:
<CodeSample
defaultLanguage="python"
code={{
python: `
from openai import OpenAI
client = OpenAI()\n
response = client.completions.create(
model="gpt-3.5-turbo-instruct",
prompt="Write a tagline for an ice cream shop."
)
`.trim(),
"node.js": `
const completion = await openai.completions.create({
model: 'gpt-3.5-turbo-instruct',
prompt: 'Write a tagline for an ice cream shop.'
});
`.trim(),
}}
/>
See the full [API reference documentation](https://platform.openai.com/docs/api-reference/completions) to learn more.
#### Inserting text
The completions endpoint also supports inserting text by providing a [suffix](/docs/api-reference/completions/create#completions-create-suffix) in addition to the standard prompt which is treated as a prefix. This need naturally arises when writing long-form text, transitioning between paragraphs, following an outline, or guiding the model towards an ending. This also works on code, and can be used to insert in the middle of a function or file.
To illustrate how suffix context effects generated text, consider the prompt, “Today I decided to make a big change.” Theres many ways one could imagine completing the sentence. But if we now supply the ending of the story: “Ive gotten many compliments on my new hair!”, the intended completion becomes clear.
> I went to college at Boston University. After getting my degree, I decided to make a change**. A big change!**
> **I packed my bags and moved to the west coast of the United States.**
> Now, I cant get enough of the Pacific Ocean!
By providing the model with additional context, it can be much more steerable. However, this is a more constrained and challenging task for the model. To get the best results, we recommend the following:
**Use `max_tokens` > 256.** The model is better at inserting longer completions. With too small `max_tokens`, the model may be cut off before it's able to connect to the suffix. Note that you will only be charged for the number of tokens produced even when using larger `max_tokens`.
**Prefer `finish_reason` == "stop".** When the model reaches a natural stopping point or a user provided stop sequence, it will set `finish_reason` as "stop". This indicates that the model has managed to connect to the suffix well and is a good signal for the quality of a completion. This is especially relevant for choosing between a few completions when using n > 1 or resampling (see the next point).
**Resample 3-5 times.** While almost all completions connect to the prefix, the model may struggle to connect the suffix in harder cases. We find that resampling 3 or 5 times (or using best_of with k=3,5) and picking the samples with "stop" as their `finish_reason` can be an effective way in such cases. While resampling, you would typically want a higher temperatures to increase diversity.
Note: if all the returned samples have `finish_reason` == "length", it's likely that max_tokens is too small and model runs out of tokens before it manages to connect the prompt and the suffix naturally. Consider increasing `max_tokens` before resampling.
**Try giving more clues.** In some cases to better help the models generation, you can provide clues by giving a few examples of patterns that the model can follow to decide a natural place to stop.
> How to make a delicious hot chocolate:
>
> 1.** Boil water**
> **2. Put hot chocolate in a cup**
> **3. Add boiling water to the cup**
> 4. Enjoy the hot chocolate
> 1. Dogs are loyal animals.
> 2. Lions are ferocious animals.
> 3. Dolphins** are playful animals.**
> 4. Horses are majestic animals.
### Completions response format
An example completions API response looks as follows:
```
{
"choices": [
{
"finish_reason": "length",
"index": 0,
"logprobs": null,
"text": "\n\n\"Let Your Sweet Tooth Run Wild at Our Creamy Ice Cream Shack"
}
],
"created": 1683130927,
"id": "cmpl-7C9Wxi9Du4j1lQjdjhxBlO22M61LD",
"model": "gpt-3.5-turbo-instruct",
"object": "text_completion",
"usage": {
"completion_tokens": 16,
"prompt_tokens": 10,
"total_tokens": 26
}
}
```
In Python, the output can be extracted with `response['choices'][0]['text']`.
The response format is similar to the response format of the Chat Completions API.
## Chat Completions vs. Completions
The Chat Completions format can be made similar to the completions format by constructing a request using a single user message. For example, one can translate from English to French with the following completions prompt:
```
Translate the following English text to French: "{text}"
```
And an equivalent chat prompt would be:
```
[{"role": "user", "content": 'Translate the following English text to French: "{text}"'}]
```
Likewise, the completions API can be used to simulate a chat between a user and an assistant by formatting the input [accordingly](https://platform.openai.com/playground/p/default-chat?model=gpt-3.5-turbo-instruct).
The difference between these APIs is the underlying models that are available in each. The chat completions API is the interface to our most capable model (`gpt-4o`), and our most cost effective model (`gpt-3.5-turbo`).
### Prompt engineering
An awareness of the best practices for working with OpenAI models can make a significant difference in application performance. The failure modes that each exhibit and the ways of working around or correcting those failure modes are not always intuitive. There is an entire field related to working with language models which has come to be known as "prompt engineering", but as the field has progressed its scope has outgrown merely engineering the prompt into engineering systems that use model queries as components. To learn more, read our guide on [prompt engineering](/docs/guides/prompt-engineering) which covers methods to improve model reasoning, reduce the likelihood of model hallucinations, and more. You can also find many useful resources including code samples in the [OpenAI Cookbook](https://cookbook.openai.com).
## FAQ
### Which model should I use?
We generally recommend that you default to using either `gpt-4o`, `gpt-4-turbo`, or `gpt-3.5-turbo`. If your use case requires high intelligence or reasoning about images as well as text, we recommend you evaluate both `gpt-4o` and `gpt-4-turbo` (although they have very similar intelligence, note that `gpt-4o` is both faster and cheaper). If your use case requires the fastest speed and lowest cost, we recommend `gpt-3.5-turbo` since it is optimized for these aspects.
`gpt-4o` and `gpt-4-turbo` are also less likely than `gpt-3.5-turbo` to make up information, a behavior known as "hallucination". Finally, `gpt-4o` and `gpt-4-turbo` have a context window that supports up to 128,000 tokens compared to 4,096 tokens for `gpt-3.5-turbo`, meaning they can reason over much more information at once.
We recommend experimenting in the [playground](https://platform.openai.com/playground?mode=chat) to investigate which models provide the best price performance trade-off for your usage. A common design pattern is to use several distinct query types which are each dispatched to the model appropriate to handle them.
### How should I set the temperature parameter?
Lower values for temperature result in more consistent outputs (e.g. 0.2), while higher values generate more diverse and creative results (e.g. 1.0). Select a temperature value based on the desired trade-off between coherence and creativity for your specific application. The temperature can range is from 0 to 2.
### Is fine-tuning available for the latest models?
See the [fine-tuning guide](/docs/guides/fine-tuning) for the latest information on which models are available for fine-tuning and how to get started.
### Do you store the data that is passed into the API?
As of March 1st, 2023, we retain your API data for 30 days but no longer use your data sent via the API to improve our models. Learn more in our [data usage policy](https://openai.com/policies/usage-policies). Some endpoints offer [zero retention](/docs/models/default-usage-policies-by-endpoint).
### How can I make my application more safe?
If you want to add a moderation layer to the outputs of the Chat API, you can follow our [moderation guide](/docs/guides/moderation) to prevent content that violates OpenAIs usage policies from being shown. We also encourage you to read our [safety guide](/docs/guides/safety-best-practices) for more information on how to build safer systems.
### Should I use ChatGPT or the API?
[ChatGPT](https://chatgpt.com) offers a chat interface for our models and a range of built-in features such as integrated browsing, code execution, plugins, and more. By contrast, using OpenAIs API provides more flexibility but requires that you write code or send the requests to our models programmatically.