Создание многоагентных приложений становится простым с помощью этого SDK с открытым исходным кодом, и его можно использовать с любым совместимым с OpenAI LLM.
Делиться

Используя слои абстракции, построенные поверх фундаментально простых идей, некоторые разработчики фреймворков агентов, похоже, считают, что сложность — это достоинство.
Я склонен следовать максиме Эйнштейна: «Все должно быть сделано настолько простым, насколько это возможно, но не проще». Итак, позвольте мне показать вам структуру, которую легко использовать и легко понять.
OpenAI применяет совершенно иной подход, нежели другие разработчики фреймворков: они не пытаются быть умными, они стараются быть понятными.
В этой статье я покажу, как можно создавать многоагентные приложения с использованием открытого SDK OpenAI.
Мы увидим, как создать простое приложение с одним агентом, а затем перейдем к изучению многоагентных конфигураций. Мы рассмотрим вызов инструментов, линейные и иерархические конфигурации, передачи от одного агента к другому и использование агентов в качестве инструментов.
В частности, мы увидим следующие примеры:
- Простой звонок агенту
- Агент, использующий инструменты
- Передача дел от одного агента другому
- Передача нескольким агентам
- Использование агентов в качестве инструментов
- Иерархическая оркестровка агентов с использованием агентов в качестве инструментов
Агент SDK
Agent SDK основан на нескольких концепциях, необходимых для агентных и многоагентных систем, и создает вокруг них фреймворк — он заменяет Swarm, образовательный фреймворк, разработанный OpenAI, где эти концепции были определены и реализованы. Agent SDK строится на Swarm и расширяет его, сохраняя при этом его основополагающие принципы легкости и простоты.
Это может показаться простым, но с помощью этой структуры можно создавать сложные агентские системы, в которых агенты используют инструменты (которые могут быть другими агентами), передают управление другим агентам и могут быть организованы любым количеством хитроумных способов.
Установка осуществляется через pip или ваш любимый инструмент управления пакетами, а пакет называется openai-agents. Я предпочитаю UV, поэтому для начала нового проекта я бы сделал что-то вроде следующего.
uv init agentTest cd agentTest uv add openai-agents
Простой звонок агенту
Простой вызов агента показан на схеме ниже.


Это диаграмма потока данных, которая показывает работающий агент как процесс с входящими и исходящими данными. Поток, который запускает процесс, — это приглашение пользователя; агент делает один или несколько вызовов LLM и получает ответы. После завершения своей задачи он выводит ответ агента.
Ниже мы видим код базовой программы, которая использует SDK для реализации этого потока. Он создает экземпляр агента, дает ему имя и некоторые инструкции; затем он запускает его и выводит результат. Это похоже на первый пример из документации OpenAI, но здесь мы создадим приложение Streamlit.
Сначала импортируем библиотеки.
импортировать streamlit как st импортировать asyncio из агентов импортировать Агент, Бегун
Нам нужен пакет Streamlit, конечно, и asyncio, потому что мы будем использовать его функционал для ожидания завершения агента перед продолжением. Далее мы импортируем минимум из пакета агентов, Agent (для создания агента) и Runner (для запуска агента).
Ниже мы определяем код для создания и запуска агента.
агент = Агент(имя=»Помощник», инструкции=»Вы полезный помощник») async def run_agent(input_string): result = await Runner.run(agent, input_string) return result.final_output
Этот код использует модель по умолчанию из OpenAI (и предполагает, что у вас есть действительный ключ API, установленный как переменная среды — и с вас, конечно, будет взиматься плата, но для наших целей она не будет большой. Я потратил на это всего несколько десятков центов).
Сначала мы создаем экземпляр агента под названием «Помощник» с помощью нескольких простых инструкций, затем определяем асинхронную функцию, которая будет запускать его со строкой (запросом), предоставленной пользователем.
Функция запуска асинхронна; нам нужно дождаться завершения LLM, прежде чем продолжить, поэтому мы запустим функцию с помощью asyncio.
Мы определяем пользовательский интерфейс с помощью функций Streamlit.
st.title(«Простой запрос SDK агента») user_input = st.text_input(«Введите запрос и нажмите «Отправить»:») st.write(«Ответ:») response_container = st.container(height=300, border=True) if st.button(«Отправить»): response = asyncio.run(run_agent(user_input)) with response_container: st.markdown(response)
Это в основном самоочевидно. Пользователю предлагается ввести запрос и нажать кнопку «Отправить». При нажатии кнопки run_agent запускается через вызов asyncio.run. Результат отображается в прокручиваемом контейнере. Ниже приведен снимок экрана примера запуска.

