Введение
Всем привет, сегодня я расскажу вам о том, как можно делать агентов с помощью Pydantic AI.
Pydantic AI — фреймворк от создателей Pydantic — популярной библиотеки для валидации данных в Python с ядром на Rust.
Начнем с простых примеров в виде вызова LLM , а затем постепенно будем усложнять задачу, создавая более сложного агента.
Виртуальное окружение.
В качестве пакетного менеджера в данном проекте используется uv, однако вы можете использовать любой другой, удобный вам, просто имейте это ввиду при установке пакетов.
Репозиторий
Весь код примеров ниже доступен на github
Модель
В качестве стартовой LLM я предлагаю использовать Mistral, а потом переехать на что то более умное, но тоже бесплатное.
Если у вас нет токена, идем на сайт, проходим регистрацию и получаем токен, делаем Research план, который дает бесплатно много токенов.
Альтернативно: можно попробовать поднять локально что то через Ollama, если ваши ресурсы позволяют, однако дойдя до более сложной имплементации вы столкнетесь с тем, что агент не может решить проблему, поэтому гонять запросы в API проще.
Переменные
Создаем .env
файл, в нем пишем, например:
MISTRAL_API_KEY=ваш_токен
Зависимости на старте
uv add pydantic-ai python-dotenv
Начнем с простого
Дергаем LLM на простой вопрос
Попробуем просто дернуть Mistral API для вызова модельки и ответа на самый простой вопрос.
from pydantic_ai import Agent from pydantic_ai.models.mistral import MistralModel from pydantic_ai.providers.mistral import MistralProvider import os from dotenv import load_dotenv load_dotenv() model = MistralModel(model_name="mistral-large-latest", provider=MistralProvider( api_key=os.getenv("MISTRAL_API_KEY")), ) agent = Agent(model=model, retries=5) result_sync = agent.run_sync("Столица Гондураса?") print(result_sync.data) #Столица Гондураса — это город Тегусигальпа.
Как мы видим принцип написания вызова LLM немного отличается от того, что предлагает Langchain, а также значительно проще чем через Open AI SDK или чистый Mistral API.
Стоит отметить что с точки зрения Pydantic AI агент — это просто интерфейс взаимодействия с LLM, что отвечает в рамках данного фреймворка на вопрос о том, что-же такое этот ваш агент.
Ваш агент может состоять просто из вызова модели, можно добавить к нему системный промпт, формат вывода и другие параметры и это будет все тот же агент, просто с доп функционалом.

