Как собрать ИИ-агента: пошаговый гайд с кодом
Практическое руководство по созданию ИИ-агента: от выбора модели до запуска с RAG и MCP. Код на Python, который можно запустить сразу.
Что понадобится
- Python 3.9 или новее.
- API-ключ от OpenAI (или другого провайдера). Получить можно в личном кабинете на платформе провайдера.
- Установленные библиотеки:
openai,requests,faiss-cpu,numpy. - Текстовый редактор или IDE.
- Базовое понимание Python и HTTP-запросов.
Все примеры кода ниже предполагают, что вы замените ВАШ_КЛЮЧ на реальный ключ. Ключ можно хранить в переменной окружения, чтобы не светить в коде.
Шаг 1: Установите зависимости и настройте ключ
Создайте виртуальное окружение и установите пакеты:
python -m venv agent-env
source agent-env/bin/activate # для Windows: agent-env\Scripts\activate
pip install openai requests faiss-cpu numpy
Сохраните ключ в переменную окружения (Linux/macOS):
export OPENAI_API_KEY="ВАШ_КЛЮЧ"
Для Windows (cmd):
set OPENAI_API_KEY=ВАШ_КЛЮЧ
Проверьте, что ключ работает:
import os
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Привет! Ответь одним словом."}]
)
print(response.choices[0].message.content)
Если увидели ответ — ключ активен.
Шаг 2: Создайте простого агента с функцией погоды
Агент отличается от модели тем, что может вызывать инструменты. Напишем функцию, которая возвращает фиктивную погоду (для демонстрации), и научим модель её вызывать.

import json
from openai import OpenAI
client = OpenAI()
def get_weather(city: str) -> str:
# Заглушка: в реальности здесь был бы запрос к API погоды.
return f"В {city} сейчас +15°C, облачно."
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Возвращает текущую погоду в городе",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "Название города"}
},
"required": ["city"]
}
}
}]
messages = [{"role": "user", "content": "Какая погода в Москве?"}]
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
tools=tools,
tool_choice="auto"
)
msg = response.choices[0].message
if msg.tool_calls:
for call in msg.tool_calls:
args = json.loads(call.function.arguments)
result = get_weather(args["city"])
messages.append(msg)
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": result
})
final = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages
)
print(final.choices[0].message.content)
else:
print(msg.content)
Запустите — агент вызовет функцию и вернёт ответ с погодой.
Шаг 3: Добавьте RAG для работы с документами
RAG (Retrieval-Augmented Generation — генерация с дополнением из поиска) позволяет агенту отвечать на вопросы по вашим данным. Сделаем простой поиск по текстовым фрагментам.
import numpy as np
import faiss
from openai import OpenAI
client = OpenAI()
# Пример базы знаний: список текстов
docs = [
"Отпуск в компании составляет 28 календарных дней.",
"Заявка на отпуск подаётся за две недели до начала.",
"Больничный оплачивается по среднему заработку."
]
# Получаем эмбеддинги для документов
embeddings = []
for text in docs:
resp = client.embeddings.create(input=text, model="text-embedding-3-small")
embeddings.append(resp.data[0].embedding)
# Создаём индекс FAISS
index = faiss.IndexFlatL2(len(embeddings[0]))
index.add(np.array(embeddings).astype('float32'))
def retrieve(query: str, k: int = 2):
q_emb = client.embeddings.create(input=query, model="text-embedding-3-small").data[0].embedding
distances, indices = index.search(np.array([q_emb]).astype('float32'), k)
return [docs[i] for i in indices[0]]
<figure class="post-fig"><img src="/media/inline-1793422159.jpg" alt="Шаг 3: Добавьте RAG для работы с документами" loading="lazy"></figure>
# Пример запроса
question = "Сколько дней отпуска?"
context = retrieve(question)
prompt = f"Ответь на вопрос, используя контекст:\n{context}\n\nВопрос: {question}"
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}]
)
print(response.choices[0].message.content)
Агент найдёт нужный фрагмент и ответит на основе него.
Шаг 4: Подключите MCP для вызова внешнего сервиса
MCP (Model Context Protocol — протокол контекста модели) позволяет агенту обращаться к внешним инструментам через стандартизированный интерфейс. В примере используем простой HTTP-сервис (заглушку). В реальности MCP-сервер может быть запущен локально или удалённо.
import requests
def call_mcp_tool(tool_name: str, params: dict) -> dict:
# Пример: обращение к локальному MCP-серверу (заглушка)
# В реальности URL и формат зависят от реализации MCP-сервера.
url = "http://localhost:8000/mcp"
payload = {"tool": tool_name, "parameters": params}
try:
resp = requests.post(url, json=payload, timeout=5)
return resp.json()
except Exception as e:
return {"error": str(e)}
# Использование в агенте: добавьте описание инструмента в tools и обрабатывайте вызов
Этот шаг требует, чтобы MCP-сервер был запущен. Без него вызов вернёт ошибку соединения — это нормально для проверки.
Шаг 5: Соберите всё вместе
Объедините функцию погоды, RAG и вызов MCP в одном агенте. Логика: сначала поиск по базе знаний, затем при необходимости вызов инструментов.
# Псевдокод для структуры
# 1. Получить запрос пользователя.
# 2. Выполнить retrieve() для поиска контекста.
# 3. Передать контекст и запрос в модель с описанием инструментов.
# 4. Если модель вернула tool_calls — выполнить соответствующие функции.
# 5. Вернуть финальный ответ.
Полный код можно собрать из предыдущих шагов, добавив ветвление.
Типичные ошибки и как их узнать
- Ошибка аутентификации (401) — ключ неверный или не передан. Проверьте переменную окружения.
- Модель не вызывает инструмент — в описании функции нет чётких параметров или модель не понимает задачу. Упростите описание, добавьте примеры в
description. - RAG возвращает нерелевантные фрагменты — мало документов или эмбеддинги не подходят. Увеличьте
kили проверьте качество текстов. - MCP-сервер недоступен — проверьте, запущен ли сервер и правильный ли URL. Ошибка соединения — явный признак.
- Агент зацикливается — ограничьте количество шагов (например, не более 5 вызовов инструментов).
Следуя шагам, вы получите работающего агента, который умеет отвечать на вопросы по вашим данным и вызывать внешние функции.