Ваш результат может отличаться (магистры права известны тем, что не дают один и тот же ответ дважды).
Чтобы определить агента, дайте ему имя и некоторые инструкции. Запуск также прост; передайте агента и запрос. Запуск агента запускает цикл, который завершается, когда достигается окончательный ответ. Этот пример прост и не требует запуска цикла более одного раза, но агенту, который вызывает инструменты, может потребоваться пройти несколько итераций, прежде чем ответ будет завершен.
Результат легко отображается. Как мы видим, это атрибут final_output значения, возвращаемого Runner.
Эта программа использует значения по умолчанию для нескольких параметров, которые можно задать вручную, например, имя модели и настройки температуры для LLM. Agent SDK также использует API Responses по умолчанию. Это API только для OpenAI (по крайней мере, пока), поэтому, если вам нужно использовать SDK с другим LLM, вам придется переключиться на более широко поддерживаемый API Chat Completions.
из агентов импортировать set_default_openai_api set_default_openai_api(«chat_completions»)
Вначале для простоты мы будем использовать API Response по умолчанию.
Агент, использующий инструменты
Агенты могут использовать инструменты, и агент совместно с LLM решает, какие инструменты ему необходимо использовать, если таковые имеются.
Ниже представлена схема потока данных, на которой показан агент, использующий инструмент.

Он похож на простого агента, но мы можем видеть дополнительный процесс, инструмент, который использует агент. Когда агент делает вызов LLM, ответ укажет, нужно ли использовать инструмент. Если это так, то агент сделает этот вызов и отправит результат обратно в LLM. Опять же, ответ от LLM укажет, нужен ли еще один вызов инструмента. Агент будет продолжать этот цикл до тех пор, пока LLM больше не будет требовать ввода от инструмента. В этот момент агент может ответить пользователю.
Ниже представлен код для одного агента, использующего один инструмент.
Программа состоит из четырех частей:
- Импорт из библиотеки Agents и Википедии (которая будет использоваться в качестве инструмента).
- Определение инструмента — это просто функция с декоратором @function_tool.
- Определение агента, использующего инструмент.
- Запуск агента и печать результата в приложении Streamlit, как и раньше.
import streamlit as st import asyncio from agents import Agent, Runner, function_tool import wikipedia @function_tool def wikipedia_lookup(q: str) -> str: «»»Найдите запрос в Википедии и верните результат»»» return wikipedia.page(q).summary research_agent = Agent( name=»Research agent», instructions=»»»Вы исследуете темы с помощью Википедии и сообщаете о результатах. «»», model=»o4-mini», tools=[wikipedia_lookup], ) async def run_agent(input_string): result = await Runner.run(research_agent, input_string) return result.final_output # Streamlit UI st.title(«Простой агент, использующий инструменты») st.write(«Этот агент использует Википедию для поиска информации.») user_input = st.text_input(«Введите запрос и нажмите 'Отправить':») st.write(«Ответ:») response_container = st.container(height=300, border=True) if st.button(«Отправить»): response = asyncio.run(run_agent(user_input)) with response_container: st.markdown(response)
Инструмент ищет страницу Википедии и возвращает сводку через стандартный вызов библиотечной функции. Обратите внимание, что мы использовали подсказки типов и строку документации для описания функции, чтобы агент мог понять, как ее использовать.
Далее следует определение агента, и здесь мы видим, что параметров больше, чем раньше: мы указываем модель, которую хотим использовать, и список инструментов (в этом списке только один).
Запуск и печать результата производятся так же, как и раньше, и он добросовестно возвращает ответ (высоту Эйфелевой башни).