А вообще в документации прекрасно описано что такое агент и что он делает, поэтому едем дальше.
Logfire (опционально)
Для трассировки жизненного пути агента, можно воспользоваться Pydantic Logfire. Это позволит нам подробнее посмотреть что делает LLM когда вызывает какой-то тул, например. Ну или просто историю сообщений.
Logfire еще не такой продвинутый как тот же LangSmith или Langfuse, однако его просто поставить и с ним просто работать, особенно полезно, чтоб понять нужна ли нам та тула, которую мы только что придумалиWeather Model мы уже видели, а вот Supervisor Model лучше знать че она может получить, поэтому перечислим как опциональные модели от предыдуших действительно, или итак все норм работает.
Кстати там есть дашборды как и у конкурентов, но лично у меня они не показывают абсолютно ничего. А сидеть и самому написывать SQL-запросы как-то лень и не входит в задачу данной статьи.
Поэтому. проходим по ссылке выше, проходим регистрацию, создаем проект и наблюдаем за нашим агентом.
Вернемся к нашему агенту.
uv add logfire
Добавляем токен через конфигурацию logfire
и добавляем аргумент instrument=True
к агенту.
from pydantic_ai import Agent from pydantic_ai.models.mistral import MistralModel from pydantic_ai.providers.mistral import MistralProvider import logfire import os from dotenv import load_dotenv load_dotenv() logfire.configure(send_to_logfire=os.getenv("LOGFIRE_TOKEN")) model = MistralModel(model_name="mistral-large-latest", provider=MistralProvider (api_key=os.getenv("MISTRAL_API_KEY")), ) agent = Agent(model=model, retries=5, instrument=True) result_sync = agent.run_sync("Столица Гондураса?") print(result_sync.data)
Structured Output
Удобная штука, которая заставит модель выдать именно то, что вам надо.
from pydantic_ai import Agent from pydantic_ai.models.mistral import MistralModel from pydantic_ai.providers.mistral import MistralProvider from pydantic import BaseModel import logfire import os from dotenv import load_dotenv load_dotenv() class Cityname(BaseModel): city: str description: str logfire.configure(send_to_logfire=os.getenv("LOGFIRE_TOKEN")) model = MistralModel( model_name="mistral-large-latest", provider=MistralProvider(api_key=os.getenv("MISTRAL_API_KEY")), ) agent = Agent(model=model, retries=5, instrument=True, result_type=Cityname) result_sync = agent.run_sync("Столица Гондураса?") print(result_sync.data)
Поскольку в проде вы скорее всего должны гонять json-ы, иметь такую штуку и быстро её реализовать очень удобно и приятно.
Weather Agent Напишем агента для информирования о погодных условиях. Здесь мы можем начать с модели которую хотели бы получить на выходе. Например, я хотел бы знать какая скорость ветра, температура и стоит ли мне одеться потеплее или и в шортах норм будет.
class WeatherModel(BaseModel): temperature: float wind_speed: float description: str
Готово. Теперь напишем минимальный системный промпт, чтоб он хоть как то понимал что от него требуется.
system_prompt= """ Ты агент по погоде. Твоя задача предоставить temperature, wind_speed и description в поле description ты должен дать совет пользователю о том, во что ему одеться думай о комфорте человека в предоставленных тебе погодных условиях """
Суммарно наш агент будет выглядеть вот так:
from pydantic_ai import Agent from pydantic_ai.models.mistral import MistralModel from pydantic_ai.providers.mistral import MistralProvider from pydantic import BaseModel import logfire import os from dotenv import load_dotenv load_dotenv() system_prompt= """ Ты агент по погоде. Твоя задача предоставить temperature, wind_speed и description в поле description ты должен дать совет пользователю о том, во что ему одеться думай о комфорте человека в предоставленных тебе погодных условиях """ class WeatherModel(BaseModel): temperature: float wind_speed: float description: str logfire.configure(send_to_logfire=os.getenv("LOGFIRE_TOKEN")) model = MistralModel(model_name="mistral-large-latest", provider=MistralProvider(api_key=os.getenv("MISTRAL_API_KEY"))) agent = Agent(model=model, retries=5, instrument=True, result_type=WeatherModel, system_prompt=system_prompt) result_sync = agent.run_sync('Какая температура сейчас в Москве?') print(result_sync.data)
Кажется мы что то забыли, но попробуем запустить, вдруг случится магия и все итак заработает.
Конечно же он попытается ответить настолько, насколько может

Но магия не случилась, он ошибся, ведь LLM даже не знает какой сегодня день XD

А теперь добавим тулу Duck Duck Go search. Аналогичная тула есть и в Langchain, так что принципиально ничего не изменилось.
agent = Agent(model=model, tools=[duckduckgo_search_tool()], retries=5, instrument=True, result_type=WeatherModel, system_prompt=system_prompt)

