~/tools / Embeddings et recherche (RAG) / RAG Prompt Builder

RAG Prompt Builder — Construit une requête /api/chat d'Ollama avec sources numérotées et citées

Transformez vos résultats de recherche et une question en une requête /api/chat d'Ollama qui demande au modèle de répondre uniquement à partir de sources numérotées et de les citer. Peut aussi demander du JSON avec le numéro de la source et un extrait cité pour chaque citation, fixer la température (temperature) à 0 et envoyer "truncate": false pour qu'un prompt qui ne tient pas échoue au lieu d'être coupé. Rien ne quitte votre navigateur.

Les sources de l'exemple sont écrites à la main sous la forme que renvoie json_agg.

3 sources, lues comme un tableau JSON d'objets.

Commande curl

Envoie la requête à Ollama sur cette machine (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
}'

Corps de la requête (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
}

Dans la réponse, le texte se trouve dans message.content. Si prompt_eval_count est bien inférieur à ce que vous attendez, le prompt a peut-être été coupé.

Champs de la requête d'après la référence de l'API et le code source d'Ollama, vérifiés sur Ollama 0.40.11 le 2026-11-05. Ollama API: /api/chat

Tout s'exécute dans votre navigateur. L'outil écrit la requête et ne se connecte à rien.

Dans la génération augmentée par récupération (RAG), vous cherchez d'abord dans vos documents, puis vous donnez au modèle les passages les plus proches avec la question. Cet outil écrit cette requête pour /api/chat d'Ollama. Collez les résultats de la recherche sous forme de tableau JSON de chaînes, de tableau JSON d'objets (par exemple la sortie de json_agg de PostgreSQL ; le texte est lu dans content, text, chunk, document ou page_content, et id, title et url sont ajoutés à l'en-tête de la source) ou de texte séparé par des lignes --- ou par des lignes vides. L'outil numérote les sources à partir de [1], place les règles dans un message system, et place les sources puis la question dans un seul message user. Avec l'option JSON, le champ format reçoit un JSON Schema avec la réponse et une liste de citations (numéro de la source et extrait cité), et le même schéma est écrit dans le message system, comme le recommande la page d'Ollama sur les sorties structurées. Sans elle, on demande au modèle d'écrire les numéros entre crochets après chaque phrase. L'option truncate compte parce qu'Ollama coupe les prompts longs sans erreur : dans le code source d'Ollama (0.40.11), il conserve les premiers tokens et la fin du prompt et supprime la partie intermédiaire, et dans notre test avec num_ctx 1024, cela a retiré le message system et les premières sources et a changé la réponse. Le champ truncate figure dans le code source d'Ollama mais pas sur la page de /api/chat ; avec "truncate": false, la même requête a renvoyé HTTP 400. Nous avons envoyé les requêtes de cet outil à Ollama 0.40.11 avec qwen2.5:7b, dans les deux modes.

Le cœur de cet outil est open source, sous licence MIT. github.com/seigo5555/toolkitbox-lib/src/rag-prompt.ts

Cas d'usage

  • Répondre à des questions sur vos propres manuels ou notes avec un modèle local, en indiquant la source de chaque affirmation
  • Essayer le prompt et le format des citations sur quelques vrais résultats de recherche avant d'écrire le code de votre application
  • Savoir si vos résultats de recherche tiennent encore dans la longueur de contexte du modèle

Utilisation

  1. Saisissez la question et collez les résultats de la recherche, par exemple les lignes renvoyées par la requête du pgvector SQL Builder.
  2. Choisissez le modèle, puis éventuellement num_ctx et les options de citations en JSON, de température 0 et de truncate.
  3. Copiez la commande curl ou le corps JSON et envoyez-le à Ollama. Collez la réponse et les mêmes sources dans le RAG Citation Checker.

FAQ

Pourquoi les sources sont-elles numérotées au lieu d'utiliser les id de ma base de données ?

Des numéros courts sont plus faciles à recopier pour le modèle que de longs id, et on peut les vérifier avec la liste qui a été envoyée. L'id, le title et l'url de chaque objet restent affichés à côté de son numéro, ce qui vous permet de retrouver la ligne à partir du numéro.

Pourquoi la question vient-elle après les sources ?

Quand un prompt est plus long que la longueur de contexte, Ollama conserve la fin du prompt et supprime le texte qui la précède, donc la question placée à la fin est la partie conservée. Il est encore plus sûr d'envoyer "truncate": false, pour obtenir une erreur et pouvoir envoyer moins de lignes ou augmenter num_ctx.

Combien de sources puis-je envoyer ?

L'outil en accepte jusqu'à 50. Le nombre qui tient dépend de leur longueur et de la longueur de contexte : la documentation d'Ollama donne une valeur par défaut de 4k tokens avec moins de 24 GiB de VRAM. Le champ prompt_eval_count de la réponse indique combien de tokens le prompt a utilisés.

L'option JSON garantit-elle des citations correctes ?

Non. Le champ format oblige la réponse à suivre le JSON Schema, mais le modèle peut encore citer la mauvaise source ou citer quelque chose qui n'y figure pas. Vérifiez la réponse avec le RAG Citation Checker.

Puis-je l'utiliser avec l'API compatible OpenAI ?

L'outil écrit la requête native de /api/chat. La documentation d'Ollama indique que les sorties structurées fonctionnent aussi via l'API compatible OpenAI avec response_format, mais la requête a une autre forme.

Mes données sont-elles envoyées quelque part ?

Non. La requête est construite dans votre navigateur. L'outil ne se connecte jamais à Ollama.

Articles liés

Voir aussi