Это простой тест агента, использующего инструмент, который требует только одного поиска. Более сложный запрос может использовать инструмент более одного раза для сбора информации.
Например, я попросил: «Найдите название знаменитой башни в Париже, найдите ее высоту, а затем найдите дату рождения ее создателя». Для этого потребовалось два вызова инструмента: один для получения информации об Эйфелевой башне, а второй — для поиска даты рождения Густава Эйфеля.
Этот процесс не отражается в конечном выводе, но мы можем увидеть этапы, через которые прошел агент, просматривая необработанные сообщения в результатах агента. Я распечатал result.raw_messages для запроса выше, а результат показан ниже.
[ 0:»ModelResponse(output=[ResponseReasoningItem(id='rs_6849968a438081a2b2fda44aa5bc775e073e3026529570c1', summary=[], type='reasoning', status=None), ResponseFunctionToolCall(arguments='{«q»:»Эйфелева башня»}', call_id='call_w1iL6fHcVqbPFE1kAuCGPFok', name='wikipedia_lookup', type='function_call', id='fc_6849968c0c4481a29a1b6c0ad80fba54073e3026529570c1', status='completed')], использование=Использование(запросы=1, входные_токены=111, выходные_токены=214, общее_токены=325), response_id='resp_68499689c60881a2af6411d137c13d82073e3026529570c1')» 1:»ModelResponse(выход=[ResponseReasoningItem(id='rs_6849968e00ec81a280bf53dcd30842b1073e3026529570c1', резюме=[], тип='рассуждение', статус=Нет), ResponseFunctionToolCall(аргументы='{«q»:»Гюстав Эйфель»}', call_id='call_DfYTuEjjBMulsRNeCZaqvV8w', name='wikipedia_lookup', type='function_call', id='fc_6849968e74ac81a298dc17d8be4012a7073e3026529570c1', status='завершено')], usage=Использование(запросы=1, входные_токены=940, выходные_токены=23, общее_токены=963), response_id='resp_6849968d7c3081a2acd7b837cfee5672073e3026529570c1')» 2:»ModelResponse(output=[ResponseReasoningItem(id='rs_68499690e33c81a2b0bda68a99380840073e3026529570c1', summary=[], type='reasoning', status=None), ResponseOutputMessage(id='msg_6849969221a081a28ede4c52ea34aa54073e3026529570c1', content=[ResponseOutputText(annotations=[], text='Знаменитая башня в Париже — Эйфелева башня. n• Высота: 330 метров (1083 фута) n• Создатель: Александр Гюстав Эйфель, родился 15 декабря 1832 года', type='output_text')], role='assistant', status='завершено', type='сообщение')], usage=Использование(запросы=1, входные_токены=1190, выходные_токены=178, общее_токены=1368), response_id='resp_6849968ff15481a292939a6eed683216073e3026529570c1')» ]
Вы можете видеть, что есть три ответа: первые два являются результатом двух вызовов инструментов, а последний — конечный вывод, который генерируется из информации, полученной из вызовов инструментов.
Мы вскоре снова увидим инструменты, когда будем использовать агентов в качестве инструментов, но сейчас мы рассмотрим, как можно использовать несколько агентов, которые взаимодействуют друг с другом.
Несколько агентов
Многие агентские приложения требуют только одного агента, и это уже большой шаг вперед по сравнению с простыми завершениями чата, которые вы найдете в интерфейсах чата LLM, таких как ChatGPT. Агенты работают в циклах и могут использовать инструменты, что делает даже одного агента довольно мощным. Однако несколько агентов, работающих вместе, могут достичь еще более сложного поведения.
В соответствии со своей простой философией OpenAI не пытается включать абстракции оркестровки агентов, как некоторые другие фреймворки. Но, несмотря на свою простую конструкцию, он поддерживает построение как простых, так и сложных конфигураций.
Сначала мы рассмотрим передачи, когда один агент передает управление другому. После этого мы увидим, как агенты могут быть объединены иерархически.
Передачи
Когда агент решает, что он выполнил свою задачу, и передает информацию другому агенту для дальнейшей работы, это называется передачей.
Существует два основных способа осуществления передачи: при агентской передаче вся история сообщений передается от одного агента другому. Это немного похоже на то, как если бы вы позвонили в банк, но человек, с которым вы сначала разговаривали, не знает ваших конкретных обстоятельств, и поэтому передает вас тому, кто знает. Разница в том, что в случае агента ИИ новый агент имеет запись всего, что было сказано предыдущему.
Второй метод — программная передача. Это когда только необходимая информация, предоставленная одним агентом, передается другому (через обычные методы программирования).
Давайте сначала рассмотрим программные передачи.
Программные передачи
Иногда новому агенту не нужно знать всю историю транзакции; возможно, требуется только конечный результат. В этом случае вместо полной передачи можно организовать программную передачу, при которой второму агенту передаются только соответствующие данные.