О чудо он плюс минус близок к тому результату который мы от него ожидали. Погода действительно близка к нулю градусам по цельсию и действительно скорость ветра также ближе к нулю.
Travel Assistant
Возьмем задачку с поиском посложнее, сможем ли мы на базе Mistral сделать агента, который сможет подобрать нам рейс?
Снова расписываем модели
class FlightModel(BaseModel): flight_company: str = Field(description="Компания которая организует перелет") flight_number:str = Field(description="Номер рейса") departure_time: datetime = Field(description="Дата и время вылета в локальном времени аэропорта") arrival_time: datetime = Field(description="Дата и время прилёта в локальном времени аэропорта") price: float = Field(description="Цена за перелет за одного человека") price_total: float = Field(description="Цена за перелет суммарно за N человек") persons: int = Field(description="количество человек") original: str = Field(description="Город вылета , название аэропорта") destination: str = Field(description="Город назначения, название аэропорта") plane: Optional[str] = Field(description="Название самолета") link: str = Field(description="Ссылка на конкретный рейс, который ты предлагаешь. Обязательно должно открыть сам рейс") description: str = Field(description="Описание пути c локальным временем вылета, прилета, ценой и остальными параметрами выше")
промптим
flight_prompt= """ Ты агент по поиску рейсов. Ты должен находить ТОЧНЫЕ данные о рейсах. ### Правила: 1. Используй ТОЛЬКО эти сайты: yandextravel.ru, aviasales.ru, ozontravel.ru, tutu.ru 2. Если не находишь рейс - скажи об этом честно 3. Все поля должны быть заполнены ТОЧНЫМИ данными 4. Время указывай в формате: YYYY-MM-DD HH:MM 5. Ссылка должна вести НАПРЯМУЮ на конкретный рейс ### Требуемые данные: {{ "flight_company": str = Field(description="Компания которая организует перелет") "flight_number":str = Field(description="Номер рейса") "departure_time": datetime = Field(description="Дата и время вылета в локальном времени аэропорта") "arrival_time": datetime = Field(description="Дата и время прилёта в локальном времени аэропорта") "price": float = Field(description="Цена за перелет за одного человека") "price_total": float = Field(description="Цена за перелет суммарно за N человек") "persons": int = Field(description="количество человек") "original": str = Field(description="Город вылета , название аэропорта") "destination": str = Field(description="Город назначения, название аэропорта") "plane": Optional[str] = Field(description="Название самолета") "link": str = Field(description="Ссылка на конкретный рейс, который ты предлагаешь. Обязательно должно открыть сам рейс") "description": str = Field(description="Описание пути c локальным временем вылета, прилета, ценой и остальными параметрами выше") }} Исходя из того маршрута, который он тебе предоставил """
Вызываем агента на основе моделей Pydantic и промпта, не забываем про search tool
logfire.configure(send_to_logfire=os.getenv("LOGFIRE_TOKEN")) model = MistralModel(model_name="mistral-large-latest", provider=MistralProvider(api_key=os.getenv("MISTRAL_API_KEY"))) agent = Agent(model=model, tools=[duckduckgo_search_tool()], retries=5, instrument=True, result_type=FlightModel, system_prompt=flight_prompt) result_sync = agent.run_sync('Найди билеты из москвы в тюмень на 24 апреля на два человека после 19:00 по МСК ') print(result_sync.data)
response:
flight_company='ютэйр' flight_number='UT 121' departure_time=datetime.datetime(2024, 4, 24, 23, 0) arrival_time=datetime.datetime(2024, 4, 25, 4, 40) price=33009.0 price_total=66018.0 persons=2 original='Москва, Внуково' destination='Тюмень, Рощино' plane=None link='https://avia.tutu.ru/rasp/Moskva--Tyumen/' description='Рейс авиакомпании UTair UT 121 вылетает из аэропорта Внуково (VKO) в Москве в 23:00 24 апреля 2024 года по местному времени. Прибытие в аэропорт Рощино (TJM) в Тюмени ожидается в 04:40 25 апреля 2024 года по местному времени. Продолжительность полёта составляет 2 часа 40 минут. Стоимость билета на одного человека составляет 33 009 рублей, а на двух человек - 66 018 рублей. Вы можете забронировать и купить билеты на сайте Туту.ру по ссылке [Авиабилеты Москва - Тюмень]'
Тем временем рейс UT 121

