~/tools / Эмбеддинги и поиск (RAG) / RAG Prompt Builder

RAG Prompt Builder — Запрос к /api/chat в Ollama: ответ только по пронумерованным источникам

Превращает результаты вашего поиска и вопрос в запрос к /api/chat в Ollama, который требует от модели отвечать только по пронумерованным источникам и ссылаться на них. По желанию просит JSON с номером источника и цитатой для каждой ссылки, ставит температуру 0 и отправляет "truncate": false, чтобы слишком длинный промпт приводил к ошибке, а не обрезался. Ничего не покидает ваш браузер.

Примеры источников написаны вручную в том виде, в каком их возвращает json_agg.

Источников: 3. Распознан формат: массив JSON из объектов.

Команда curl

Отправляет запрос в Ollama на этом компьютере (localhost:11434).

curl http://localhost:11434/api/chat -d '{
  "model": "qwen2.5:7b",
  "messages": [
    {
      "role": "system",
      "content": "Answer the question using only the numbered sources in the user message. Cite the number of each source you use. If the sources do not contain the answer, say that you do not know and cite nothing. Answer in the same language as the question. For each citation, give the source number and copy a short quote from that source exactly as it is written. Return JSON that matches this schema: {\"type\":\"object\",\"properties\":{\"answer\":{\"type\":\"string\"},\"citations\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"source\":{\"type\":\"integer\"},\"quote\":{\"type\":\"string\"}},\"required\":[\"source\",\"quote\"]}}},\"required\":[\"answer\",\"citations\"]}"
    },
    {
      "role": "user",
      "content": "Sources:\n\n[1] (id: 12)\nWith HNSW, hnsw.ef_search is 40 by default, so a query returns at most 40 rows unless you raise it.\n\n[2] (id: 7)\nSET LOCAL inside a transaction changes hnsw.ef_search for a single query.\n\n[3] (id: 3)\npgvector supports PostgreSQL 13 and later.\n\nQuestion: Why does my HNSW search return only 40 rows with LIMIT 100?"
    }
  ],
  "stream": false,
  "format": {
    "type": "object",
    "properties": {
      "answer": {
        "type": "string"
      },
      "citations": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "source": {
              "type": "integer"
            },
            "quote": {
              "type": "string"
            }
          },
          "required": [
            "source",
            "quote"
          ]
        }
      }
    },
    "required": [
      "answer",
      "citations"
    ]
  },
  "options": {
    "temperature": 0
  },
  "truncate": false
}'

Тело запроса (JSON)

{
  "model": "qwen2.5:7b",
  "messages": [
    {
      "role": "system",
      "content": "Answer the question using only the numbered sources in the user message. Cite the number of each source you use. If the sources do not contain the answer, say that you do not know and cite nothing. Answer in the same language as the question. For each citation, give the source number and copy a short quote from that source exactly as it is written. Return JSON that matches this schema: {\"type\":\"object\",\"properties\":{\"answer\":{\"type\":\"string\"},\"citations\":{\"type\":\"array\",\"items\":{\"type\":\"object\",\"properties\":{\"source\":{\"type\":\"integer\"},\"quote\":{\"type\":\"string\"}},\"required\":[\"source\",\"quote\"]}}},\"required\":[\"answer\",\"citations\"]}"
    },
    {
      "role": "user",
      "content": "Sources:\n\n[1] (id: 12)\nWith HNSW, hnsw.ef_search is 40 by default, so a query returns at most 40 rows unless you raise it.\n\n[2] (id: 7)\nSET LOCAL inside a transaction changes hnsw.ef_search for a single query.\n\n[3] (id: 3)\npgvector supports PostgreSQL 13 and later.\n\nQuestion: Why does my HNSW search return only 40 rows with LIMIT 100?"
    }
  ],
  "stream": false,
  "format": {
    "type": "object",
    "properties": {
      "answer": {
        "type": "string"
      },
      "citations": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "source": {
              "type": "integer"
            },
            "quote": {
              "type": "string"
            }
          },
          "required": [
            "source",
            "quote"
          ]
        }
      }
    },
    "required": [
      "answer",
      "citations"
    ]
  },
  "options": {
    "temperature": 0
  },
  "truncate": false
}

