Source: docs/guides/SIMPLE_NOTEBOOK_GUIDE.md
Simple Notebook Guide - Questionnaire to Contract
π― Goal: Show How Example Contracts Guide New Contract Generation
This guide shows the transparent process of using example contracts to generate new ones.
π The 3-Part Pattern
1. Show the Examples (What AI Learns From)
# Load example contracts from ops/
examples_path = project_root / "apps/backend/ops/few_shot_examples/contract_generation_examples.json"
with open(examples_path) as f:
examples = json.load(f)
print("π EXAMPLE CONTRACTS (what AI learns from):")
print("="*80)
for i, example in enumerate(examples['examples'][:2], 1):
print(f"\nEXAMPLE {i}: {example['scenario']}")
print(f" League: {example['input_context']['league_name']}")
print(f" Tier: {example['input_context']['tier']}")
print(f" Annual Fee: ${example['input_context']['annual_fee']:,}")
print(f"\n Contract Sections:")
for section_name, section_content in example['output_sections'].items():
print(f" β’ {section_content['section_title']}")2. Show the Schema (What Structure AI Must Follow)
# Load output schema
from apps.backend.schemas.questionnaire_extraction import LeagueQuestionnaire
schema = LeagueQuestionnaire.model_json_schema()
print("\nπ OUTPUT SCHEMA (structure AI must follow):")
print("="*80)
print(json.dumps({
"title": schema['title'],
"required_fields": schema.get('required', []),
"total_properties": len(schema.get('properties', {}))
}, indent=2))3. Build the Prompt (What AI Actually Receives)
# Assemble the complete prompt
prompt = f"""
You are a contract generation specialist.
LEARN FROM THESE EXAMPLES:
{json.dumps(examples['examples'][:2], indent=2)}
OUTPUT MUST MATCH THIS SCHEMA:
{json.dumps(schema, indent=2)}
NOW GENERATE CONTRACT FOR:
{json.dumps(new_league_data, indent=2)}
"""
print("\nπ§ ASSEMBLED PROMPT (sent to AI):")
print("="*80)
print(prompt[:500] + "...\n[truncated for display]")π¨ Notebook Cell Structure
Cell 1: Setup
# Imports
import sys, json
from pathlib import Path
sys.path.insert(0, str(Path.cwd().parent.parent.parent))
from apps.backend.services.questionnaire_processor.league_processors.contract_generator import ContractGenerator
from apps.backend.schemas.questionnaire_extraction import LeagueQuestionnaireCell 2: Load Example Contracts
print("="*80)
print("STEP 1: LOAD EXAMPLE CONTRACTS (what AI learns from)")
print("="*80)
examples_path = project_root / "apps/backend/ops/few_shot_examples/contract_generation_examples.json"
with open(examples_path) as f:
contract_examples = json.load(f)
# Display examples
for example in contract_examples['examples'][:2]:
print(f"\nπ {example['scenario']}")
print(json.dumps(example, indent=2)[:300] + "...")Cell 3: Load Output Schema
print("\n" + "="*80)
print("STEP 2: LOAD OUTPUT SCHEMA (structure AI must follow)")
print("="*80)
schema = LeagueQuestionnaire.model_json_schema()
print(f"Schema has {len(schema['properties'])} top-level fields")
print(json.dumps(schema, indent=2)[:500] + "...")Cell 4: Load Your Questionnaire
print("\n" + "="*80)
print("STEP 3: PROCESS YOUR QUESTIONNAIRE")
print("="*80)
# Use existing extractor (NO new logic!)
from apps.backend.services.questionnaire_processor.league_processors.questionnaire_extractor import QuestionnaireExtractor
extractor = QuestionnaireExtractor()
league_data = extractor.extract(your_pdf_file)
print(f"Extracted data for: {league_data['league_name']}")Cell 5: Show How Prompt Is Built
print("\n" + "="*80)
print("STEP 4: BUILD PROMPT (examples + schema + your data)")
print("="*80)
assembled_prompt = f"""
EXAMPLES:
{json.dumps(contract_examples['examples'], indent=2)}
SCHEMA:
{json.dumps(schema, indent=2)}
YOUR DATA:
{json.dumps(league_data, indent=2)}
Generate contract following examples and schema.
"""
print("Prompt size:", len(assembled_prompt), "characters")
print(assembled_prompt[:400] + "...\n[truncated]")Cell 6: Generate Contract
print("\n" + "="*80)
print("STEP 5: GENERATE CONTRACT (using existing generator)")
print("="*80)
# Use existing generator (NO new logic!)
generator = ContractGenerator()
contract = generator.generate(league_data)
print(f"β
Contract generated!")
print(contract[:500] + "...")π That's It! Simple Pattern:
- Load examples from
ops/few_shot_examples/ - Load schema from
schemas/ - Use existing services from
services/ - Show each step transparently
No new logic, just using what exists!