Это конечно неплохо, что он справился с тем выводом, который от него просили, но задачу он так и не выполнил. А рейса Utair из Москвы на сайте на это время в принципе нету. В общем забавный эксперимент едем дальше.
Идем в Google AI Studio и отдаем свои данные на train. Бесплатно, за данные ни о чем, четко, то что нам надо. Так еще и моделька вроде умнее будет…
Реализуем
from pydantic_ai import Agent from pydantic_ai.models.gemini import GeminiModel from pydantic_ai.providers.google_gla import GoogleGLAProvider from pydantic_ai.common_tools.duckduckgo import duckduckgo_search_tool from pydantic import BaseModel, Field from datetime import datetime from typing import Optional import logfire import os from dotenv import load_dotenv load_dotenv() flight_prompt= """ Ты агент по поиску рейсов. Ты должен находить ТОЧНЫЕ данные о рейсах. ### Правила: 1. Используй ТОЛЬКО эти сайты: yandextravel.ru, aviasales.ru, ozontravel.ru, tutu.ru 2. Если не находишь рейс - скажи об этом честно 3. Все поля должны быть заполнены ТОЧНЫМИ данными 4. Время указывай в формате: YYYY-MM-DD HH:MM 5. Ссылка должна вести НАПРЯМУЮ на конкретный рейс ### Требуемые данные: {{ "flight_company": str = Field(description="Компания которая организует перелет") "flight_number":str = Field(description="Номер рейса") "departure_time": datetime = Field(description="Дата и время вылета в локальном времени аэропорта") "arrival_time": datetime = Field(description="Дата и время прилёта в локальном времени аэропорта") "price": float = Field(description="Цена за перелет за одного человека") "price_total": float = Field(description="Цена за перелет суммарно за N человек") "persons": int = Field(description="количество человек") "original": str = Field(description="Город вылета , название аэропорта") "destination": str = Field(description="Город назначения, название аэропорта") "plane": Optional[str] = Field(description="Название самолета") "link": str = Field(description="Ссылка на конкретный рейс, который ты предлагаешь. Обязательно должно открыть сам рейс") "description": str = Field(description="Описание пути c локальным временем вылета, прилета, ценой и остальными параметрами выше") }} Исходя из того маршрута, который он тебе предоставил """ class FlightModel(BaseModel): flight_company: str = Field(description="Компания которая организует перелет") flight_number:str = Field(description="Номер рейса") departure_time: datetime = Field(description="Дата и время вылета в локальном времени аэропорта") arrival_time: datetime = Field(description="Дата и время прилёта в локальном времени аэропорта") price: float = Field(description="Цена за перелет за одного человека") price_total: float = Field(description="Цена за перелет суммарно за N человек") persons: int = Field(description="количество человек") original: str = Field(description="Город вылета , название аэропорта") destination: str = Field(description="Город назначения, название аэропорта") plane: Optional[str] = Field(description="Название самолета") link: str = Field(description="Ссылка на конкретный рейс, который ты предлагаешь. Обязательно должно открыть сам рейс") description: str = Field(description="Описание пути c локальным временем вылета, прилета, ценой и остальными параметрами выше") logfire.configure(send_to_logfire=os.getenv("LOGFIRE_TOKEN")) model = GeminiModel( 'gemini-2.0-flash', provider=GoogleGLAProvider(api_key=os.getenv('GEMINI_API_KEY')) ) agent = Agent(model=model, tools=[duckduckgo_search_tool()], retries=5, instrument=True, result_type=FlightModel, system_prompt=flight_prompt) result_sync = agent.run_sync('Найди прямой рейс самолета из москвы в тюмень компании Utair на 24 апреля на два человека после 19:00 по МСК ') print(result_sync.data)
response:
flight_company='Utair' flight_number='UT453' departure_time=datetime.datetime(2024, 4, 24, 21, 30) arrival_time=datetime.datetime(2024, 4, 25, 0, 5) price=5929.0 price_total=11858.0 persons=2 original='Москва, Внуково' destination='Тюмень, Рощино' plane='Boeing 737' link='https://avia.tutu.ru/f/Moskva/Tyumen/' description='Прямой рейс Utair UT453 из Москвы (Внуково) в Тюмень (Рощино). Вылет 24 апреля в 21:30, прилет 25 апреля в 00:05. Цена за одного человека 5929 рублей, общая стоимость за двоих 11858 рублей.'
Ну чтож такой рейс действительно существует, но по времени и сумме у нас ошибка.