На схеме показана типовая программная передача обслуживания между двумя агентами.
Ниже приведен пример этой функциональности, где один агент находит информацию по теме, а другой берет эту информацию и пишет статью, подходящую для детей.
Для простоты мы не будем использовать в этом примере наш инструмент Википедии; вместо этого мы полагаемся на знания LLM.
import streamlit as st import asyncio from agents import Agent, Runner writer_agent = Agent( name=»Writer agent», instructions=f»»»Перепишите статью так, чтобы она подходила для детей в возрасте около 8 лет. Будьте энтузиастом темы — все это приключение!»»», model=»o4-mini», ) researcher_agent = Agent( name=»Research agent», instructions=f»»»Вы исследуете темы и сообщаете о результатах.»»», model=»o4-mini», ) async def run_agent(input_string): result = await Runner.run(researcher_agent, input_string) result2 = await Runner.run(writer_agent, result.final_output) return result2 # Streamlit UI st.title(«Writer Agent») st.write(«Пишите материалы для детей.») user_input = st.text_input(«Введите запрос и нажмите 'Отправить':») st.write(«Ответ:») response_container = st.container(height=300, border=True) if st.button(«Send»): response = asyncio.run(run_agent(user_input)) with response_container: st.markdown(response.final_output) st.write(response) st.json(response.raw_responses)
В приведенном выше коде мы определяем двух агентов: один исследует тему, а другой создает текст, подходящий для детей.
Эта техника не опирается на какие-либо специальные функции SDK; она просто запускает одного агента, получает вывод в result и использует его в качестве ввода для следующего агента (вывод в result2). Это то же самое, что использовать вывод одной функции в качестве ввода для следующей в обычном программировании. Действительно, это именно то, чем он является.
Агентские передачи
Однако иногда агенту необходимо знать историю того, что произошло ранее. Вот где вступают в дело OpenAI Agents Handoffs.
Ниже представлена диаграмма потока данных, представляющая Agentic Handoff. Вы увидите, что она очень похожа на Programmatic Handoff; разница в том, что данные передаются второму агенту, а также в том, что возможен вывод от первого агента, когда handoff не требуется.