В ответе сервера ответ модели находится в message.content. Если prompt_eval_count намного меньше ожидаемого, промпт, возможно, был обрезан.

Поля запроса — по справочнику API и исходному коду Ollama, проверено на Ollama 0.40.11 2026-11-05. Ollama API: /api/chat

Всё выполняется в вашем браузере. Инструмент пишет запрос и ни к чему не подключается.

При генерации, дополненной поиском (RAG), вы сначала ищете по своим документам, а затем передаёте модели ближайшие фрагменты вместе с вопросом. Этот инструмент пишет такой запрос для /api/chat в Ollama. Вставьте результаты поиска как массив JSON из строк, как массив JSON из объектов (например, результат json_agg из PostgreSQL; текст берётся из content, text, chunk, document или page_content, а id, title и url добавляются в заголовок источника) либо как обычный текст, разделённый строками --- или пустыми строками. Инструмент нумерует источники начиная с [1], помещает правила в сообщение system, а источники и затем вопрос — в одно сообщение user. При включённом варианте JSON поле format получает JSON Schema с ответом и списком ссылок (номер источника и цитата), и та же схема записывается в сообщение system, как рекомендует страница Ollama о структурированном выводе. Без него модель просят после каждого предложения ставить номера в квадратных скобках. Параметр truncate важен, потому что Ollama обрезает длинные промпты без ошибки: в исходном коде Ollama (0.40.11) она сохраняет несколько первых токенов и конец промпта, а середину отбрасывает, и в нашем тесте с num_ctx 1024 это убрало сообщение system и первые источники и изменило ответ. Поле truncate есть в исходном коде Ollama, но не на странице /api/chat; с "truncate": false тот же запрос вернул HTTP 400. Запросы из этого инструмента мы отправляли в Ollama 0.40.11 с qwen2.5:7b в обоих режимах.

Основная логика этого инструмента открыта под лицензией MIT. github.com/seigo5555/toolkitbox-lib/src/rag-prompt.ts

Когда пригодится

  • Отвечать на вопросы по собственным руководствам или заметкам с помощью локальной модели, указывая источник каждого утверждения
  • Опробовать промпт и формат ссылок на нескольких настоящих результатах поиска, прежде чем писать код приложения
  • Узнать, помещаются ли результаты поиска в длину контекста модели

Как пользоваться

  1. Введите вопрос и вставьте результаты поиска, например строки, которые вернул запрос из pgvector SQL Builder.
  2. Выберите модель и, по желанию, num_ctx и параметры: ссылки в JSON, температура 0 и truncate.
  3. Скопируйте команду curl или тело JSON и отправьте в Ollama. Вставьте ответ и те же источники в RAG Citation Checker.

Вопросы

Почему источники нумеруются, а не используются идентификаторы из моей базы?

Короткие номера модели проще воспроизвести, чем длинные идентификаторы, и их можно сверить с отправленным списком. Id, title и url каждого объекта по-прежнему показаны рядом с его номером, так что номер можно сопоставить обратно со строкой.

Почему вопрос стоит после источников?

Когда промпт длиннее длины контекста, Ollama сохраняет его конец и отбрасывает текст перед ним, поэтому вопрос в конце — та часть, которая остаётся. Ещё надёжнее отправлять "truncate": false, чтобы получить ошибку и отправить меньше строк или увеличить num_ctx.

Сколько источников можно отправить?

Инструмент принимает до 50. Сколько поместится, зависит от их длины и от длины контекста: в документации Ollama по умолчанию указано 4k токенов при менее чем 24 GiB VRAM. Поле prompt_eval_count в ответе показывает, сколько токенов заняло промпт.

Гарантирует ли вариант JSON верные ссылки?

Нет. Поле format заставляет ответ соответствовать JSON Schema, но модель всё равно может сослаться не на тот источник или процитировать то, чего в нём нет. Проверьте ответ в RAG Citation Checker.

Можно ли использовать его с API, совместимым с OpenAI?

Инструмент пишет собственный запрос /api/chat. В документации Ollama сказано, что структурированный вывод работает и через API, совместимый с OpenAI, с помощью response_format, но запрос там имеет другую форму.

Отправляются ли мои данные куда-либо?

Нет. Запрос строится в вашем браузере. Инструмент никогда не подключается к Ollama.

Похожие статьи

Похожие