В общем то таки, исключая факт того .что цена неверная, как и время, мы наконец смогли найти существующий рейс.
В общем доработав системный промпт, полагаю, можно добиться более качественных результатов, а мы же двинемся дальше.
Agent Delegation
В контексте мультиагентных систем мы рассмотрим один из представленных в документации вариантов реализации в формате Agent Delegation.
Поскольку у нас вроде неплохо получился агент с погодой, возьмем его и добавим еще парочку.
Идейно я хочу получить следующую картину:

Супервизор — анализирует запрос пользователя и решает к какой туле (агенту) ему обратиться.
Currency Agent — агент по курсу валют
Weather Agent — знакомый нам агент по погоде
Joke Agent — агент юморист как в доке Pydantic AI.
На этом моменте в реализации мы отклонимся от подхода Pydantic AI в использовании декораторов, поскольку это выглядит интересно, но как этим пользоваться потом не совсем понятно. Вместо них просто явно пропишем тулы, которыми может пользоваться наш супервизор.
Перейдем к реализации.
Создадим отдельные файлы для схем, промптов и самих агентов, поскольку теперь следит за кодом станет сложнее и проще сделать импорт из файла, чем листать построчно и искать очередную ошибку.
schemas.py
from pydantic import BaseModel from typing import Optional class CurrencyModel(BaseModel): currency: str value: float description: str class WeatherModel(BaseModel): temperature: float wind_speed: float description: str class JokeModel(BaseModel): joke: str class SupervisorModel(BaseModel): weather: Optional[WeatherModel] = None currency: Optional[CurrencyModel] = None joke: Optional[JokeModel] = None
Соответственно от Currency Model мы хотим получить саму валюту, её значение и какое-то внятное пояснение от агента
От Joke Model просто любая строка сойдет, вообще не паримся.
Weather Model мы уже видели, а вот Supervisor Model лучше знать че она может получить, поэтому перечислим как опциональные модели от предыдуших
Напишем минимальный системный промпт для каждого из агентов, чтобы они понимали свою роль
supervisor_prompt = """ Ты агент супервизор Твоя задача решить какого агента использовать, в зависмости от намерения пользователя: - get_currency - агент по валютам, он может сказать сколько стоит одна валюта в другой - get_weather - агент по погоде - generate_joke - агент генератор шуток Поняв намерение пользователя, вызови тул для выполнения запроса Верни на выходе результат этого тула """ currency_prompt = """ Ты агент для поиска текущего курса валют на основе запроса пользователя сформируй ответ как: {{ currency: str value: float description: str }} currency - USD value - цена валюты USD Пример: Сколько щас стоит 100 000 RUB в USD ответ: {{ currency: USD value: 1 202,21 description: 100 000 Российских Рублей стоят 1 202,21 USD (доллар США) }} """ weather_prompt = """ Ты агент по погоде. Твоя задача предоставить temperature, wind_speed и description в поле description ты должен дать совет пользователю о том, во что ему одеться думай о комфорте человека в предоставленных тебе погодных условиях формат вывода: {{ temperature: float wind_speed: float description: str }} """ joke_prompt = """ Сгенерируй шутку Будь креативным, необычным и нестандартным, ни в чем себя не ограничивая """
Ну и теперь переходим к реализации самих агентов, здесь я решил остаться на Gemini, поскольку она не начинает ныть при большем количестве последовательных запросов, в отличие от Mistral.
from pydantic_ai import Agent from pydantic_ai.models.gemini import GeminiModel from pydantic_ai.providers.google_gla import GoogleGLAProvider from pydantic_ai.common_tools.duckduckgo import duckduckgo_search_tool import logfire import os from dotenv import load_dotenv from prompts import weather_prompt, currency_prompt, joke_prompt, supervisor_prompt from schemas import WeatherModel, CurrencyModel, JokeModel load_dotenv() gemini = GeminiModel( model_name="gemini-2.0-flash", provider=GoogleGLAProvider(api_key=os.getenv("GEMINI_API_KEY")), ) logfire.configure(send_to_logfire=os.getenv("LOGFIRE_TOKEN")) currency_agent = Agent( model=gemini, tools=[duckduckgo_search_tool()], retries=5, instrument=True, result_type=CurrencyModel, system_prompt=currency_prompt, ) weather_agent = Agent( model=gemini, tools=[duckduckgo_search_tool()], retries=5, instrument=True, result_type=WeatherModel, system_prompt=weather_prompt, ) joke_agent = Agent( model=gemini, retries=5, instrument=True, result_type=JokeModel, system_prompt=joke_prompt, model_settings={ "temperature": 0.9, }, ) async def get_currency() -> CurrencyModel: currency = await currency_agent.run("Пожалуйста, скажи мне курс валют.") return currency.data async def get_weather() -> WeatherModel: weather = await weather_agent.run("Какая сейчас погода?") return weather.data async def generate_joke() -> str: joke = await joke_agent.run("Расскажи анекдот.") return joke.data supervisor_agent = Agent( model=gemini, retries=5, instrument=True, tools=[get_currency, get_weather, generate_joke], system_prompt=supervisor_prompt, ) import asyncio async def main(): result = await supervisor_agent.run("Какая температура сейчас в Москве?") print(result.data) asyncio.run(main()) #1 #Message: Какая температура сейчас в Москве? #Response: В Москве сейчас 14 градусов Цельсия, ожидается облачная с прояснениями погода, возможны осадки, ветер 7.2 метра в секунду. #2 # Message: Сгенерируй самую странную шутку, что ты когда либо видел # Response: #Конечно! Вот для вас необычная шутка: #Почему хомяки никогда не работают в колл-центрах? #Потому что они всегда хотят только спать на работе и никак не могут перестать вертеть колесо, даже по телефону! 