Код также похож на предыдущий пример. Я немного подправил инструкции, но главное отличие — это список передач в researcher_agent. Это не отличается от того, как мы объявляем инструменты.
Исследовательскому агенту разрешено передавать работу Детскому агенту-писателю, когда он завершает свою работу. Эффект этого заключается в том, что Детский агент-писатель не только берет на себя управление обработкой, но и знает, что сделал Исследовательский агент, а также исходную подсказку.
Однако есть еще одно важное отличие. Агент должен сам определить, происходит ли передача или нет. В примере, приведенном ниже, я поручил агенту написать что-то подходящее для детей, и поэтому он передал работу агенту Kids' Writer. Если бы я не сказал ему сделать это, он бы просто вернул исходный текст.
import streamlit as st import asyncio from agents import Agent, Runner kids_writer_agent = Agent( name=»Kids Writer Agent», instructions=f»»»Перепишите статью так, чтобы она подходила для детей в возрасте около 8 лет. Будьте энтузиастом темы — все это приключение!»»», model=»o4-mini», ) researcher_agent = Agent( name=»Research agent», instructions=f»»»Ответьте на запрос и сообщите результаты.»»», model=»o4-mini», handoffs = [kids_writer_agent] ) async def run_agent(input_string): result = await Runner.run(researcher_agent, input_string) return result # Streamlit UI st.title(«Writer Agent2») st.write(«Пишите материалы для детей.») user_input = st.text_input(«Введите запрос и нажмите 'Отправить':») st.write(«Ответ:») response_container = st.container(height=300, border=True) if st.button(«Send»): response = asyncio.run(run_agent(user_input)) with response_container: st.markdown(response.final_output) st.write(response) st.json(response.raw_responses)
На скриншоте этого нет, но я добавил код для вывода ответа и raw_responses, чтобы вы могли увидеть передачу в действии, если запустите код самостоятельно.
Ниже представлен скриншот этого агента.

Агент может иметь список передач в своем распоряжении, и он будет разумно выбирать правильного агента (или ни одного) для передачи. Вы можете видеть, как это было бы полезно в ситуации обслуживания клиентов, когда сложный запрос клиента может быть передан через ряд более опытных агентов, каждый из которых должен знать историю запросов.
Теперь мы рассмотрим, как можно использовать передачи обслуживания, в которых участвуют несколько агентов.
Передача нескольким агентам
Теперь мы увидим новую версию предыдущей программы, в которой исследовательский агент выбирает разных агентов в зависимости от возраста читателя.
Работа агента заключается в создании текста для трех аудиторий: взрослых, подростков и детей. Исследовательский агент будет собирать информацию, а затем передавать ее одному из трех других агентов. Вот поток данных (обратите внимание, что я исключил ссылки на LLM для ясности — каждый агент общается с LLM, но мы можем рассматривать это как внутреннюю функцию агента).

А вот и код.
import streamlit as st import asyncio from agents import Agent, Runner, handoff adult_writer_agent = Agent( name=»Adult Writer Agent», instructions=f»»»Напишите статью на основе информации, что она подходит для взрослых, интересующихся культурой. «»», model=»o4-mini», ) teen_writer_agent = Agent( name=»Teen Writer Agent», instructions=f»»»Напишите статью на основе информации, что она подходит для подростков, которые хотят круто провести время. «»», model=»o4-mini», ) kid_writer_agent = Agent( name=»Kid Writer Agent», instructions=f»»»Напишите статью на основе информации, что она подходит для детей около 8 лет. Будьте энтузиастами! «»», model=»o4-mini», ) researcher_agent = Agent( name=»Research agent», instructions=f»»»Найдите информацию по заданной теме(ам). «»», model=»o4-mini», handoffs = [kid_writer_agent, teen_writer_agent, adult_writer_agent] ) async def run_agent(input_string): result = await Runner.run(researcher_agent, input_string) return result # Streamlit UI st.title(«Writer Agent3») st.write(«Пишите материалы для взрослых, подростков или детей.») user_input = st.text_input(«Введите запрос и нажмите «Отправить»:») st.write(«Ответ:») response_container = st.container(height=300, border=True) if st.button(«Отправить»): response = asyncio.run(run_agent(user_input)) with response_container: st.markdown(response.final_output) st.write(response) st.json(response.raw_responses)
Структура программы похожа, но теперь у нас есть набор агентов для передачи и их список в Research Agent. Инструкции в различных агентах говорят сами за себя, и программа правильно отреагирует на подсказку, например, «Написать эссе о Париже, Франция для детей» или «…для подростков» или «…для взрослых». Research Agent правильно выберет соответствующего Writer Agent для задачи.
На скриншоте ниже показан пример текста для подростков.

