Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Модели чата — это языковые модели, оптимизированные для диалоговых интерфейсов. Новые модели ведут себя иначе, чем старые модели API завершения. Предыдущие модели были с вводом текста и выводом текста, что означает, что они принимали строку запроса и возвращали завершение для добавления в запрос. Однако последние модели предполагают ввод в виде беседы и вывод в виде сообщений. Модели ожидают входных данных в формате, аналогичном стенограмме чата. Они возвращают результат, представляющий сообщение, написанное в чате моделью. Этот формат был разработан специально для многоэтапных бесед, но он также может работать хорошо для сценариев, отличных от чата.
В этой статье описано, как приступить к работе с моделями завершения чата. Чтобы получить лучшие результаты, используйте описанные здесь методы. Не пытайтесь взаимодействовать с моделями так же, как с предыдущей серией моделей, поскольку эти модели часто бывают многословны и дают менее полезные ответы.
Необходимые условия
- Развернута модель завершения чатов Azure OpenAI.
- Установите библиотеку OpenAI Python:
pip install openai. - Для аутентификации Microsoft Entra ID установите Azure Identity:
pip install azure-identity. - Для примера подсчета токенов установите tiktoken:
pip install tiktoken. - Если вы используете
AZURE_OPENAI_API_KEYключи API, задайте переменную среды.
- Пакет SDK .NET 8.0 или более поздней версии.
- Для проверки подлинности Microsoft Entra ID установите Azure CLI и назначьте роль
Cognitive Services Userучетной записи пользователя. - Если вы используете
AZURE_OPENAI_API_KEYключи API, задайте переменную среды.
Работа с моделями завершения чата
В следующем фрагменте кода показан самый простой способ взаимодействия с моделями, используюющими API завершения чата.
Примечание
API ответов использует тот же стиль взаимодействия чата, но поддерживает последние функции, которые не поддерживаются с более старым API завершения чата.
from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
token_provider = get_bearer_token_provider(
DefaultAzureCredential(), "https://ai.azure.com/.default"
)
client = OpenAI(
base_url = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=token_provider,
)
response = client.chat.completions.create(
model="YOUR-DEPLOYMENT-NAME", # Replace with your model deployment name.
messages=[
{"role": "system", "content": "Assistant is a large language model trained by OpenAI."},
{"role": "user", "content": "Who were the founders of Microsoft?"}
]
)
#print(response)
print(response.model_dump_json(indent=2))
print(response.choices[0].message.content)
{
"id": "chatcmpl-8GHoQAJ3zN2DJYqOFiVysrMQJfe1P",
"choices": [
{
"finish_reason": "stop",
"index": 0,
"message": {
"content": "Microsoft was founded by Bill Gates and Paul Allen. They established the company on April 4, 1975. Bill Gates served as the CEO of Microsoft until 2000 and later as Chairman and Chief Software Architect until his retirement in 2008, while Paul Allen left the company in 1983 but remained on the board of directors until 2000.",
"role": "assistant",
"function_call": null
},
"content_filter_results": {
"hate": {
"filtered": false,
"severity": "safe"
},
"self_harm": {
"filtered": false,
"severity": "safe"
},
"sexual": {
"filtered": false,
"severity": "safe"
},
"violence": {
"filtered": false,
"severity": "safe"
}
}
}
],
"created": 1698892410,
"model": "gpt-4o",
"object": "chat.completion",
"usage": {
"completion_tokens": 73,
"prompt_tokens": 29,
"total_tokens": 102
},
"prompt_filter_results": [
{
"prompt_index": 0,
"content_filter_results": {
"hate": {
"filtered": false,
"severity": "safe"
},
"self_harm": {
"filtered": false,
"severity": "safe"
},
"sexual": {
"filtered": false,
"severity": "safe"
},
"violence": {
"filtered": false,
"severity": "safe"
}
}
}
]
}
Microsoft was founded by Bill Gates and Paul Allen. They established the company on April 4, 1975. Bill Gates served as the CEO of Microsoft until 2000 and later as Chairman and Chief Software Architect until his retirement in 2008, while Paul Allen left the company in 1983 but remained on the board of directors until 2000.
Каждый ответ включает в себя finish_reason. Возможные значения finish_reason :
- stop: API вернул полные выходные данные модели.
-
длина: неполные выходные данные модели из-за
max_tokensпараметра или предела токена. - content_filter: опустил содержимое из-за флага из фильтров содержимого.
- null: ответ API все еще не завершен или неполный.
Рассмотрите возможность установки max_tokens немного более высокого значения, чем обычно. Более высокое значение гарантирует, что модель не перестает создавать текст, прежде чем он достигнет конца сообщения.
Работа с API завершения чата
Модели OpenAI для завершения чатов обучены принимать входные данные в формате беседы. Параметр сообщений принимает массив объектов, где сообщения упорядочены по ролям. При использовании API Python используется список словарей.
Формат базового завершения чата:
{"role": "system", "content": "Provide some context and/or instructions to the model"},
{"role": "user", "content": "The user's message goes here"}
Беседа с одним примером ответа, за которым следует вопрос, будет выглядеть следующим образом:
{"role": "system", "content": "Provide some context and/or instructions to the model."},
{"role": "user", "content": "Example question goes here."},
{"role": "assistant", "content": "Example answer goes here."},
{"role": "user", "content": "First question/message for the model to actually respond to."}
Системная роль
Системная роль, также известная как системное сообщение, включается в начало массива. Это сообщение содержит начальные инструкции для модели. Вы можете предоставить различные сведения в системной роли, например:
- Краткое описание помощника.
- Черты личности помощника.
- Инструкции или правила, которые требуется выполнить помощнику.
- Данные или сведения, необходимые для модели, например соответствующие вопросы из часто задаваемых вопросов.
Вы можете настроить системную роль для вашего варианта использования или включить основные инструкции. Системная роль или сообщение является необязательным, но мы рекомендуем включить по крайней мере базовый, чтобы получить лучшие результаты.
Сообщения
После системной роли можно включить ряд сообщений между user и assistant.
{"role": "user", "content": "What is thermodynamics?"}
Чтобы активировать ответ от модели, завершите сообщением пользователя, чтобы указать, что наступила очередь помощника ответить. Кроме того, можно включить ряд примеров сообщений между пользователем и помощником в качестве способа обучения с использованием малых выборок.
Примеры запроса сообщения
В следующем разделе показаны примеры различных стилей запросов, которые можно использовать с моделями завершения чата. Эти примеры являются лишь отправной точкой. Вы можете экспериментировать с различными запросами на настройку поведения для собственных вариантов использования.
Базовый пример
Если вы хотите, чтобы модель завершения чата выглядела так же, как и chatgpt.com, можно использовать базовое системное сообщение, например Assistant is a large language model trained by OpenAI.
{"role": "system", "content": "Assistant is a large language model trained by OpenAI."},
{"role": "user", "content": "Who were the founders of Microsoft?"}
Пример с инструкциями
Для некоторых сценариев может потребоваться предоставить дополнительные инструкции модели, чтобы задать ограничения на её возможности.
{"role": "system", "content": "Assistant is an intelligent chatbot designed to help users answer their tax related questions.
Instructions:
- Only answer questions related to taxes.
- If you're unsure of an answer, you can say "I don't know" or "I'm not sure" and recommend users go to the IRS website for more information. "},
{"role": "user", "content": "When are my taxes due?"}
Использование данных для заземления
Вы также можете включить соответствующие данные или сведения в системное сообщение, чтобы предоставить модели дополнительный контекст для беседы. Если необходимо включить только небольшое количество сведений, его можно жестко закодировать в системном сообщении. Если у вас есть большой объем данных, о которых следует знать модели, можно использовать embeddings или продукт, например Поиск с использованием ИИ Azure для получения наиболее важных сведений во время запроса.
{"role": "system", "content": "Assistant is an intelligent chatbot designed to help users answer technical questions about Azure OpenAI in Microsoft Foundry Models. Only answer questions using the context below and if you're not sure of an answer, you can say 'I don't know'.
Context:
- Azure OpenAI provides REST API access to OpenAI's powerful language models including the GPT-3, Codex and Embeddings model series.
- Azure OpenAI gives customers advanced language AI with OpenAI GPT-4o, GPT-image series, and Embeddings models with the security and enterprise promise of Azure. Azure OpenAI co-develops the APIs with OpenAI, ensuring compatibility and a smooth transition from one to the other.
- At Microsoft, we're committed to the advancement of AI driven by principles that put people first. Microsoft has made significant investments to help guard against abuse and unintended harm, which includes requiring applicants to show well-defined use cases, incorporating Microsoft’s principles for responsible AI use."
},
{"role": "user", "content": "What is Azure OpenAI?"}
Обучение с использованием небольшого количества примеров для завершения диалогов
Вы также можете предоставить модели пару примеров. Подход для обучения с малым количеством примеров немного изменился из-за нового формата подсказки. Теперь вы можете включить ряд сообщений между пользователем и помощником в запросе в виде нескольких примеров. Используя эти примеры, вы можете подготовить ответы на распространенные вопросы, чтобы настроить модель или обучить её конкретному поведению.
В этом примере показано, как использовать обучение с малого числа примеров с GPT-35-Turbo и GPT-4. Вы можете поэкспериментировать с различными подходами, чтобы увидеть, что лучше всего подходит для вашего варианта использования.
{"role": "system", "content": "Assistant is an intelligent chatbot designed to help users answer their tax related questions. "},
{"role": "user", "content": "When do I need to file my taxes by?"},
{"role": "assistant", "content": "In 2023, you will need to file your taxes by April 18th. The date falls after the usual April 15th deadline because April 15th falls on a Saturday in 2023. For more details, see https://www.irs.gov/filing/individuals/when-to-file."},
{"role": "user", "content": "How can I check the status of my tax refund?"},
{"role": "assistant", "content": "You can check the status of your tax refund by visiting https://www.irs.gov/refunds"}
Использование завершения чата для сценариев, отличных от чата
API завершения чата предназначен для работы с несколькими беседами, но он также хорошо подходит для сценариев, отличных от чата.
Например, для сценария извлечения сущностей можно использовать следующую подсказку:
{"role": "system", "content": "You are an assistant designed to extract entities from text. Users will paste in a string of text and you will respond with entities you've extracted from the text as a JSON object. Here's an example of your output format:
{
"name": "",
"company": "",
"phone_number": ""
}"},
{"role": "user", "content": "Hello. My name is Robert Smith. I'm calling from Contoso Insurance, Delaware. My colleague mentioned that you are interested in learning about our comprehensive benefits policy. Could you give me a call back at (555) 346-9322 when you get a chance so we can go over the benefits?"}
Создание базового цикла беседы
В примерах до сих пор показана базовая механика взаимодействия с API завершения чата. В этом примере показано, как создать цикл беседы, выполняющий следующие действия:
- Непрерывно принимает входные данные консоли и правильно форматирует его как часть списка сообщений в качестве содержимого роли пользователя.
- Выводит ответы, которые печатаются в консоли, форматируются и добавляются в список сообщений как содержимое роли помощника.
Каждый раз, когда задаётся новый вопрос, расшифровка предыдущей части беседы отправляется вместе с последним вопросом. Так как у модели нет памяти, необходимо отправить обновленную расшифровку с каждым новым вопросом или модель потеряет контекст предыдущих вопросов и ответов.
from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
token_provider = get_bearer_token_provider(
DefaultAzureCredential(), "https://ai.azure.com/.default"
)
client = OpenAI(
base_url = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=token_provider,
)
conversation=[{"role": "system", "content": "You are a helpful assistant."}]
while True:
user_input = input("Q:")
conversation.append({"role": "user", "content": user_input})
response = client.chat.completions.create(
model="YOUR-DEPLOYMENT-NAME", # Replace with your model deployment name.
messages=conversation
)
conversation.append({"role": "assistant", "content": response.choices[0].message.content})
print("\n" + response.choices[0].message.content + "\n")
При запуске предыдущего кода вы получите пустое окно консоли. Введите первый вопрос в окне и выберите Enter ключ. После возврата ответа можно повторить процесс и задать вопросы.
Управление беседами
Предыдущий пример выполняется до тех пор, пока не будет достигнуто максимальное количество токенов модели (контекстное окно). С каждым задаваемым вопросом и получаемым ответом, список messages увеличивается в размерах. Общее количество токенов messages плюс количество запрошенных выходных токенов должно оставаться в пределах модели, иначе запрос завершится ошибкой. Обратитесь к странице моделей, чтобы узнать текущие ограничения на количество токенов.
Вы обязаны убедиться, что запрос и завершение находятся в пределах лимита токенов. Для длительных бесед необходимо отслеживать количество токенов и отправлять модели только запрос, который находится в пределах допустимого. Кроме того, с помощью API ответов можно поручить API обработку и управление усечением истории беседы.
В следующем примере кода показан простой пример цикла чата с методом обработки количества токенов 4096 с помощью библиотеки tiktoken OpenAI.
Возможно, вам потребуется обновить версию tiktoken с pip install tiktoken --upgrade.
import tiktoken
from openai import OpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
token_provider = get_bearer_token_provider(
DefaultAzureCredential(), "https://ai.azure.com/.default"
)
client = OpenAI(
base_url = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/",
api_key=token_provider,
)
system_message = {"role": "system", "content": "You are a helpful assistant."}
max_response_tokens = 250
token_limit = 4096
conversation = []
conversation.append(system_message)
def num_tokens_from_messages(messages, model="gpt-4o"):
"""Return the number of tokens used by a list of messages."""
try:
encoding = tiktoken.encoding_for_model(model)
except KeyError:
print("Warning: model not found. Using o200k_base encoding.")
encoding = tiktoken.get_encoding("o200k_base")
if model in {
"gpt-4o",
"gpt-4o-mini",
"gpt-5",
"gpt-4.1",
"o1",
"o1-mini",
"o3",
"o3-mini",
"o4-mini",
}:
tokens_per_message = 3
tokens_per_name = 1
elif any(model.startswith(prefix) for prefix in [
"gpt-4o-",
"gpt-5-",
"gpt-4.1-",
"o1-",
"o3-",
"o4-mini-",
]):
tokens_per_message = 3
tokens_per_name = 1
else:
raise NotImplementedError(
f"""num_tokens_from_messages() is not implemented for model {model}. """
)
num_tokens = 0
for message in messages:
num_tokens += tokens_per_message
for key, value in message.items():
num_tokens += len(encoding.encode(value))
if key == "name":
num_tokens += tokens_per_name
num_tokens += 3
return num_tokens
while True:
user_input = input("Q:")
conversation.append({"role": "user", "content": user_input})
conv_history_tokens = num_tokens_from_messages(conversation, model="gpt-4o")
while conv_history_tokens + max_response_tokens >= token_limit:
del conversation[1]
conv_history_tokens = num_tokens_from_messages(conversation, model="gpt-4o")
response = client.chat.completions.create(
model="YOUR-DEPLOYMENT-NAME",
messages=conversation,
temperature=0.7,
max_tokens=max_response_tokens
)
conversation.append({"role": "assistant", "content": response.choices[0].message.content})
print("\n" + response.choices[0].message.content + "\n")
В этом примере после достижения количества токенов из расшифровки беседы удаляются самые старые сообщения. Для повышения эффективности del используется вместо pop(). Мы начинаем с индекса 1, чтобы всегда сохранять системное сообщение и удалять только сообщения пользователя или помощника. С течением времени этот метод управления беседой может привести к снижению качества беседы, так как модель постепенно теряет контекст предыдущих частей беседы.
Альтернативный подход — лимитировать длительность беседы максимальной длиной токена или ограничить до определенного числа переходов. После достижения максимального предела токенов модель теряет контекст, если вы позволите продолжить беседу. Вы можете предложить пользователю начать новую беседу и очистить список сообщений, чтобы начать новую беседу с полным ограничением маркера.
Упрощённая версия одного из примеров сборника OpenAI для подсчёта токенов была продемонстрирована ранее.
Устранение неполадок
Не удалось завершить генерацию, так как модель сгенерировала недопустимый выходной Юникод.
| Код ошибки | Сообщение об ошибке | Обходное решение |
|---|---|---|
| 500 | 500 — Внутренняя ошибка сервера: код ошибки: 500 — {"error": {"message": "Не удалось создать завершение, так как модель сгенерировала недопустимый вывод Юникода"}} | Вы можете свести к минимуму возникновение этих ошибок, уменьшая температуру запросов до менее 1 и обеспечивая использование клиента с логикой повторных попыток. Повторная попытка выполнения запроса часто приводит к успешному ответу. |
Распространенные ошибки
- 401/403 (проверка подлинности): проверьте ключ API или убедитесь, что у вас есть Microsoft Entra ID доступ к ресурсу OpenAI Azure.
-
400/404 (развертывание не найдено): убедитесь, что
modelсоответствует имени развертывания. -
Недопустимый URL-адрес: убедитесь, что
base_urlзаканчивается/openai/v1/.
Настройка
Создайте консольное приложение .NET:
dotnet new console -n chat-completions cd chat-completionsУстановите необходимые пакеты NuGet:
dotnet add package OpenAI --prerelease dotnet add package Azure.IdentityДля проверки подлинности без ключа с помощью Microsoft Entra ID войдите в Azure:
az login
Работа с моделями завершения чата
В следующем фрагменте кода показан самый простой способ взаимодействия с моделями, используюющими API завершения чата.
Примечание
API ответов использует тот же стиль взаимодействия чата, но поддерживает последние функции, которые не поддерживаются с помощью БОЛЕЕ старого API завершения чата.
using Azure.Identity;
using OpenAI;
using OpenAI.Chat;
using System.ClientModel.Primitives;
#pragma warning disable OPENAI001
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ChatClient client = new(
model: "YOUR-DEPLOYMENT-NAME",
authenticationPolicy: tokenPolicy,
options: new OpenAIClientOptions()
{
Endpoint = new Uri("https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/")
}
);
ChatCompletion completion = await client.CompleteChatAsync(
[
new SystemChatMessage("Assistant is a large language model trained by OpenAI."),
new UserChatMessage("Who were the founders of Microsoft?"),
]);
Console.WriteLine(completion.Content[0].Text);
Microsoft was founded by Bill Gates and Paul Allen. They established the company on April 4, 1975. Bill Gates served as the CEO of Microsoft until 2000 and later as Chairman and Chief Software Architect until his retirement in 2008, while Paul Allen left the company in 1983 but remained on the board of directors until 2000.
Каждый ответ включает себя FinishReason. Возможные значения FinishReason :
- Остановка. API вернул полные выходные данные модели.
-
Длина: Неполные выходные данные модели из-за
MaxOutputTokenCountпараметра или предела токенов. - ContentFilter: Содержимое опущено из-за флага фильтрации содержимого.
- null: ответ API все еще не завершен или неполный.
Рассмотрите возможность установки MaxOutputTokenCount немного более высокого значения, чем обычно. Более высокое значение гарантирует, что модель не перестает создавать текст, прежде чем он достигнет конца сообщения.
Работа с API завершения чата
Модели OpenAI для завершения чатов обучены принимать входные данные в формате беседы. Параметр сообщений принимает массив объектов, где сообщения упорядочены по ролям. При использовании пакета SDK для .NET используются строго типизированные классы сообщений для каждой роли.
Формат базового завершения чата:
new SystemChatMessage("Provide some context and/or instructions to the model"),
new UserChatMessage("The user's message goes here")
Беседа с одним примером ответа, за которым следует вопрос, будет выглядеть следующим образом:
new SystemChatMessage("Provide some context and/or instructions to the model."),
new UserChatMessage("Example question goes here."),
new AssistantChatMessage("Example answer goes here."),
new UserChatMessage("First question/message for the model to actually respond to.")
Системная роль
Системная роль, также известная как системное сообщение, включается в начало массива. Это сообщение содержит начальные инструкции для модели. Вы можете предоставить различные сведения в системной роли, например:
- Краткое описание помощника.
- Черты личности помощника.
- Инструкции или правила, которые требуется выполнить помощнику.
- Данные или сведения, необходимые для модели, например соответствующие вопросы из часто задаваемых вопросов.
Вы можете настроить системную роль для вашего варианта использования или включить основные инструкции. Системная роль или сообщение является необязательным, но мы рекомендуем включить по крайней мере базовый, чтобы получить лучшие результаты.
Сообщения
После системной роли можно включить ряд сообщений между user и assistant.
new UserChatMessage("What is thermodynamics?")
Чтобы активировать ответ от модели, завершите сообщением пользователя, чтобы указать, что наступила очередь помощника ответить. Кроме того, можно включить ряд примеров сообщений между пользователем и помощником в качестве способа обучения с использованием малых выборок.
Примеры запроса сообщения
В следующем разделе показаны примеры различных стилей запросов, которые можно использовать с моделями завершения чата. Эти примеры являются лишь отправной точкой. Вы можете экспериментировать с различными запросами на настройку поведения для собственных вариантов использования.
Базовый пример
Если вы хотите, чтобы модель завершения чата выглядела так же, как и chatgpt.com, можно использовать базовое системное сообщение, например Assistant is a large language model trained by OpenAI.
new SystemChatMessage("Assistant is a large language model trained by OpenAI."),
new UserChatMessage("Who were the founders of Microsoft?")
Пример с инструкциями
Для некоторых сценариев может потребоваться предоставить дополнительные инструкции модели, чтобы задать ограничения на её возможности.
new SystemChatMessage(@"Assistant is an intelligent chatbot designed to help users answer their tax related questions.
Instructions:
- Only answer questions related to taxes.
- If you're unsure of an answer, you can say ""I don't know"" or ""I'm not sure"" and recommend users go to the IRS website for more information."),
new UserChatMessage("When are my taxes due?")
Использование данных для заземления
Вы также можете включить соответствующие данные или сведения в системное сообщение, чтобы предоставить модели дополнительный контекст для беседы. Если необходимо включить только небольшое количество сведений, его можно жестко закодировать в системном сообщении. Если у вас есть большой объем данных, о которых следует знать модели, можно использовать embeddings или продукт, например Поиск с использованием ИИ Azure для получения наиболее важных сведений во время запроса.
new SystemChatMessage(@"Assistant is an intelligent chatbot designed to help users answer technical questions about Azure OpenAI in Microsoft Foundry Models. Only answer questions using the context below and if you're not sure of an answer, you can say 'I don't know'.
Context:
- Azure OpenAI provides REST API access to OpenAI's powerful language models including the GPT-3, Codex and Embeddings model series.
- Azure OpenAI gives customers advanced language AI with OpenAI GPT-4o, GPT-image series, and Embeddings models with the security and enterprise promise of Azure. Azure OpenAI co-develops the APIs with OpenAI, ensuring compatibility and a smooth transition from one to the other.
- At Microsoft, we're committed to the advancement of AI driven by principles that put people first. Microsoft has made significant investments to help guard against abuse and unintended harm, which includes requiring applicants to show well-defined use cases, incorporating Microsoft's principles for responsible AI use."),
new UserChatMessage("What is Azure OpenAI?")
Обучение с использованием небольшого количества примеров для завершения диалогов
Вы также можете предоставить модели пару примеров. Вы можете включить ряд сообщений между пользователем и помощником в запрос в качестве нескольких примеров. Используя эти примеры, вы можете подготовить ответы на распространенные вопросы, чтобы настроить модель или обучить её конкретному поведению.
new SystemChatMessage("Assistant is an intelligent chatbot designed to help users answer their tax related questions."),
new UserChatMessage("When do I need to file my taxes by?"),
new AssistantChatMessage("In 2023, you will need to file your taxes by April 18th. The date falls after the usual April 15th deadline because April 15th falls on a Saturday in 2023. For more details, see https://www.irs.gov/filing/individuals/when-to-file."),
new UserChatMessage("How can I check the status of my tax refund?"),
new AssistantChatMessage("You can check the status of your tax refund by visiting https://www.irs.gov/refunds")
Использование завершения чата для сценариев, отличных от чата
API завершения чата предназначен для работы с несколькими беседами, но он также хорошо подходит для сценариев, отличных от чата.
Например, для сценария извлечения сущностей можно использовать следующую подсказку:
new SystemChatMessage(@"You are an assistant designed to extract entities from text. Users will paste in a string of text and you will respond with entities you've extracted from the text as a JSON object. Here's an example of your output format:
{
""name"": """",
""company"": """",
""phone_number"": """"
}"),
new UserChatMessage("Hello. My name is Robert Smith. I'm calling from Contoso Insurance, Delaware. My colleague mentioned that you are interested in learning about our comprehensive benefits policy. Could you give me a call back at (555) 346-9322 when you get a chance so we can go over the benefits?")
Создание базового цикла беседы
В примерах до сих пор показана базовая механика взаимодействия с API завершения чата. В этом примере показано, как создать цикл беседы, выполняющий следующие действия:
- Непрерывно принимает входные данные консоли и правильно форматирует его как часть списка сообщений в качестве содержимого роли пользователя.
- Выводит ответы, которые печатаются в консоли, форматируются и добавляются в список сообщений как содержимое роли помощника.
Каждый раз, когда задаётся новый вопрос, расшифровка предыдущей части беседы отправляется вместе с последним вопросом. Так как у модели нет памяти, необходимо отправить обновленную расшифровку с каждым новым вопросом или модель потеряет контекст предыдущих вопросов и ответов.
using Azure.Identity;
using OpenAI;
using OpenAI.Chat;
using System.ClientModel.Primitives;
#pragma warning disable OPENAI001
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ChatClient client = new(
model: "YOUR-DEPLOYMENT-NAME",
authenticationPolicy: tokenPolicy,
options: new OpenAIClientOptions()
{
Endpoint = new Uri("https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/")
}
);
List<ChatMessage> conversation =
[
new SystemChatMessage("You are a helpful assistant."),
];
while (true)
{
Console.Write("Q: ");
string? userInput = Console.ReadLine();
if (string.IsNullOrWhiteSpace(userInput)) break;
conversation.Add(new UserChatMessage(userInput));
ChatCompletion response = await client.CompleteChatAsync(conversation);
string assistantMessage = response.Content[0].Text;
conversation.Add(new AssistantChatMessage(assistantMessage));
Console.WriteLine($"\n{assistantMessage}\n");
}
При запуске предыдущего кода вы получите пустое окно консоли. Введите первый вопрос в окне и выберите Enter ключ. После возврата ответа можно повторить процесс и задать вопросы.
Управление беседами
Предыдущий пример выполняется до тех пор, пока не будет достигнут предел токенов модели (окно контекста). С каждым задаваемым вопросом и получаемым ответом, список conversation увеличивается в размерах. Общее количество маркеров ваших сообщений плюс запрошенные выходные маркеры должны оставаться в пределах лимита модели, иначе запрос будет отклонен. Обратитесь к странице моделей, чтобы узнать текущие ограничения на количество токенов.
Вы обязаны убедиться, что запрос и завершение находятся в пределах лимита токенов. Для длительных бесед необходимо отслеживать количество токенов и отправлять модели только запрос, который находится в пределах допустимого. Кроме того, с API для ответов можно поручить API управление журналом бесед, включая его сокращение.
В следующем примере кода показан простой пример цикла чата, который обрезает журнал бесед, когда количество сохраненных сообщений приближается к ограничению. Он удаляет самые старые несистемные сообщения, чтобы поддерживать разговор в рамках.
Вы можете установить пакеты Microsoft.ML.Tokenizers и Microsoft.ML.Tokenizers.Data.0200kBase для точного подсчета маркеров:
dotnet add package Microsoft.ML.Tokenizers
dotnet add package Microsoft.ML.Tokenizers.Data.O200kBase
using Azure.Identity;
using Microsoft.ML.Tokenizers;
using OpenAI;
using OpenAI.Chat;
using System.ClientModel.Primitives;
#pragma warning disable OPENAI001
BearerTokenPolicy tokenPolicy = new(
new DefaultAzureCredential(),
"https://ai.azure.com/.default");
ChatClient client = new(
model: "YOUR-DEPLOYMENT-NAME",
authenticationPolicy: tokenPolicy,
options: new OpenAIClientOptions()
{
Endpoint = new Uri("https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/")
}
);
const int MaxResponseTokens = 250;
const int TokenLimit = 4096;
var tokenizer = TiktokenTokenizer.CreateForModel("gpt-4o");
List<ChatMessage> conversation =
[
new SystemChatMessage("You are a helpful assistant."),
];
static int CountTokens(TiktokenTokenizer tokenizer, IEnumerable<ChatMessage> messages)
{
int count = 3; // base overhead for reply priming
foreach (var message in messages)
{
count += 4; // per-message overhead
string content = message switch
{
SystemChatMessage s => s.Content[0].Text ?? string.Empty,
UserChatMessage u => u.Content[0].Text ?? string.Empty,
AssistantChatMessage a => a.Content[0].Text ?? string.Empty,
_ => string.Empty
};
count += tokenizer.CountTokens(content);
}
return count;
}
while (true)
{
Console.Write("Q: ");
string? userInput = Console.ReadLine();
if (string.IsNullOrWhiteSpace(userInput)) break;
conversation.Add(new UserChatMessage(userInput));
int historyTokens = CountTokens(tokenizer, conversation);
while (historyTokens + MaxResponseTokens >= TokenLimit && conversation.Count > 2)
{
conversation.RemoveAt(1); // remove oldest non-system message
historyTokens = CountTokens(tokenizer, conversation);
}
ChatCompletionOptions options = new() { MaxOutputTokenCount = MaxResponseTokens };
ChatCompletion response = await client.CompleteChatAsync(conversation, options);
string assistantMessage = response.Content[0].Text;
conversation.Add(new AssistantChatMessage(assistantMessage));
Console.WriteLine($"\n{assistantMessage}\n");
}
В этом примере после достижения количества токенов из расшифровки беседы удаляются самые старые сообщения. Мы всегда сохраняем системное сообщение и удаляем только сообщения пользователя или помощника. С течением времени этот метод управления беседой может привести к снижению качества беседы, так как модель постепенно теряет контекст предыдущих частей беседы.
Альтернативный подход — лимитировать длительность беседы максимальной длиной токена или ограничить до определенного числа переходов. После достижения максимального предела токенов модель теряет контекст, если вы позволите продолжить беседу. Вы можете предложить пользователю начать новую беседу и очистить список сообщений, чтобы начать новую беседу с полным ограничением маркера.
Устранение неполадок
Не удалось завершить генерацию, так как модель сгенерировала недопустимый выходной Юникод.
| Код ошибки | Сообщение об ошибке | Обходное решение |
|---|---|---|
| 500 | 500 — Внутренняя ошибка сервера: код ошибки: 500 — {"error": {"message": "Не удалось создать завершение, так как модель сгенерировала недопустимый вывод Юникода"}} | Вы можете свести к минимуму вероятность возникновения этих ошибок, уменьшив значение Temperature в вашем ChatCompletionOptions до менее чем 1 и обеспечив использование клиента с логикой повторных попыток. Повторная попытка выполнения запроса часто приводит к успешному ответу. |
Распространенные ошибки
- 401/403 (проверка подлинности): проверьте ключ API или убедитесь, что у вас есть Microsoft Entra ID доступ к ресурсу OpenAI Azure.
-
400/404 (развертывание не найдено): Убедитесь, что имя модели, передано конструктору
ChatClient, соответствует имени развертывания. -
Неверная конечная точка: убедитесь, что URI в
OpenAIClientOptionsуказывает наhttps://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/.