#3 # Message: Сколько стоит 50 000 рублей в USD? #К сожалению, я не могу рассчитать стоимость 50 000 рублей в USD, но могу предоставить информацию о курсе 1 USD к EUR. 1 USD стоит 0.93 EUR.
А ну и да, лучше этот код написать в асинхронном стиле, иначе вы рискуете поймать ошибку с event loop. run sync
здесь может заработать, но не так радужно как обычный асинхронный run
В общем со своей задачей справились агенты по погоде и по шуткам. Агент по Валюте решил что сойдет просто дать текущий курс, ну да ладно.
В общем и целом это кое-как работает, также как и с агентом по поиску билетов на самолет нужно вносить много правок в системный промпт и дорабатывать его.
MCP
Перейдем к обещанному в начале статьи и самому хайповому варианту — MCP протоколу. На хабре уже есть статьи, описывающие его, поэтому я просто оставлю ссылку здесь.
Для запуска MCP и LLM на нужно 2 вещи:
1) Сервер, возьмем из документации mcp-server-fetch
ставим через
uv add mcp-server-fetch
2) Клиент, его пишем сами через Pydantic AI
Здесь я бы хотел реализовать агента, который будет ходить на сайты по блокчейну, их я просто передам через системный промпт.
Вдохновлялся я этим видосом про MCP
Кстати, про defillama.com, не советую просить агента ходить туда, поскольку может случиться ситуация. когда он очень много раз стучался и не достучался, а еще потратил много токенов: >1 000 000 input токенов

