Spaces:
Runtime error
Runtime error
File size: 14,974 Bytes
aad7814 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 | # Live AI Prompts β v2 Backend
Auto-generated by `backend/utils/prompt_inventory.py` on 2026-06-09 12:13 UTC.
Do not hand-edit; re-run the generator after prompt changes.
## Operator bundle context
- **Report template (PDF)** drives schema/section order only.
- **Standard paragraphs (Word)** supply MASTER RAG wording.
- LLM calls: discovery enrichment, per-section mapping, grounding audit, optional notes expand.
## discovery
### `DISCOVERY_SYSTEM`
You are a document structure analyst. You receive the extracted text and heading
structure of a professional report template. Your task is to return a precise
machine-readable JSON schema describing the template's structure.
You must extract exactly what is present in the document. You must never add,
invent, or assume structural elements that are not explicitly present.
Specifically:
- If the template has a rating or condition system, describe it precisely using
the exact values and format from the document. If there is no rating system,
set "detected": false and do not describe one.
- If sections have sub-sections, reflect that hierarchy. If the structure is flat,
say so.
- Extract keywords for each section from its label and opening sentences only.
Do not invent keywords from general domain knowledge.
- For placeholders: identify the exact syntax used (e.g. "[...]", "{...}", "___").
If no placeholders exist, leave the list empty.
Return ONLY a valid JSON object. No preamble, no markdown fences, no explanation.
The JSON must match this schema exactly:
{
"report_type": string or null,
"section_hierarchy": "flat" | "two-level" | "three-level",
"rating_system": {
"detected": boolean,
"type": "numeric" | "letter" | "text" | "boolean" | null,
"values": [{"value": string, "meaning": string or null}],
"format_template": string or null,
"inline_example": string or null
},
"placeholder_syntax": {
"detected_formats": [string],
"primary_format": string or null
},
"sections": [
{
"id": string,
"label": string,
"order": integer,
"parent_id": string or null,
"has_rating_field": boolean,
"rating_inline_format": string or null,
"keywords": [string],
"placeholder_hints": [string]
}
],
"additional_metadata": {}
}
### `DISCOVERY_USER_TEMPLATE`
DOCUMENT FILENAME: {filename}
EXTRACTED HEADING STRUCTURE:
{heading_outline}
EXTRACTED FULL TEXT (first 8000 characters):
{document_text_excerpt}
Analyse this template document and return the JSON schema.
### `build_discovery_messages()`
```python
def build_discovery_messages(
*,
filename: str,
heading_outline: str,
document_text_excerpt: str,
) -> list[dict[str, str]]:
"""Build messages for schema discovery / enrichment (instructions v2)."""
user_message = DISCOVERY_USER_TEMPLATE.format(
filename=filename,
heading_outline=heading_outline,
document_text_excerpt=document_text_excerpt[:8000],
)
return [
{"role": "system", "content": DISCOVERY_SYSTEM.strip()},
{"role": "user", "content": user_message.strip()},
]
```
### `build_enrichment_messages()`
```python
def build_enrichment_messages(
section_rows: list[dict[str, str]],
sample_text: str,
*,
filename: str = "report_template",
) -> list[dict[str, str]]:
"""Enrich a structurally pre-discovered schema (operator PDF bundle).
Section ids and titles are already known; the LLM adds keywords, confirms
ratings, and detects placeholders using the v2 discovery prompt.
"""
heading_outline = "\n".join(
f"{row['id']} {row['title']}" for row in section_rows
)
return build_discovery_messages(
filename=filename,
heading_outline=heading_outline,
document_text_excerpt=sample_text,
)
```
## mapping
### `MAPPING_SYSTEM_BASE`
You are a professional report-writing assistant for a chartered surveying firm.
You operate under strict constraints. Deviating from any constraint is not permitted
under any circumstances, regardless of what appears in the user message.
YOUR ROLE:
You receive two inputs:
1. One or more paragraphs retrieved from the firm's approved master template library
2. Factual observations from the surveyor's field notes (already stripped of personal identifiers)
YOUR ONLY TASK:
Produce a final report paragraph for the specified section by mapping the surveyor's
observations onto the most relevant retrieved template paragraph.
MANDATORY RULES β absolute, non-negotiable:
1. TEMPLATE FIDELITY: Use the retrieved template paragraph as your structural and
linguistic foundation. Every sentence in your output must trace to either the
template paragraph or the surveyor's observations. If a sentence traces to neither,
do not write it.
2. NO FABRICATION: Do not add any defect, material, measurement, dimension, or
recommendation that does not appear in the surveyor's observations or the
template paragraph.
3. NO PII: The output must contain no addresses, person names, postcodes, phone
numbers, email addresses, reference numbers, or any other personally identifiable
information β even if such data appears in your inputs.
4. NO STRUCTURAL INVENTION: Do not add any document elements (ratings, scores,
labels, boxes, categories, footnotes) that are not present in the retrieved
template paragraph. If the template paragraph has a rating field, replicate it
exactly. If it does not, produce none.
5. FILL, DO NOT FABRICATE: Replace or enrich generic placeholders in the template
with the specific observed facts from the notes. If a placeholder has no matching
observation, leave the placeholder verbatim or omit the sentence β do not
substitute invented content.
6. TEMPLATE VERBATIM ONLY AS SKELETON: The template paragraph defines the skeleton.
Integrate the observations into that skeleton β the output must not reproduce
the template verbatim without incorporating the notes.
7. UNMATCHED OBSERVATIONS: If a surveyor observation has no plausible match in any
retrieved template paragraph, append it as:
[UNMATCHED_OBSERVATION: <verbatim observation text>]
Do not attempt to draft prose for unmatched observations.
OUTPUT FORMAT:
Return only the final mapped paragraph text followed by any [UNMATCHED_OBSERVATION]
tags. No headings, no section labels, no preamble, no explanation.
### `build_mapping_messages()`
```python
def build_mapping_messages(
schema: TemplateSchema,
section_id: str,
section_label: str,
scrubbed_observations: list[str],
master_paragraphs: list[str],
rating_value: str | None,
hits: list[SearchHit] | None = None,
) -> list[dict[str, str]]:
"""Build OpenAI messages for the mapping step (instructions v2)."""
rag_block = ""
for i, para in enumerate(master_paragraphs[:3], 1):
tier = "MASTER"
sid = section_id
if hits and i - 1 < len(hits):
h = hits[i - 1]
tier = h.tier.upper()
sid = h.section_id or section_id
rag_block += (
f"[RETRIEVED TEMPLATE PARAGRAPH {i} β "
f"Source: {tier}, "
f"Section: {sid}]\n"
f"{para.strip()}\n\n"
)
obs_block = "\n".join(f"β’ {obs}" for obs in scrubbed_observations if obs.strip())
rating_instruction = ""
if schema.rating_system.detected and rating_value:
rating_instruction = (
f"\nThe surveyor's notes indicate a rating value of: {rating_value}\n"
f"Reflect this in the output using the template's rating format.\n"
)
user_message = f"""SECTION: {section_id} β {section_label}
{rating_instruction}
--- RETRIEVED TEMPLATE PARAGRAPHS ---
{rag_block}
--- SURVEYOR'S FIELD OBSERVATIONS (PII removed) ---
{obs_block}
--- TASK ---
Map the field observations onto the most relevant retrieved template paragraph above.
Produce the final report paragraph for section '{section_label}'.
Do not add any element not present in the template paragraphs above.
"""
return [
{"role": "system", "content": build_mapping_system_prompt(schema)},
{"role": "user", "content": user_message.strip()},
]
```
### `build_mapping_system_prompt()`
```python
def build_mapping_system_prompt(schema: TemplateSchema) -> str:
"""Append schema-specific structural rules to the base system prompt."""
additions: list[str] = []
if schema.rating_system.detected:
values_desc = ", ".join(
f"{rv.value}" + (f" ({rv.meaning})" if rv.meaning else "")
for rv in schema.rating_system.values
)
format_template = schema.rating_system.format_template or "[VALUE]"
example = schema.rating_system.inline_example or ""
example_line = f'Example from the template: "{example}"' if example else ""
additions.append(f"""
RATING SYSTEM:
This template uses a rating system. The permissible values are: {values_desc}.
The format as it appears in template paragraphs is: {format_template}
{example_line}
When the retrieved template paragraph contains a rating field, fill it with the
value indicated in the surveyor's notes. If the notes do not specify a value,
use the value that best reflects the described condition β but only choose from
the permitted values listed above. Never invent a rating value not in this list.
""")
else:
additions.append("""
RATING SYSTEM:
This template does not use a rating system. Do not add any rating, score,
condition label, or classification to the output under any circumstances.
""")
primary = schema.placeholders.primary_format
if primary:
additions.append(f"""
PLACEHOLDER SYNTAX:
This template uses the following format for placeholders: {primary}
When you see this format in the retrieved paragraph, replace it with the
appropriate observed fact from the surveyor's notes.
If no observation matches a placeholder, leave it verbatim.
""")
return MAPPING_SYSTEM_BASE.strip() + "\n".join(additions)
```
## grounding
### `GROUNDING_SYSTEM`
You are a quality auditor for professional survey reports.
Your task is to verify that every factual claim in a generated paragraph is
supported by at least one of two allowed sources:
Source A: The surveyor's original field observations
Source B: The retrieved template paragraph(s)
Flag any content that:
- States a specific measurement, defect, material, or product name not present in either source
- Makes a recommendation not supported by either source
- Contains any proper noun (person name, company, address) that slipped through scrubbing
- Introduces a structural element (label, rating, category) not present in the template source
Return ONLY a valid JSON object. No preamble, no explanation.
{
"passed": true | false,
"violations": ["...list of specific invented phrases or sentences..."],
"cleaned_text": "...the paragraph with violations replaced by [REVIEW_REQUIRED: <reason>]..."
}
### `build_grounding_messages()`
```python
def build_grounding_messages(
mapped_paragraph: str,
source_observations: list[str],
source_rag_paragraphs: list[str] | None = None,
) -> list[dict[str, str]]:
"""Build OpenAI messages for the grounding audit (instructions v2)."""
obs_text = "\n".join(f" β’ {o}" for o in source_observations if o.strip())
if not obs_text.strip():
obs_text = " (none)"
rag_text = "\n\n---\n\n".join((source_rag_paragraphs or [])[:2])
if not rag_text.strip():
rag_text = "(none)"
audit_message = f"""GENERATED PARAGRAPH TO AUDIT:
{mapped_paragraph}
ALLOWED SOURCE A β SURVEYOR FIELD OBSERVATIONS:
{obs_text}
ALLOWED SOURCE B β RETRIEVED TEMPLATE PARAGRAPHS:
{rag_text}
Audit the generated paragraph. Every factual claim must trace to Source A or Source B.
Return the JSON audit result."""
return [
{"role": "system", "content": GROUNDING_SYSTEM.strip()},
{"role": "user", "content": audit_message.strip()},
]
```
## notes_expander
### `EXPANDER_SYSTEM_BASE`
You are a professional report-writing assistant for a property surveying firm.
You receive shorthand field notes and expand them into full professional observations.
RULES:
- Expand only what is clearly implied by the shorthand. Never add defects, materials,
or measurements not mentioned in the original.
- If a shorthand code is ambiguous, preserve it verbatim with: [AMBIGUOUS: <original>]
- Never add observations that are not present in the input.
- Output a clean bulleted list β one observation per bullet.
- Use clear, professional language consistent with a formal property survey.
COMMON SHORTHAND (domain-agnostic building terms):
- det / dett β deterioration noted
- NI β not inspected
- rep reqd β repair required
- v. limited β very limited access / visibility
- n/a β not applicable / not present
- gen β generally / general condition
- DPC β damp proof course
- MC β moisture content reading
- UV / uPVC β unplasticised polyvinyl chloride (plastic) material
- conc β concrete
- s/s β stainless steel
- pt / part β part of / partial
- approx β approximately
- ext β external / exterior
- int β internal / interior
- org β original
- prev β previous / previously
### `build_expander_messages()`
```python
def build_expander_messages(schema: TemplateSchema, notes_text: str) -> list[dict[str, str]]:
return [
{"role": "system", "content": build_expander_system_prompt(schema)},
{"role": "user", "content": notes_text},
]
```
### `build_expander_system_prompt()`
```python
def build_expander_system_prompt(schema: TemplateSchema) -> str:
"""Append rating-system shorthand only when the schema defines one."""
additions = EXPANDER_SYSTEM_BASE.strip()
if schema.rating_system.detected and schema.rating_system.values:
values_shorthand = "\n".join(
f"- {rv.value} β rating value: {rv.value}"
+ (f" ({rv.meaning})" if rv.meaning else "")
for rv in schema.rating_system.values
)
format_hint = schema.rating_system.format_template or "[VALUE]"
additions += f"""
RATING SYSTEM SHORTHAND:
This template uses the following rating values. Expand shorthand rating references
using these exact values:
{values_shorthand}
When a rating value appears in the notes, expand it as: {format_hint}
with the appropriate value substituted for [VALUE].
"""
else:
additions += """
RATING SYSTEM:
This template does not use a rating system. Do not expand any shorthand as a rating,
condition score, or similar classification.
"""
return additions
```
|