Подсказки, представленные в этом примере, просты. Более сложные подсказки, вероятно, дадут лучший и более последовательный результат, но цель здесь — показать методы, а не создать умное приложение.
Это один тип сотрудничества; другой — использовать других агентов в качестве инструментов. Это не слишком отличается от программной передачи, которую мы видели ранее.
Агенты как инструменты
Запуск агента — это вызов функции таким же образом, как вызов инструмента. Так почему бы не использовать агентов как интеллектуальные инструменты?
Вместо того чтобы передать управление новому агенту, мы используем его как функцию, которой мы передаем информацию и от которой получаем информацию обратно.
Ниже представлена схема потока данных, иллюстрирующая эту идею. В отличие от передачи, главный агент не передает общее управление другому агенту; вместо этого он разумно выбирает вызов агента, как если бы это был инструмент. Вызванный агент выполняет свою работу, а затем возвращает управление вызывающему агенту. Опять же, потоки данных к LLM были опущены для ясности.

Ниже представлен скриншот измененной версии предыдущей программы. Мы немного изменили природу приложения. Теперь основным агентом является турагент; он ожидает, что пользователь укажет ему пункт назначения и возрастную группу, для которой он должен писать. Пользовательский интерфейс изменен таким образом, что возрастная группа выбирается с помощью переключателя. Поле ввода текста должно быть пунктом назначения.

