feat: Implement Study Interview Mode as default study creation method
Study Interview Mode is now the DEFAULT for all study creation requests. This intelligent Q&A system guides users through optimization setup with: - 7-phase interview flow: introspection → objectives → constraints → design_variables → validation → review → complete - Material-aware validation with 12 materials and fuzzy name matching - Anti-pattern detection for 12 common mistakes (mass-no-constraint, stress-over-yield, etc.) - Auto extractor mapping E1-E24 based on goal keywords - State persistence with JSON serialization and backup rotation - StudyBlueprint generation with full validation Triggers: "create a study", "new study", "optimize this", any study creation intent Skip with: "skip interview", "quick setup", "manual config" Components: - StudyInterviewEngine: Main orchestrator - QuestionEngine: Conditional logic evaluation - EngineeringValidator: MaterialsDatabase + AntiPatternDetector - InterviewPresenter: Markdown formatting for Claude - StudyBlueprint: Validated configuration output - InterviewState: Persistent state management All 129 tests passing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
249
.claude/skills/modules/study-interview-mode.md
Normal file
249
.claude/skills/modules/study-interview-mode.md
Normal file
@@ -0,0 +1,249 @@
|
||||
# Study Interview Mode Skill
|
||||
|
||||
## Purpose
|
||||
|
||||
This skill enables an intelligent interview-based approach to study creation. Instead of asking users to fill out complex configuration files, Claude guides them through a natural conversation to gather all necessary information for optimization study setup.
|
||||
|
||||
**This is now the DEFAULT mode for all study creation.**
|
||||
|
||||
## Triggers (DEFAULT for Study Creation)
|
||||
|
||||
This skill is automatically invoked when the user says ANY of:
|
||||
- "create a study", "new study", "set up study"
|
||||
- "create a study for my bracket"
|
||||
- "optimize this", "optimize my model"
|
||||
- "I want to minimize mass", "I want to reduce weight"
|
||||
- Any study creation request
|
||||
|
||||
### Skip Interview (Manual Mode)
|
||||
|
||||
Only skip to manual mode when user explicitly requests:
|
||||
- "skip interview", "quick setup", "manual config"
|
||||
- Power users recreating known configurations
|
||||
|
||||
## Interview Flow
|
||||
|
||||
### Phase 1: Introspection
|
||||
Before questions begin, automatically analyze the NX model:
|
||||
```python
|
||||
from optimization_engine.interview import StudyInterviewEngine
|
||||
|
||||
engine = StudyInterviewEngine(study_path)
|
||||
|
||||
# Run introspection first (if model available)
|
||||
introspection = {
|
||||
"expressions": [...], # From part introspection
|
||||
"materials": [...], # From simulation
|
||||
"load_cases": [...], # From simulation
|
||||
"model_path": "...",
|
||||
"sim_path": "..."
|
||||
}
|
||||
|
||||
session = engine.start_interview(study_name, introspection=introspection)
|
||||
```
|
||||
|
||||
### Phase 2: Problem Definition
|
||||
Ask about the study's purpose and context:
|
||||
- What are you trying to optimize?
|
||||
- Describe your study in a few words
|
||||
|
||||
### Phase 3: Objectives
|
||||
Determine optimization goals:
|
||||
- Primary goal (minimize mass, stress, displacement, etc.)
|
||||
- Secondary objectives (if any)
|
||||
- Multi-objective or single-objective?
|
||||
|
||||
The ExtractorMapper automatically assigns extractors:
|
||||
- Mass → E4 (BDF Mass) or E5 (CAD Mass)
|
||||
- Displacement → E1
|
||||
- Stress → E3
|
||||
- Frequency → E2
|
||||
- Zernike → E8, E9, E10
|
||||
|
||||
### Phase 4: Constraints
|
||||
Define physical limits:
|
||||
- Material-aware validation (checks against yield stress)
|
||||
- Auto-suggests safety factors
|
||||
- Detects anti-patterns (e.g., mass minimization without constraints)
|
||||
|
||||
### Phase 5: Design Variables
|
||||
Select parameters to vary:
|
||||
- Dynamic options from introspection
|
||||
- Auto-suggests bounds based on current values
|
||||
- Detects too-wide or too-narrow bounds
|
||||
|
||||
### Phase 6: Validation
|
||||
Final checks before generation:
|
||||
- Run baseline simulation (optional)
|
||||
- Verify all parameters accessible
|
||||
- Check for conflicting constraints
|
||||
|
||||
### Phase 7: Review
|
||||
Present StudyBlueprint for confirmation:
|
||||
- Show all settings in readable format
|
||||
- Allow what-if modifications
|
||||
- Confirm or restart
|
||||
|
||||
## Key Classes
|
||||
|
||||
### StudyInterviewEngine
|
||||
Main orchestrator:
|
||||
```python
|
||||
from optimization_engine.interview import StudyInterviewEngine
|
||||
|
||||
engine = StudyInterviewEngine(study_path)
|
||||
session = engine.start_interview(study_name, introspection=introspection)
|
||||
|
||||
# Get first question
|
||||
action = engine.get_first_question()
|
||||
# Present action.message to user
|
||||
|
||||
# Process user answer
|
||||
next_action = engine.process_answer(user_response)
|
||||
|
||||
# When complete, get blueprint
|
||||
if next_action.action_type == "show_summary":
|
||||
blueprint = next_action.blueprint
|
||||
```
|
||||
|
||||
### InterviewState
|
||||
Persisted interview state with JSON serialization:
|
||||
```python
|
||||
from optimization_engine.interview import InterviewState, InterviewStateManager
|
||||
|
||||
manager = InterviewStateManager(study_path)
|
||||
state = manager.load_state() # Resume if exists
|
||||
```
|
||||
|
||||
### StudyBlueprint
|
||||
Validated configuration ready for generation:
|
||||
```python
|
||||
blueprint = engine.generate_blueprint()
|
||||
config = blueprint.to_config_json() # For optimization_config.json
|
||||
```
|
||||
|
||||
## Anti-Pattern Detection
|
||||
|
||||
The EngineeringValidator detects common mistakes:
|
||||
- `mass_no_constraint`: Mass minimization without stress/displacement limits
|
||||
- `stress_over_yield`: Stress constraint exceeds material yield
|
||||
- `bounds_too_wide`: Design variable range > 100x
|
||||
- `too_many_objectives`: More than 3 objectives
|
||||
- `single_dv_many_trials`: Many trials for single variable
|
||||
|
||||
When detected, user is warned and asked to acknowledge.
|
||||
|
||||
## Materials Database
|
||||
|
||||
Built-in materials with properties:
|
||||
- Aluminum alloys (6061-T6, 7075-T6)
|
||||
- Steel grades (A36, 304 SS, 316 SS)
|
||||
- Titanium (Ti-6Al-4V)
|
||||
- Composites (CFRP, GFRP)
|
||||
- Plastics (ABS, Nylon)
|
||||
|
||||
Fuzzy matching supports user input like "Al 6061", "aluminum", "6061-T6".
|
||||
|
||||
## Presenter Modes
|
||||
|
||||
### ClaudePresenter (Default)
|
||||
Markdown-formatted for Claude conversation:
|
||||
```markdown
|
||||
### Question 1 of ~12: Problem Definition
|
||||
|
||||
What are you trying to optimize?
|
||||
|
||||
1. Minimize mass/weight
|
||||
2. Minimize maximum stress
|
||||
3. Minimize displacement
|
||||
4. Maximize natural frequency
|
||||
```
|
||||
|
||||
### DashboardPresenter
|
||||
JSON events for React dashboard (future).
|
||||
|
||||
### CLIPresenter
|
||||
Plain text for command-line interface (future).
|
||||
|
||||
## State Persistence
|
||||
|
||||
Interview state is saved after each answer:
|
||||
```
|
||||
studies/my_study/
|
||||
├── .interview/
|
||||
│ ├── state.json # Current state
|
||||
│ ├── state.lock # Concurrency lock
|
||||
│ ├── interview_log.md # Audit trail
|
||||
│ └── backups/ # State history
|
||||
│ ├── state_20260102_103000.json
|
||||
│ └── ...
|
||||
```
|
||||
|
||||
Supports resume after session interruption.
|
||||
|
||||
## Integration with Study Wizard
|
||||
|
||||
After interview completes:
|
||||
```python
|
||||
from optimization_engine.study.wizard import StudyWizard
|
||||
|
||||
wizard = StudyWizard.from_interview(blueprint, study_path)
|
||||
wizard.generate()
|
||||
```
|
||||
|
||||
## Example Conversation
|
||||
|
||||
**Claude**: Let me help you set up your optimization study. I'll ask a few questions to understand what you're trying to achieve.
|
||||
|
||||
**Claude**: ### Question 1 of ~12: Problem Definition
|
||||
What are you trying to optimize? (You can describe in your own words)
|
||||
|
||||
**User**: I want to make this bracket as light as possible
|
||||
|
||||
**Claude**: Got it - mass minimization. Let me check the material...
|
||||
|
||||
**Claude**: ### Question 2 of ~12: Constraints
|
||||
Your model uses Aluminum 6061-T6 (yield stress: 276 MPa).
|
||||
What's the maximum allowable stress? I recommend staying below 184 MPa (SF=1.5).
|
||||
|
||||
**User**: 200 MPa should be fine
|
||||
|
||||
**Claude**: I notice 200 MPa is close to the yield stress. This allows minimal plastic deformation.
|
||||
Do you want to proceed with this value? [Yes/No]
|
||||
|
||||
**User**: Yes, proceed
|
||||
|
||||
*(Interview continues...)*
|
||||
|
||||
**Claude**: ### Summary
|
||||
Here's your optimization setup:
|
||||
|
||||
| Setting | Value |
|
||||
|---------|-------|
|
||||
| Study Name | bracket_v1 |
|
||||
| Objective | Minimize mass (E4) |
|
||||
| Constraint | Max stress ≤ 200 MPa |
|
||||
| Design Variables | thickness [1-10 mm], rib_height [5-20 mm] |
|
||||
| Trials | 100 |
|
||||
| Sampler | TPE |
|
||||
|
||||
Ready to generate? [Confirm/Modify/Restart]
|
||||
|
||||
## Files Created
|
||||
|
||||
After confirmation, the following are generated:
|
||||
- `optimization_config.json` - From blueprint.to_config_json()
|
||||
- `run_optimization.py` - From SYS_10 or SYS_11 template
|
||||
- `INTERVIEW_LOG.md` - Audit trail of Q&A
|
||||
|
||||
## Error Handling
|
||||
|
||||
If the interview is interrupted:
|
||||
1. State is auto-saved after each answer
|
||||
2. On restart, detect existing state
|
||||
3. Offer to resume or start fresh
|
||||
|
||||
If validation fails:
|
||||
1. Present error with fix suggestion
|
||||
2. Ask user to acknowledge or modify
|
||||
3. Don't block on warnings, only on errors
|
||||
Reference in New Issue
Block a user