From 43f15a9f1f75fb7bc739d8172719fecf087d8c76 Mon Sep 17 00:00:00 2001 From: Reversean Date: Sun, 20 Sep 2026 21:57:05 +0300 Subject: [PATCH 1/3] fix(ai): set the answer format by example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The system instruction gives the answer format as a template of bracketed placeholders, and the model copies them instead of filling them in: on four fabricated events the old instruction opened every answer with the literal "[Краткое summary]". The format is now one filled example, kept inside a tag so it reads as a sample rather than as part of the conversation, and the rules say what the answer contains instead of what it must not do. Forbidding the copying was the alternative, but it leaves the placeholders in front of the model. On the same four events an example-based instruction opened every answer with a sentence about the error itself and kept all three section headings. The example is written in the markup the rules ask for: identifiers in backticks, multi-line code in a fenced block between list items. The rules never mentioned inline code, and answers came back with identifiers as plain words and without code blocks. Everything outside the example is in English, the language of the spotlighting rules it is concatenated with. The example carries the language of the answer. --- src/services/askAi/instructions/cto.ts | 58 +++++++++++++++++++------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/src/services/askAi/instructions/cto.ts b/src/services/askAi/instructions/cto.ts index 111a1588..901e7f61 100644 --- a/src/services/askAi/instructions/cto.ts +++ b/src/services/askAi/instructions/cto.ts @@ -1,24 +1,50 @@ -export const ctoInstruction = `Ты технический директор ИТ компании, тебе нужно пояснить ошибку и предложить решение. +/** + * System instruction: the model's role and the shape of the answer. + * + * The shape comes from a filled example. + * + * @see {@link https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices | Claude prompting best practices} + */ +export const ctoInstruction = `Explain the error and propose a fix. -Предоставь ответ **строго** в следующем формате на русском языке: +Answer in Russian, following the rules in and the sample in . -[Краткое summary] +The first one or two sentences name what broke and why: that is the analysis itself, not a lead-in to it. Then come the sections "## Описание проблемы", "## Решение" and "## Как избежать повторения", with the headings repeated word for word. Write about the error in the event data, not about the one in the sample. + + +- Write valid Markdown +- Indent nested lists with spaces, the same width on every level +- Where nesting would grow deeper, write a subsection instead +- Add links where they help +- Put identifiers, field names, values and one-line snippets in backticks +- Keep headings plain: no numbering, no code +- Put multi-line code in a fenced block with a language tag +- Never place code block inside list item, keep it between items + + + +Страница корзины падает у всех, чья сессия истекла: сервер отвечает объектом ошибки, а код принимает ответ за список товаров и вызывает у него \`map\`. ## Описание проблемы -[Подробный, но лаконичный анализ сути проблемы] +Функция \`renderCart\` читает \`data.items\` сразу после запроса, не проверяя, что он удался. На истёкшей сессии сервер возвращает \`{ error: "session expired" }\`, поля \`items\` в ответе нет, и вызов \`items.map\` бросает \`TypeError\`. Падение повторяется при каждом открытии корзины и от содержимого заказа не зависит. ## Решение -[Конкретные шаги по исправлению + рекомендуемый лучший вариант] +1. Разбирать в \`fetchCart\` неуспешный ответ отдельно: на \`session expired\` отправлять пользователя на страницу входа. + +\`\`\`ts +const response = await fetch('/api/cart'); + +if (!response.ok) { + const { error } = await response.json(); + + throw new CartRequestError(error); +} +\`\`\` + +2. В \`renderCart\` показывать пустую корзину, когда \`items\` не массив. + +Первый шаг лечит причину, второй остаётся страховкой на случай других неожиданных ответов. ## Как избежать повторения -[Как предотвратить повторение подобной ошибки в будущем: процессы, инструменты, архитектурные решения, code review и т.д.] - -**Formatting instructions:** -- Output only valid Markdown. -- Use consistent indentation for all nested lists. -- Never use tabs instead of spaces. -- Use links if necessary. -- Never use numbering in headings. -- Prefer sections with nested headings to avoid deeply-nested lists. -- Never nest inline code-blocks inside headings. -- Never nest multiline code-blocks inside lists.`; +Разбирать ответы сервера в одном месте — клиенте API, который бросает исключение на любой ответ не из 2xx. Тогда ни один вызов не примет тело ошибки за данные. На code review отдельно смотреть на новые запросы, у которых нет ветки ошибки. +`; From 97798e6eb123406984d0bb0a0b45e406ba23575f Mon Sep 17 00:00:00 2001 From: github-actions <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 21 Sep 2026 11:31:56 +0000 Subject: [PATCH 2/3] Bump version up to 1.5.17 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2319788e..3f359ea0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hawk.api", - "version": "1.5.16", + "version": "1.5.17", "main": "index.ts", "license": "BUSL-1.1", "scripts": { From f9240c4b757d690660a470079ce325d88b7fde33 Mon Sep 17 00:00:00 2001 From: Reversean Date: Mon, 21 Sep 2026 20:50:14 +0300 Subject: [PATCH 3/3] fixup! fix(ai): set the answer format by example --- src/services/askAi/instructions/cto.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/askAi/instructions/cto.ts b/src/services/askAi/instructions/cto.ts index 901e7f61..fa6dc022 100644 --- a/src/services/askAi/instructions/cto.ts +++ b/src/services/askAi/instructions/cto.ts @@ -3,7 +3,7 @@ * * The shape comes from a filled example. * - * @see {@link https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices | Claude prompting best practices} + * @see {@link https://developers.openai.com/api/docs/guides/prompt-engineering | OpenAI prompt engineering guide} */ export const ctoInstruction = `Explain the error and propose a fix.