Prompt Studio is Unstract's flagship feature for no-code document extraction using natural language prompts. This page describes the overall architecture, showing how frontend IDE components, backend services, and tool execution layers interact to enable prompt-based extraction from documents.
The architecture follows a three-tier model:
For specific component implementations, see Frontend IDE Components for UI details, Backend Helper and Orchestration for server-side logic, and Document Management and Indexing for the indexing pipeline.
Prompt Studio Architecture within Unstract Platform
The architecture follows a layered approach where the frontend IDE communicates with Django backend services, which orchestrate document processing, prompt execution via Flask service, and tool execution using containerized adapters.
Sources:
Prompt Studio uses several Django models to store tool configuration, prompts, documents, and execution results.
Data Model Relationships
Key Models:
| Model | Primary Key | Purpose |
|---|---|---|
CustomTool | tool_id (UUID) | Top-level tool configuration including preamble, postamble, challenge settings |
ToolStudioPrompt | prompt_id (UUID) | Individual prompts with key, text, enforce_type, and profile_manager FK |
ProfileManager | profile_id (UUID) | LLM/VectorDB/Embedding/X2Text adapter configuration per tool |
DocumentManager | document_id (UUID) | Uploaded document metadata linked to tool |
PromptStudioOutputManager | Auto-increment ID | Execution results with output JSON, token usage, eval metrics |
Model Field Details:
CustomTool backend/prompt_studio/prompt_studio_core_v2/models.py37-127:
tool_name, description, author - Tool metadatapreamble, postamble, prompt_grammer - Prompt formattingenable_challenge, challenge_llm - LLM challenge featuresummarize_context, summarize_as_source, summarize_llm_adapter - Summarization settingssingle_pass_extraction_mode, enable_highlight - Extraction optionsToolStudioPrompt backend/prompt_studio/prompt_studio_v2/models.py11-58:
prompt_key - Unique identifier for output fieldprompt - LLM prompt textenforce_type - Output type: text, number, email, date, boolean, json, line-item, tableactive, required - Prompt flagsprofile_manager - FK to ProfileManager (can override tool default)ProfileManager backend/prompt_studio/prompt_profile_manager_v2/models.py1-100:
llm, vector_store, embedding_model, x2text - FKs to AdapterInstancechunk_size, chunk_overlap - Chunking parametersretrieval_strategy - RAG strategy: simple, subquestion, fusionsimilarity_top_k - Number of chunks to retrieveSources:
Document Ingestion and Extraction Pipeline
Step-by-Step Flow:
Document Upload: User uploads document via ManageDocsModal → Django backend saves to MinIO → Creates DocumentManager record
Document Indexing backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py316-471:
PromptStudioHelper.index_document() orchestrates indexingdynamic_extractor() to extract text via X2Text serviceDocumentIndexingService.index_document() chunks text, generates embeddings, stores in VectorDBvector_db + embedding + x2text + chunk_size + chunk_overlap + file_pathPrompt Execution backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py510-712:
prompt_responder() called with tool_id, document_id, prompt_id, profile_manager_id_execute_single_prompt() - Single prompt with specific LLM profile_execute_prompts_in_single_pass() - All prompts in one LLM call (excludes TABLE/RECORD types)_fetch_response() validates profile, generates doc_id, calls Prompt ServicePrompt Service Execution prompt-service/src/unstract/prompt_service/controllers/answer_prompt.py38-653:
answer_prompt controller receives request with prompts arrayVariableReplacementService replaces %variable% placeholdersRetrievalService.perform_retrieval() queries VectorDB for context (if chunk_size > 0)AnswerPromptService.run_completion() sends prompt + context to LLMAnswerPromptService.handle_json() parses JSON responsesOutput Storage: Results saved to PromptStudioOutputManager model, UI updated via Zustand stores
Sources:
PromptStudioHelper backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py84-1504 is the main orchestration layer for Prompt Studio operations.
Key Methods:
| Method | Purpose | Returns |
|---|---|---|
index_document() | Orchestrates document indexing | doc_id (index key) |
prompt_responder() | Executes prompts against documents | Dict with output and metadata |
_fetch_response() | Calls Prompt Service for single prompt | Response from Prompt Service |
_fetch_single_pass_response() | Calls Prompt Service for all prompts | Response from Prompt Service |
dynamic_indexer() | Creates vector index for document | Index result or pending status |
dynamic_extractor() | Extracts text from document | Extracted text string |
summarize() | Generates document summary | Summary file path |
Indexing Flow backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py316-471:
Prompt Execution Flow backend/prompt_studio/prompt_studio_core_v2/prompt_studio_helper.py510-712:
Sources:
PromptStudioRegistryHelper backend/prompt_studio/prompt_studio_registry_v2/prompt_studio_registry_helper.py32-450 handles exporting Prompt Studio tools to the tool registry for use in workflows and API deployments.
Export Process:
Spec Generation backend/prompt_studio/prompt_studio_registry_v2/prompt_studio_registry_helper.py40-95:
The spec defines tool settings as a JSON schema:
challenge_llm - LLM adapter for challenge featureenable_challenge - Boolean flagsummarize_as_source - Use summarized textsingle_pass_extraction_mode - Execution modeenable_highlight, enable_word_confidence - Highlight featuresSources:
The PromptCard component manages individual prompt instances with their configuration and execution state. It acts as a container that coordinates between user interactions, backend API calls, and real-time WebSocket updates.
File: frontend/src/components/custom-tools/prompt-card/PromptCard.jsx17-372
Key Responsibilities:
promptDetailsState, promptKey, promptText)selectedLlmProfileIdState Structure:
| State Variable | Type | Purpose |
|---|---|---|
promptDetailsState | Object | Local copy of prompt configuration |
promptKey | String | Unique identifier for prompt output |
promptText | String | LLM prompt text content |
selectedLlmProfileId | String | Active LLM profile ID |
updateStatus | Object | Save operation status tracking |
progressMsg | Object | WebSocket execution messages |
isCoverageLoading | Boolean | Coverage computation status |
Key Methods:
handleChange() - Updates prompt properties and syncs to backendhandleRun() - Validates inputs and triggers prompt executionhandleSelectDefaultLLM() - Changes active LLM profilehandleSelectHighlight() - Updates document highlight based on outputSources:
The PromptCardItems component renders the UI structure of a prompt card, delegating to specialized subcomponents for different sections.
File: frontend/src/components/custom-tools/prompt-card/PromptCardItems.jsx32-370
Component Structure:
State Management:
| State Variable | Purpose |
|---|---|
llmProfileDetails | Array of available LLM profiles with metadata |
enforceType | Output type constraint (Text, JSON, Table) |
tableSettings | Configuration for table extraction mode |
enabledProfiles | List of active LLM profiles for multi-pass |
Props Flow:
PromptCard props
↓
PromptCardItems props
↓
├─→ Header (run handlers, delete handler, status)
├─→ EditableText (onChange handlers, validation)
└─→ PromptOutput (outputs, coverage, token usage)
Sources:
The Header component provides controls for prompt execution and management at the top of each prompt card.
File: frontend/src/components/custom-tools/prompt-card/Header.jsx32-334
Run Button Configuration:
| Button Label | Prompt Run Type | Scope |
|---|---|---|
| "Run" | RUN_ONE_PROMPT_ONE_LLM_ONE_DOC | Single prompt, default LLM, current doc |
| "Run All" (docs) | RUN_ONE_PROMPT_ALL_LLMS_ALL_DOCS | Single prompt, all LLMs, all docs |
| "Run All" (LLMs) | RUN_ONE_PROMPT_ALL_LLMS_ONE_DOC | Single prompt, all LLMs, current doc |
Status Indicators:
The updateStatus object displays one of three states:
promptStudioUpdateStatus.isUpdating - Blue loading tagpromptStudioUpdateStatus.done - Green success tag (3s timeout)promptStudioUpdateStatus.validationError - Red error tagDropdown Menu Actions:
active field)ConfirmModal)Sources:
The PromptOutput component handles execution result display with different rendering modes based on whether single-pass or multi-pass extraction is enabled.
File: frontend/src/components/custom-tools/prompt-card/PromptOutput.jsx56-516
Execution Modes:
Single Pass Mode (singlePassExtractMode = true):
defaultLlmProfile for all promptsMulti Pass Mode (singlePassExtractMode = false):
CheckableTag components control profile enablementOutput Key Generation:
Rendering Logic:
| Enforce Type | Component | Description |
|---|---|---|
TABLE | TableOutput (plugin) | Structured table view |
JSON | DisplayPromptResult | Formatted JSON with syntax highlighting |
| Other | DisplayPromptResult | Plain text display |
Profile Card Components:
TokenUsage - Displays token counts (embedding, prompt, completion)PromptRunTimer - Shows execution durationPromptRunCost - Calculates cost based on token usageSources:
The DocumentManager component provides multi-format document viewing with navigation controls and a management modal for document operations.
File: frontend/src/components/custom-tools/document-manager/DocumentManager.jsx78-481
View Tabs:
| Tab Key | Label | Component | API View Type |
|---|---|---|---|
| "1" | PDF View | PdfViewer / TextViewer | viewTypes.original |
| "2" | Raw View | TextViewerPre | viewTypes.extract |
| "3" | Summary View | SummarizeView (plugin) | N/A |
Document Loading Flow:
handleFetchContent(viewType)
↓
getDocuments(toolId, docId, viewType)
↓
GET /api/v1/unstract/{orgId}/prompt-studio/file/{toolId}
?document_id={docId}&view_type={viewType}
↓
base64toBlobWithMime(data, mimeType)
↓
setFileUrl() or setExtractTxt()
Document Type Rendering:
.pdf → PdfViewer with highlight support.txt, .md → TextViewer componentNavigation:
listOfDocs arrayselectedDoc in store, triggering re-fetchSources:
The ManageDocsModal component provides a modal interface for document lifecycle management including upload, indexing, deletion, and status monitoring.
File: frontend/src/components/custom-tools/manage-docs-modal/ManageDocsModal.jsx66-818
Upload Workflow:
beforeUpload(file)
↓
Validate file name uniqueness
↓
Check file type (PDF vs. non-PDF)
↓
ConfirmMultiDoc modal (if non-PDF, plugin-based)
↓
handleUploadChange(info)
↓
POST /api/v1/unstract/{orgId}/prompt-studio/file/{toolId}
↓
Update listOfDocs in store
Index Status Tracking:
The component maintains two index status arrays:
rawIndexStatus - Vector index for standard retrievalsummarizeIndexStatus - Summary-based retrieval (plugin)Index status structure:
Table Columns:
| Column | Data | Conditional Rendering |
|---|---|---|
| Document Variants | document_name | Always shown |
| Raw View | Index status + LLM profile name | Always shown |
| Summary View | Summary index status | Only if SummarizeStatusTitle plugin available |
| Actions | Reindex button + progress message | Always shown |
| Delete | Delete button (with confirmation) | Always shown |
| Select | Radio button | Always shown |
Real-time Updates:
WebSocket messages from useSocketCustomToolStore update indexMessages state:
Sources:
The CombinedOutput component aggregates and displays outputs from all prompts for the selected document, supporting both default profile and multi-profile views.
File: frontend/src/components/custom-tools/combined-output/CombinedOutput.jsx47-243
View Modes:
Default Profile Mode (activeKey === "0"):
/prompt-studio/prompt-output/prompt-default-profile/profile_managerprompt_keySpecific Profile Mode (activeKey !== "0"):
selectedProfile{ prompt_id, profile_manager, output } objectsOutput Processing:
JsonView Subcomponent:
ProfileInfoBar shows selected profile metadataSources:
The OutputForDocModal component displays a coverage view showing prompt execution results across all document variants for a specific prompt.
File: frontend/src/components/custom-tools/output-for-doc-modal/OutputForDocModal.jsx46-390
Profile Tab Switching:
API Endpoint:
GET /api/v1/unstract/{orgId}/prompt-studio/prompt-output/
?tool_id={toolId}
&prompt_id={promptId}
&profile_manager={profile}
&is_single_pass_extract={singlePassExtractMode}
Table Display:
| Column | Conditional | Data Source |
|---|---|---|
| Document Variants | Always | listOfDocs[].document_name |
| Token Count | !singlePassExtractMode | output?.token_usage?.total_tokens |
| Value | Always | Status icon + displayPromptResult(output) |
Status Icons:
InfoCircleFilled (orange) - Output is undefinedCloseCircleFilled (red) - Output is null/falseCheckCircleFilled (green) - Output has valueDocument Ordering:
moveSelectedDocToTop() ensures currently selected document appears first in the table.
Sources:
Frontend to Backend Communication
Key Endpoints:
| Endpoint | Method | Component | Backend Handler |
|---|---|---|---|
/prompt-studio/{tool_id}/ | GET | CustomToolsHelper | Returns CustomTool with prompts |
/prompt-studio/prompt-studio-prompt/{tool_id}/ | PATCH | PromptCard | Updates ToolStudioPrompt |
/prompt-studio/file/{tool_id} | POST | ManageDocsModal | Creates DocumentManager |
/prompt-studio/index-document/{tool_id} | POST | ManageDocsModal | Calls index_document() |
/prompt-studio/prompt-output/ | GET | CombinedOutput | Returns PromptStudioOutputManager records |
/prompt-studio/export/{tool_id} | POST | Header | Calls PromptStudioRegistryHelper.export() |
Sources:
useCustomToolStore frontend/src/store/custom-tool-store.js1-161:
WebSocket Integration frontend/src/store/socket-custom-tool.js1-50:
Real-time messages from backend via WebSocket for indexing/execution progress:
Sources:
Prompt Studio supports two execution strategies:
Multi-Pass Extraction (Default):
profile_manager settingsenforce_type values including table and recordSingle-Pass Extraction:
profile_manager for all promptstable and record type promptsControlled by CustomTool.single_pass_extraction_mode backend/prompt_studio/prompt_studio_core_v2/models.py84-87 and frontend state singlePassExtractMode frontend/src/store/custom-tool-store.js22
Sources:
CustomTool configuration options backend/prompt_studio/prompt_studio_core_v2/models.py37-127:
| Setting | Type | Purpose |
|---|---|---|
preamble | TextField | Text prepended to all prompts |
postamble | TextField | Text appended to all prompts |
prompt_grammer | JSONField | Synonyms for domain terminology |
enable_challenge | Boolean | Enable LLM challenge feature |
challenge_llm | FK | Adapter for challenge verification |
monitor_llm | FK | Adapter for evaluation monitoring |
summarize_context | Boolean | Enable document summarization |
summarize_as_source | Boolean | Use summary instead of raw text |
summarize_llm_adapter | FK | Adapter for summarization |
single_pass_extraction_mode | Boolean | All prompts in one LLM call |
enable_highlight | Boolean | Generate document highlights |
enable_word_confidence | Boolean | Word-level confidence scores |
ToolStudioPrompt.enforce_type backend/prompt_studio/prompt_studio_v2/models.py17-33 specifies output format:
Frontend dropdown populated from backend/prompt_studio/prompt_studio_core_v2/static/select_choices.json10-18
Sources:
Tool export process for use in workflows and API deployments:
Export Flow for Prompt Studio Tools
Export Data Structure backend/prompt_studio/prompt_studio_registry_v2/prompt_studio_registry_helper.py40-113:
Export Behavior:
PromptStudioRegistry recordis_shared_with_org flagforce_export=True to overwrite existing deploymentsSources:
The CustomToolsHelper component (frontend/src/components/helpers/custom-tools/CustomToolsHelper.js20-146) provides the data loading foundation:
| Component | Primary APIs | Data Updates |
|---|---|---|
PromptCard | /prompt-studio/prompt/{id}/ PATCH | promptDetailsState |
ManageDocsModal | /prompt-studio/file/{toolId} POST/DELETE | listOfDocs |
OutputForDocModal | /prompt-studio/prompt-output/ GET | promptOutputs |
CombinedOutput | /prompt-studio/prompt-output/prompt-default-profile/ | Combined results |
DocumentManager | /prompt-studio/file/{toolId} GET | fileUrl, extractTxt |
Sources:
The PromptCard component allows users to:
Sources:
The system supports highlighting relevant portions of documents based on prompt outputs:
Sources:
Additional features for customizing prompt behavior:
Sources:
The Prompt Management UI integrates with other parts of the Unstract platform:
Sources:
The ToolIde component serves as the main container for the Prompt Management UI, combining:
Sources:
The ToolsMain component organizes the prompt management interface with:
Sources:
The Prompt Management UI provides a comprehensive interface for creating, editing, and executing prompts against documents using language models. It enables users to extract structured information from unstructured documents through a flexible and powerful prompt engineering workflow.
Key capabilities include:
The user interface is designed to provide a seamless experience for prompt engineering, with real-time feedback and powerful visualization tools to help users refine their prompts for optimal information extraction.
Refresh this wiki