OCNORA
aibeginner10 min setupby Mantle

Q&A over a fetched document

Answer a question about any public document: fetch it over HTTP, hand the text plus the question to an LLM with a grounding prompt, and post the answer to a callback URL.

Drag to pan, pinch to zoom. This is the real graph the template installs.

How it works

What it does

  • Webhook in: {question, document_url, callback_url}.
  • Fetch document GETs the URL; Answer from the document runs ai.llm with a grounding system prompt so the model only answers from the fetched text.
  • Post answer to callback delivers {question, answer, document_url} to your callback.

Setup

  • Choose an AI connection on Answer from the document.
  • Optional: put the document behind an HTTP connection (base URL + auth) and use path instead of url on Fetch document.

Nodes 4

  1. 01Questiontrigger.webhookTrigger
  2. 02Fetch documenthttp.requestHTTP
  3. 03Answer from the documentai.llmAI
  4. 04Post answer to callbackhttp.requestHTTP
View template JSON
{
  "format": "mantle-workflow/v1",
  "id": "ai-doc-qa",
  "name": "Q&A over a fetched document",
  "graph": {
    "nodes": [
      {
        "id": "webhook",
        "type": "trigger.webhook",
        "label": "Question",
        "config": {
          "slug": "doc-qa",
          "input_schema": {
            "required": [
              "question",
              "document_url",
              "callback_url"
            ],
            "properties": {
              "question": {
                "type": "string"
              },
              "document_url": {
                "type": "string"
              },
              "callback_url": {
                "type": "string"
              }
            }
          }
        },
        "connection_id": null,
        "worker_type": "generic-worker",
        "position": {
          "x": 60,
          "y": 220
        }
      },
      {
        "id": "fetch_doc",
        "type": "http.request",
        "label": "Fetch document",
        "config": {
          "method": "GET",
          "url": "{{ steps.webhook.document_url }}",
          "timeout_seconds": 20
        },
        "connection_id": null,
        "worker_type": "generic-worker",
        "position": {
          "x": 380,
          "y": 220
        }
      },
      {
        "id": "answer",
        "type": "ai.llm",
        "label": "Answer from the document",
        "config": {
          "model": "claude-sonnet-4-5",
          "temperature": 0,
          "max_tokens": 600,
          "system_prompt": "Answer ONLY from the supplied document. If the answer is not in it, say so. Quote the relevant passage briefly.",
          "user_prompt": "DOCUMENT:\n{{ steps.fetch_doc.body }}\n\nQUESTION: {{ steps.webhook.question }}"
        },
        "connection_id": null,
        "worker_type": "ai-worker",
        "position": {
          "x": 700,
          "y": 220
        }
      },
      {
        "id": "post_answer",
        "type": "http.request",
        "label": "Post answer to callback",
        "config": {
          "method": "POST",
          "url": "{{ steps.webhook.callback_url }}",
          "headers": {
            "Content-Type": "application/json"
          },
          "json": {
            "question": "steps.webhook.question",
            "answer": "steps.answer.response",
            "document_url": "steps.webhook.document_url"
          }
        },
        "connection_id": null,
        "worker_type": "generic-worker",
        "position": {
          "x": 1020,
          "y": 220
        }
      }
    ],
    "edges": [
      {
        "from": "webhook",
        "to": "fetch_doc"
      },
      {
        "from": "fetch_doc",
        "to": "answer"
      },
      {
        "from": "answer",
        "to": "post_answer"
      }
    ]
  }
}

Use it, then make it yours.

Templates install as drafts. Change anything, and Workflow Health re-checks the graph on every save.