uv add "pydantic-ai-slim[mcp]"
from pydantic_ai import Agent from pydantic_ai.models.gemini import GeminiModel from pydantic_ai.providers.google_gla import GoogleGLAProvider from pydantic_ai.mcp import MCPServerStdio from pydantic_ai.mcp import MCPServerHTTP from pydantic import BaseModel import logfire import os from dotenv import load_dotenv load_dotenv() class ChainModel(BaseModel): Reasoning: str Act: str tool_call: str Response: str system_prompt = """ Ты ассистент по блокчейну Твоя задача анализировать и выдавать инсайты пользователю Будь полезным и постарайся как можно лучше и эффективнее помочь ему Твой ответ должен содержать только реальные факты полученные по ссылкам ниже: https://coinmarketcap.com https://www.blockchain.com НЕ ЛЕНИСЬ пример 1: "Human": какой топ 10 протоколов в defi llama {{"Reasoning": мне необходимо проанализировать api defillama, у меня есть к ней доступ, необходимо сходит туда и сделать запрос и вернуть пользователю топ 10 протоколов "Act": SEARCH [поиск топ 10 протоколов в defi llama] "tool call": 200 ok, tool is called successfully "Response": я собрал топ 10 протоколов а также предлагаю следующуие стратегии: ... }} Пойми что от тебя требуется, сделай это, верни response Если у тебя не получилось выполнить запрос и он упал с ошибкой, сообщи это пользователю """ logfire.configure(send_to_logfire=os.getenv("LOGFIRE_TOKEN")) fetch_server = MCPServerStdio(command="uv", args=["run", "-m", "mcp_server_fetch"]) model = GeminiModel( "gemini-2.0-flash", provider=GoogleGLAProvider(api_key=os.getenv("GEMINI_API_KEY")) ) agent = Agent( model=model, retries=5, mcp_servers=[fetch_server], system_prompt=system_prompt, instrument=True, result_type=ChainModel, ) async def main(): async with agent.run_mcp_servers(): result = await agent.run("Привет, отвечай пж по русски всегда") while True: print(f"\n{result.data}") user_input = str(input("HumanMessage:")) result = await agent.run( user_prompt=user_input, message_history=result.new_messages(), ) if __name__ == "__main__": import asyncio asyncio.run(main())
Ну и все, теперь запускаем.
По сути изменилось то, что вместо tool мы пишем mcp_servers, а сам сервер запускаем внутри этого скрипта.
Запустив скрипт, мы сможем взаимодействовать с агентом и что-то у него спрашивать
User='Какие сейчас топ токены в крипте? покажи 5 самых дорогих' Response: Reasoning='Я получил данные с coinmarketcap.com. Теперь мне нужно проанализировать HTML контент и выдать топ 5 самых дорогих криптовалют основываясь на их цене.' Act='Топ 5 криптовалют' tool_call='default_api.fetch(url = "https://coinmarketcap.com")' Response='Топ 5 самых дорогих криптовалют на данный момент:\n\n1. "Bitcoin (BTC): $82,217.58\n2. "Ethereum (ETH): $1,560.86\n3. "Tether (USDT): $0.9994\n4. "XRP (XRP): $2.01\n5. "BNB (BNB): $581.44
Ну и в принципе обмана я не вижу, циферки немного отличаются, но очень-очень близко, учитываем факт того что сайт обновляется постоянно, вместе с ценами.

Summary
В общем и целом, в рамках этой статьи я успел рассказать вам про то, как можно сделать агентов на Pydantic AI, лично мне данный фреймворк понравился. Видно что он еще в разработке и фичи будут добавляться, однако текущие возможности этого фреймворка позволят быстро и без боли сделать вам агентов без лишних зависимостей, без необходимости вникать в графы и прочие вещи, связанные с аналогичными фреймворками.
Про RAG тут пока сомнительно и не понятно. В доке есть пример, но выглядит он уже более серьезно, чем RAG на том же лангчейне. Ну и тут есть обсуждение на github как раз по этой тематике.
ссылка на оригинал статьи https://habr.com/ru/articles/900270/
Добавить комментарий