()
| 220 | # ============================================================================= |
| 221 | |
| 222 | def demo_3_constraint_violation(): |
| 223 | print("\n" + "=" * 60) |
| 224 | print("Demo 3: Constraint Violation - Length and Forbidden Phrase") |
| 225 | print("=" * 60) |
| 226 | |
| 227 | schema = ResponseSchema( |
| 228 | max_length=300, |
| 229 | min_length=20, |
| 230 | forbidden_phrases=["I cannot", "As an AI", "I am unable"], |
| 231 | ) |
| 232 | config = ControlLayerConfig(total_tokens=800, max_attempts=3, base_delay_ms=50) |
| 233 | |
| 234 | responses_seq = [ |
| 235 | LONG_RESPONSES[0], |
| 236 | "I cannot provide that information.", |
| 237 | GOOD_TEXT_RESPONSES[0], |
| 238 | ] |
| 239 | llm = make_deterministic_llm(responses_seq) |
| 240 | layer = ControlLayer( |
| 241 | llm_fn=llm, |
| 242 | system_prompt="You are a concise technical assistant.", |
| 243 | schema=schema, |
| 244 | config=config, |
| 245 | ) |
| 246 | layer.register_fallback( |
| 247 | "template", |
| 248 | lambda q: "Unable to generate a compliant response. Please rephrase your query.", |
| 249 | ) |
| 250 | |
| 251 | packet = layer.run( |
| 252 | user_input="Explain what a control layer does in an LLM system.", |
| 253 | constraints=[ |
| 254 | "Keep your response under 300 characters.", |
| 255 | "Do not use refusal phrases.", |
| 256 | ], |
| 257 | ) |
| 258 | |
| 259 | print(f" Final outcome: {'PASSED' if packet.validation.passed else 'FAILED'}") |
| 260 | print(f" Attempts used: {packet.attempts}") |
| 261 | print(f" Strategy: {packet.strategy_used.value}") |
| 262 | print(f" Total latency: {packet.total_latency_ms:.1f}ms") |
| 263 | print(f" Response length: {len(packet.response)} chars") |
| 264 | print(f" Response: {packet.response[:120]}...") |
| 265 | return packet, layer.audit |
| 266 | |
| 267 | |
| 268 | # ============================================================================= |
no test coverage detected