Код-ревью Middle ИИ-фичи в продукте обновлено
Код-ревью: обработчик вызова LLM, написанный ИИ
Вопрос
Ассистент сгенерировал эндпоинт, который извлекает из письма клиента поля заявки через LLM API. Найдите проблемы.
const OPENAI_KEY = "sk-live-4f9a...";
app.post("/api/extract", async (req, res) => {
const { email } = req.body;
const r = await fetch(LLM_URL, {
method: "POST",
headers: { Authorization: `Bearer ${OPENAI_KEY}` },
body: JSON.stringify({
model: MODEL,
messages: [
{ role: "system", content: "Верни JSON: name, phone, product" },
{ role: "user", content: email },
],
}),
});
const data = await r.json();
const order = JSON.parse(data.choices[0].message.content);
await db.orders.insert(order);
res.json(order);
});
Коротко
Типичный код от ассистента: работает на демо и ломается в проде. Ключ должен жить в секретах, эндпоинт защищён аутентификацией и лимитами.
Что должен найти ревьюер
- Безопасностьстрока 1Ключ API захардкожен в коде и попадёт в репозиторий. Его место в секретах окружения, а утёкший ключ надо отозвать.
- Безопасностьстрока 3Нет проверки аутентификации и лимитов: любой может вызывать эндпоинт и тратить бюджет.
- Ошибкастрока 5fetch без таймаута и без повторов на 429 и 5xx: зависший провайдер повесит запросы, временный сбой сразу станет ошибкой.
- Ошибкастрока 5Не проверяется r.ok: при ошибке провайдера data.choices не будет, и обработчик упадёт с непонятным исключением.
- Производительностьстрока 9Нет max_tokens и ограничения длины письма: огромное письмо или длинный ответ дадут дорогой и медленный запрос.
- Ошибкастрока 17JSON.parse без проверки схемы: невалидный JSON уронит обработчик, а выдуманные или пустые поля попадут в базу. Нужна валидация (например, Zod) и фолбэк.
- Безопасностьстрока 18Ответ модели пишется в базу целиком: модель могла вернуть лишние поля, включая служебные. Сохранять только проверенные поля.
Разбор
Типичный код от ассистента: работает на демо и ломается в проде. Ключ должен жить в секретах, эндпоинт защищён аутентификацией и лимитами. Вызов провайдера с таймаутом, проверкой статуса и повторами с backoff. Длина входа и выхода ограничены. Ответ модели это недоверенный ввод: валидируем схему, берём только нужные поля, при ошибке повторяем ограниченно или уходим в фолбэк.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.