В логику приложения был внесен ряд изменений. Пользовательский интерфейс изменяет способ ввода информации, и это отражается в способе построения подсказки — мы используем f-строку для включения двух фрагментов данных в подсказку.
Кроме того, теперь у нас есть дополнительный агент, который форматирует текст. Другие агенты похожи (но обратите внимание, что подсказки были улучшены), и мы также используем структурированный вывод, чтобы гарантировать, что текст, который мы выводим, является именно тем, что мы ожидаем.
Однако по сути мы видим, что агенты-писатели и агенты-форматировщики указаны как инструменты в агенте-исследователе.
import streamlit as st import asyncio from agents import Agent, Runner, function_tool from pydantic import BaseModel class PRArticle(BaseModel): article_text: str commentary: str adult_writer_agent = Agent( name=»Adult Writer Agent», instructions=»»»Напишите статью на основе информации, которая подходит для взрослых, интересующихся культурой. Будьте зрелыми.»»», model=»gpt-4o», ) teen_writer_agent = Agent( name=»Teen Writer Agent», instructions=»»»Напишите статью на основе информации, которая подходит для подростков, которые хотят хорошо провести время. Будьте крутыми!»»», model=»gpt-4o», ) kid_writer_agent = Agent( name=»Kid Writer Agent», instructions=»»»Напишите статью на основе информации, которая подходит для детей около 8 лет. Будьте энтузиастами!»»», model=»gpt-4o», ) format_agent = Agent( name=»Format Agent», instructions=f»»»Отредактируйте статью, добавив заголовок и подзаголовки, и убедитесь, что текст отформатирован как Markdown. Верните только текст статьи.»»», model=»gpt-4o», ) researcher_agent = Agent( name=»Research agent», instructions=»»»Вы турагент, который найдет полезную информацию для своих клиентов всех возрастов. Найдите информацию о заданном месте назначения. Когда у вас будет результат, отправьте его соответствующему агенту-писателю для создания короткого PR-текста. Когда у вас будет результат, отправьте его агенту-форматировщику для окончательной обработки. «»», model=»gpt-4o», tools = [kid_writer_agent.as_tool( tool_name=»kids_article_writer», tool_description=»Напишите эссе для детей»,), teen_writer_agent.as_tool( tool_name=»teen_article_writer», tool_description=»Напишите эссе для подростков»,), adult_writer_agent.as_tool( tool_name=»adult_article_writer», tool_description=»Напишите эссе для взрослых»,), format_agent.as_tool( tool_name=»format_article», tool_description=»Добавьте заголовки и подзаголовки и отформатируйте как Markdown», ),], output_type = PRArticle ) async def run_agent(input_string): result = await Runner.run(researcher_agent, input_string) return result # Streamlit UI st.title(«Турагент») st.write(«Турагент напишет о направлениях для разных аудиторий.») destination = st.text_input(«Введите направление, выберите возрастную группу и нажмите «Отправить»:») age_group = st.radio(«Какая возрастная группа читателя?», [«Взрослый», «Подросток», «Ребенок»], horizontal=True, ) st.write(«Ответ:») response_container = st.container(height=500, border=True) if st.button(«Отправить»): response = asyncio.run(run_agent(f»Пункт назначения — {destination}, а возрастная группа читателя — {age_group}»)) с response_container: st.markdown(response.final_output.article_text) st.write(response) st.json(response.raw_responses)
Список инструментов немного отличается от того, что мы видели ранее:
- Имя инструмента — это имя агента плюс .agent_as_tool(), метод, который делает агент совместимым с другими инструментами.
- Инструменту необходимо указать несколько параметров — имя и описание.
Еще одно очень полезное дополнение — использование структурированных выходов, как упоминалось выше. Это отделяет текст, который нам нужен, от любых других комментариев, которые LLM может захотеть вставить. Если вы запустите код, вы увидите в raw_responses дополнительную информацию, которую генерирует LLM.
Использование структурированных результатов помогает получать последовательные результаты и решает проблему, которая меня особенно беспокоит.
Я попросил, чтобы вывод был пропущен через агент форматирования, который структурирует результат как Markdown. Это зависит от LLM, это зависит от подсказки, и кто знает, может быть, это зависит от времени суток или погоды, но всякий раз, когда я думаю, что все правильно, LLM внезапно вставляет ограждение Markdown. Поэтому вместо чистого:
## Это заголовок Это какой-то текст
Вместо этого я получаю:
Вот ваш текст, отформатированный как Markdown: ''' Markdown # Это заголовок Это какой-то текст '''
Бесит!
В любом случае, ответ, похоже, заключается в использовании структурированных выходов. Если вы попросите его отформатировать ответ как текст того, что вы хотите, плюс второе поле под названием «комментарий» или что-то в этом роде, он, похоже, сделает правильно. Любые посторонние вещи, которые LLM решит выдать, попадут во второе поле, а чистый Markdown — в текстовое поле.
Ладно, Шекспир, это не так: корректировка инструкций таким образом, чтобы они были более подробными, могла бы дать лучшие результаты (текущие подсказки очень просты). Но это работает достаточно хорошо, чтобы проиллюстрировать метод.
Заключение
Это лишь поверхностный взгляд на OpenAI Agents SDK. Спасибо за прочтение, и я надеюсь, что вы нашли это полезным. Мы увидели, как создавать агентов и как комбинировать их различными способами, и мы очень быстро рассмотрели структурированные выходы.
Примеры, конечно, простые, но я надеюсь, что они иллюстрируют простой способ организации работы агентов, не прибегая к сложным абстракциям и громоздким фреймворкам.
Код здесь использует API Response, потому что это значение по умолчанию. Однако он должен работать так же и с API Completions. Это значит, что вы не ограничены ChatGPT, и, немного повозившись, этот SDK можно использовать с любым LLM, который поддерживает API Completions OpenAI.
В документации OpenAI можно найти еще много полезной информации.
Источник: towardsdatascience.com



























