Build a document Q&A app with Generic RAG
Build an application that answers questions over a fixed set of documents, without writing code. You create an application of the Generic RAG type, describe its pipeline in properties, and upload the documents once. This guide is for app developers and administrators. It assumes your administrator has deployed DIAL Generic RAG.
Prerequisites
- The Generic RAG application type registered in DIAL Core. Ask your administrator for its ID. The upstream ID is
https://dial.epam.com/application_type_schemas/generic-rag. - Access to two models in DIAL Core: an embeddings model, and an LLM that accepts images.
- To use the API: the DIAL Core URL, an API key, and your bucket ID. See Create a Quick App through the API.
Step 1: Design the pipeline
Write the application's properties. This configuration needs only PostgreSQL. It indexes text two ways, keeps page images for the answers, and lets requests filter by two metadata fields:
{
"metadata_schema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"category": {"type": "string", "enable_filtering": true},
"published_on": {"type": "string", "format": "date", "enable_filtering": true}
},
"additionalProperties": true
},
"parsers": [
{"type": "unstructured_parser"},
{"type": "page_extractor"}
],
"indexes": {
"keywords": {
"display_name": "Keyword search",
"indexer": {"type": "text_normalizer", "language": "english"}
},
"semantic": {
"display_name": "Semantic search",
"indexer": {"type": "text_embeddings", "deployment_name": "text-embedding-3-small"}
}
},
"retriever": {
"type": "classic",
"document_selector": {"type": "explicit"}
},
"generation": {
"type": "default",
"llm": {"deployment_name": "gpt-4.1-2025-04-14"}
}
}
- Parsers.
unstructured_parserextracts text from PDF, Markdown, and plain text.page_extractorkeeps PDF pages as images. - Indexes. Both use the default
pgvectorstorage.keywordsis a full-text index, andsemantican embeddings index. - Retriever.
classicpasses up to 4 page images to the LLM with the text. Theexplicitselector lets each request filter by metadata. - Models. Replace the deployment names with models you have.
For every option, see Generic RAG channel configuration.
Step 2: Create the application
Create the application in DIAL Admin or through the API.
In DIAL Admin. Open the Generic RAG Application Runner and create an application from it. Set the properties from Step 1 in the application's Parameters.
Through the API. Save the application with PUT /v1/applications/{bucket}/{application-path}:
curl -X PUT "https://<DIAL_HOST>/v1/applications/<BUCKET>/policy-docs" \
-H "Content-Type: application/json" \
-H "api-key: <DIAL_API_KEY>" \
-d @- <<'EOF'
{
"displayName": "Policy documents",
"description": "Answers questions about company policies.",
"applicationTypeSchemaId": "https://dial.epam.com/application_type_schemas/generic-rag",
"applicationProperties": <PROPERTIES_FROM_STEP_1>
}
EOF
The application's ID is applications/<BUCKET>/policy-docs. DIAL Core validates the properties against the type's schema and rejects invalid ones.
Step 3: Upload the documents
In DIAL Admin. When your administrator has deployed the frontend, the application's Parameters tab shows its documents. Select Add, choose a file, and fill in the metadata.
Through the API. Upload each file to the channel API:
curl -X POST "https://<DIAL_HOST>/v1/deployments/applications/<BUCKET>/policy-docs/route/channel/documents" \
-H "Api-Key: <DIAL_API_KEY>" \
-F "attachment=@travel-policy.pdf;type=application/pdf" \
-F 'metadata={"category": "travel", "published_on": "2026-01-15"}'
A document is searchable when its status is ready. Check it with GET .../route/channel/documents. When indexing runs in the background, the upload returns with created.
Step 4: Ask questions
Select the application in DIAL Chat and ask a question. Answers cite the documents, with the page for a PDF, and link to them.
Through the API, a request can narrow the search with custom_fields.configuration:
curl -X POST "https://<DIAL_HOST>/openai/deployments/applications/<BUCKET>/policy-docs/chat/completions" \
-H "Content-Type: application/json" \
-H "api-key: <DIAL_API_KEY>" \
-d '{
"messages": [{"role": "user", "content": "How many days ahead must travel be booked?"}],
"custom_fields": {
"configuration": {
"retriever": {
"document_selector": {"type": "explicit", "filters": [{"category": "travel"}]}
}
}
}
}'
Generic RAG answers each message on its own, without the earlier messages of the conversation.
Step 5: Connect the MCP tools
The application is also an MCP server, with tools to list, read, search, and cite the documents. To give them to a Quick App, add a dial-app Toolset:
{
"tool_sets": [
{
"type": "dial-app",
"name": "policies",
"deployment_id": "applications/<BUCKET>/policy-docs",
"transport": "mcp"
}
]
}
See Generic RAG MCP server for the tools, and dial-app for every field.
Result
Users ask the application about the uploaded documents and get answers with citations. Agents use the same documents through MCP tools.
| Symptom | What to check |
|---|---|
| The upload fails with "unsupported file type" | The parsers accept the file's MIME type. |
A document stays created | A background job is queued. Ask your administrator about background jobs. |
A document is ready but never cited | GET .../route/channel/stats: a document with no text chunks had no text to extract. |
| The answer says it couldn't find the answer | Turn on debug stages to see what each index returned. Ask your administrator for ENABLE_DEBUG_STAGES. |
Further reading
- DIAL Generic RAG — how Generic RAG indexes documents and answers questions
- Generic RAG channel configuration — every parser, index, retriever, and generator option
- Generic RAG channel API — manage documents from scripts
- Generic RAG MCP server — the MCP tools every Generic RAG application exposes
- When to use which — other ways to build a DIAL app
- DIAL Admin: Applications — add, import, and configure applications in DIAL Admin