| <!DOCTYPE html> |
| <html lang="de"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>AgentArena — E8 Experiment + Run Pipeline</title> |
| <style> |
| :root { |
| --bg-primary: #0d0d1a; |
| --bg-secondary: #1a1a2e; |
| --bg-card: #16213e; |
| --bg-setup: rgba(59, 130, 246, 0.06); |
| --bg-execution: rgba(16, 185, 129, 0.06); |
| --bg-evaluation: rgba(168, 85, 247, 0.06); |
| --border-setup: rgba(59, 130, 246, 0.25); |
| --border-execution: rgba(16, 185, 129, 0.25); |
| --border-evaluation: rgba(168, 85, 247, 0.25); |
| --accent-setup: #3b82f6; |
| --accent-execution: #10b981; |
| --accent-evaluation: #a855f7; |
| --accent-exp: #f59e0b; |
| --accent-exp-dim: rgba(245, 158, 11, 0.12); |
| --accent-exp-border: rgba(245, 158, 11, 0.28); |
| --accent-baseline: #94a3b8; |
| --accent-injected: #10b981; |
| --text-primary: #e2e8f0; |
| --text-secondary: #94a3b8; |
| --text-muted: #64748b; |
| --connector: #334155; |
| --step-bg: #1e293b; |
| --step-hover: #243452; |
| --step-active: #1e3a5f; |
| --mono: 'Fira Code', 'Cascadia Code', 'Consolas', monospace; |
| --sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; |
| --radius: 10px; |
| --transition: 0.22s cubic-bezier(0.4, 0, 0.2, 1); |
| } |
| |
| * { |
| box-sizing: border-box; |
| margin: 0; |
| padding: 0; |
| } |
| |
| body { |
| background: var(--bg-primary); |
| color: var(--text-primary); |
| font-family: var(--sans); |
| min-height: 100vh; |
| line-height: 1.6; |
| padding: 0 0 80px; |
| } |
| |
| |
| .header { |
| background: linear-gradient(135deg, #0d0d1a 0%, #16213e 50%, #0d0d1a 100%); |
| border-bottom: 1px solid rgba(255,255,255,0.06); |
| padding: 48px 24px 40px; |
| text-align: center; |
| position: relative; |
| overflow: hidden; |
| } |
| |
| .header::before { |
| content: ''; |
| position: absolute; |
| inset: 0; |
| background: |
| radial-gradient(ellipse 60% 40% at 20% 50%, rgba(59,130,246,0.07) 0%, transparent 70%), |
| radial-gradient(ellipse 60% 40% at 80% 50%, rgba(168,85,247,0.07) 0%, transparent 70%); |
| pointer-events: none; |
| } |
| |
| .header-badge { |
| display: inline-flex; |
| align-items: center; |
| gap: 8px; |
| background: rgba(255,255,255,0.05); |
| border: 1px solid rgba(255,255,255,0.1); |
| border-radius: 999px; |
| padding: 4px 14px; |
| font-size: 11px; |
| font-family: var(--mono); |
| color: var(--text-muted); |
| letter-spacing: 0.08em; |
| text-transform: uppercase; |
| margin-bottom: 20px; |
| } |
| |
| .header-badge .dot { |
| width: 6px; |
| height: 6px; |
| border-radius: 50%; |
| background: #10b981; |
| box-shadow: 0 0 8px #10b981; |
| animation: pulse 2s ease infinite; |
| } |
| |
| @keyframes pulse { |
| 0%, 100% { opacity: 1; } |
| 50% { opacity: 0.4; } |
| } |
| |
| h1 { |
| font-size: clamp(26px, 5vw, 42px); |
| font-weight: 700; |
| letter-spacing: -0.02em; |
| margin-bottom: 10px; |
| background: linear-gradient(135deg, #e2e8f0 30%, #94a3b8 100%); |
| -webkit-background-clip: text; |
| -webkit-text-fill-color: transparent; |
| background-clip: text; |
| } |
| |
| h1 span { |
| background: linear-gradient(135deg, #3b82f6, #a855f7); |
| -webkit-background-clip: text; |
| -webkit-text-fill-color: transparent; |
| background-clip: text; |
| } |
| |
| .subtitle { |
| color: var(--text-secondary); |
| font-size: 15px; |
| max-width: 520px; |
| margin: 0 auto; |
| } |
| |
| |
| .legend { |
| display: flex; |
| justify-content: center; |
| flex-wrap: wrap; |
| gap: 12px; |
| padding: 24px 24px 0; |
| } |
| |
| .legend-item { |
| display: flex; |
| align-items: center; |
| gap: 8px; |
| background: var(--bg-card); |
| border-radius: 999px; |
| padding: 6px 16px; |
| font-size: 12px; |
| font-weight: 500; |
| color: var(--text-secondary); |
| border: 1px solid rgba(255,255,255,0.06); |
| } |
| |
| .legend-dot { |
| width: 8px; |
| height: 8px; |
| border-radius: 50%; |
| flex-shrink: 0; |
| } |
| |
| .legend-item.setup .legend-dot { background: var(--accent-setup); box-shadow: 0 0 8px var(--accent-setup); } |
| .legend-item.exec .legend-dot { background: var(--accent-execution); box-shadow: 0 0 8px var(--accent-execution); } |
| .legend-item.eval .legend-dot { background: var(--accent-evaluation); box-shadow: 0 0 8px var(--accent-evaluation); } |
| |
| |
| .pipeline-wrapper { |
| max-width: 780px; |
| margin: 36px auto 0; |
| padding: 0 16px; |
| display: flex; |
| flex-direction: column; |
| gap: 0; |
| } |
| |
| |
| .phase-block { |
| border-radius: 16px; |
| padding: 6px; |
| margin-bottom: 6px; |
| position: relative; |
| } |
| |
| .phase-block.setup { |
| background: var(--bg-setup); |
| border: 1px solid var(--border-setup); |
| } |
| |
| .phase-block.execution { |
| background: var(--bg-execution); |
| border: 1px solid var(--border-execution); |
| } |
| |
| .phase-block.evaluation { |
| background: var(--bg-evaluation); |
| border: 1px solid var(--border-evaluation); |
| } |
| |
| .phase-label { |
| font-size: 10px; |
| font-weight: 700; |
| letter-spacing: 0.12em; |
| text-transform: uppercase; |
| padding: 6px 14px 4px; |
| opacity: 0.8; |
| } |
| |
| .phase-block.setup .phase-label { color: var(--accent-setup); } |
| .phase-block.execution .phase-label { color: var(--accent-execution); } |
| .phase-block.evaluation .phase-label { color: var(--accent-evaluation); } |
| |
| |
| .step-wrapper { |
| position: relative; |
| display: flex; |
| flex-direction: column; |
| } |
| |
| .step { |
| display: flex; |
| align-items: center; |
| gap: 16px; |
| background: var(--step-bg); |
| border-radius: var(--radius); |
| padding: 16px 18px; |
| cursor: pointer; |
| border: 1px solid rgba(255,255,255,0.06); |
| transition: background var(--transition), border-color var(--transition), transform var(--transition); |
| position: relative; |
| z-index: 1; |
| margin: 3px 0; |
| user-select: none; |
| } |
| |
| .step:hover { |
| background: var(--step-hover); |
| border-color: rgba(255,255,255,0.12); |
| transform: translateX(2px); |
| } |
| |
| .step.active { |
| border-color: var(--step-accent); |
| background: var(--step-bg); |
| box-shadow: 0 0 0 1px var(--step-accent), inset 0 0 20px rgba(0,0,0,0.2); |
| transform: translateX(3px); |
| } |
| |
| .step-number { |
| width: 34px; |
| height: 34px; |
| border-radius: 50%; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| font-size: 12px; |
| font-weight: 700; |
| font-family: var(--mono); |
| flex-shrink: 0; |
| border: 2px solid; |
| transition: all var(--transition); |
| } |
| |
| .step-icon { |
| font-size: 20px; |
| flex-shrink: 0; |
| width: 28px; |
| text-align: center; |
| filter: grayscale(0.2); |
| transition: filter var(--transition), transform var(--transition); |
| } |
| |
| .step:hover .step-icon, |
| .step.active .step-icon { |
| filter: none; |
| transform: scale(1.1); |
| } |
| |
| .step-content { |
| flex: 1; |
| min-width: 0; |
| } |
| |
| .step-title { |
| font-size: 14px; |
| font-weight: 600; |
| color: var(--text-primary); |
| margin-bottom: 2px; |
| } |
| |
| .step-desc { |
| font-size: 12px; |
| color: var(--text-secondary); |
| white-space: nowrap; |
| overflow: hidden; |
| text-overflow: ellipsis; |
| } |
| |
| .step-chevron { |
| color: var(--text-muted); |
| font-size: 14px; |
| flex-shrink: 0; |
| transition: transform var(--transition), color var(--transition); |
| } |
| |
| .step.active .step-chevron { |
| transform: rotate(180deg); |
| color: var(--step-accent); |
| } |
| |
| |
| .phase-block.setup .step { --step-accent: var(--accent-setup); } |
| .phase-block.execution .step { --step-accent: var(--accent-execution); } |
| .phase-block.evaluation .step { --step-accent: var(--accent-evaluation); } |
| |
| .phase-block.setup .step-number { color: var(--accent-setup); border-color: var(--accent-setup); } |
| .phase-block.execution .step-number { color: var(--accent-execution); border-color: var(--accent-execution); } |
| .phase-block.evaluation .step-number { color: var(--accent-evaluation); border-color: var(--accent-evaluation); } |
| |
| .step.active .step-number { |
| background: var(--step-accent); |
| color: #000; |
| } |
| |
| |
| .detail-panel { |
| overflow: hidden; |
| max-height: 0; |
| opacity: 0; |
| transition: max-height 0.35s cubic-bezier(0.4, 0, 0.2, 1), |
| opacity 0.25s ease, |
| margin 0.25s ease; |
| margin: 0 4px; |
| } |
| |
| .detail-panel.open { |
| max-height: 320px; |
| opacity: 1; |
| margin: 0 4px 4px; |
| } |
| |
| .detail-inner { |
| background: rgba(0,0,0,0.35); |
| border-radius: 8px; |
| padding: 16px 18px; |
| border-left: 3px solid var(--step-accent); |
| font-size: 13px; |
| color: var(--text-secondary); |
| } |
| |
| .detail-inner .code-block { |
| font-family: var(--mono); |
| font-size: 12px; |
| background: rgba(0,0,0,0.4); |
| border-radius: 6px; |
| padding: 10px 14px; |
| margin-top: 10px; |
| color: #7dd3fc; |
| overflow-x: auto; |
| white-space: pre; |
| line-height: 1.7; |
| border: 1px solid rgba(255,255,255,0.06); |
| } |
| |
| .detail-inner .code-block .kw { color: #c084fc; } |
| .detail-inner .code-block .fn { color: #38bdf8; } |
| .detail-inner .code-block .str { color: #86efac; } |
| .detail-inner .code-block .cm { color: #64748b; } |
| |
| |
| .phase-connector { |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| height: 28px; |
| color: var(--text-muted); |
| font-size: 18px; |
| opacity: 0.5; |
| position: relative; |
| } |
| |
| .phase-connector::before, |
| .phase-connector::after { |
| content: ''; |
| position: absolute; |
| left: 50%; |
| width: 1px; |
| background: linear-gradient(to bottom, transparent, var(--connector), transparent); |
| } |
| |
| .phase-connector::before { top: 0; height: 10px; } |
| .phase-connector::after { bottom: 0; height: 10px; } |
| |
| |
| .footer-note { |
| max-width: 780px; |
| margin: 32px auto 0; |
| padding: 0 16px; |
| } |
| |
| .footer-card { |
| background: var(--bg-card); |
| border: 1px solid rgba(255,255,255,0.08); |
| border-radius: 12px; |
| padding: 18px 22px; |
| display: flex; |
| align-items: flex-start; |
| gap: 14px; |
| } |
| |
| .footer-icon { |
| font-size: 22px; |
| flex-shrink: 0; |
| margin-top: 1px; |
| } |
| |
| .footer-text { |
| font-size: 13px; |
| color: var(--text-secondary); |
| } |
| |
| .footer-text strong { |
| color: var(--text-primary); |
| font-family: var(--mono); |
| } |
| |
| |
| .stats-bar { |
| max-width: 780px; |
| margin: 24px auto 0; |
| padding: 0 16px; |
| display: flex; |
| gap: 10px; |
| flex-wrap: wrap; |
| } |
| |
| .stat-pill { |
| flex: 1; |
| min-width: 120px; |
| background: var(--bg-card); |
| border: 1px solid rgba(255,255,255,0.07); |
| border-radius: var(--radius); |
| padding: 12px 16px; |
| text-align: center; |
| } |
| |
| .stat-value { |
| font-size: 22px; |
| font-weight: 700; |
| font-family: var(--mono); |
| margin-bottom: 2px; |
| } |
| |
| .stat-label { |
| font-size: 10px; |
| text-transform: uppercase; |
| letter-spacing: 0.1em; |
| color: var(--text-muted); |
| } |
| |
| .stat-pill:nth-child(1) .stat-value { color: var(--accent-setup); } |
| .stat-pill:nth-child(2) .stat-value { color: var(--accent-execution); } |
| .stat-pill:nth-child(3) .stat-value { color: var(--accent-evaluation); } |
| .stat-pill:nth-child(4) .stat-value { color: #f59e0b; } |
| |
| |
| @media (max-width: 500px) { |
| .step { padding: 14px; gap: 12px; } |
| .step-desc { display: none; } |
| .detail-inner .code-block { font-size: 11px; } |
| } |
| |
| |
| |
| |
| |
| |
| .versuch-section { |
| max-width: 960px; |
| margin: 36px auto 0; |
| padding: 0 16px; |
| } |
| |
| .versuch-section-title { |
| display: flex; |
| align-items: center; |
| gap: 12px; |
| margin-bottom: 20px; |
| } |
| |
| .versuch-section-title .section-badge { |
| font-size: 10px; |
| font-weight: 700; |
| letter-spacing: 0.14em; |
| text-transform: uppercase; |
| color: var(--accent-exp); |
| background: var(--accent-exp-dim); |
| border: 1px solid var(--accent-exp-border); |
| border-radius: 999px; |
| padding: 3px 12px; |
| } |
| |
| .versuch-section-title h2 { |
| font-size: clamp(18px, 3vw, 24px); |
| font-weight: 700; |
| color: var(--text-primary); |
| letter-spacing: -0.01em; |
| } |
| |
| |
| .exp-overview { |
| background: var(--bg-card); |
| border: 1px solid var(--accent-exp-border); |
| border-radius: 16px; |
| padding: 24px 28px; |
| margin-bottom: 24px; |
| position: relative; |
| overflow: hidden; |
| } |
| |
| .exp-overview::before { |
| content: ''; |
| position: absolute; |
| inset: 0; |
| background: radial-gradient(ellipse 70% 60% at 100% 0%, rgba(245,158,11,0.05) 0%, transparent 60%); |
| pointer-events: none; |
| } |
| |
| .exp-overview-header { |
| display: flex; |
| align-items: center; |
| gap: 14px; |
| margin-bottom: 18px; |
| } |
| |
| .exp-id-badge { |
| font-family: var(--mono); |
| font-size: 13px; |
| font-weight: 700; |
| color: #000; |
| background: var(--accent-exp); |
| border-radius: 6px; |
| padding: 4px 10px; |
| letter-spacing: 0.04em; |
| flex-shrink: 0; |
| } |
| |
| .exp-overview-header h3 { |
| font-size: 16px; |
| font-weight: 600; |
| color: var(--text-primary); |
| } |
| |
| .exp-hypothesis { |
| background: rgba(0,0,0,0.3); |
| border-left: 3px solid var(--accent-exp); |
| border-radius: 0 8px 8px 0; |
| padding: 14px 18px; |
| font-size: 14px; |
| color: var(--text-secondary); |
| margin-bottom: 20px; |
| font-style: italic; |
| line-height: 1.65; |
| } |
| |
| .exp-hypothesis strong { |
| color: var(--accent-exp); |
| font-style: normal; |
| } |
| |
| .exp-meta-grid { |
| display: grid; |
| grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); |
| gap: 12px; |
| } |
| |
| .exp-meta-item { |
| background: rgba(255,255,255,0.03); |
| border: 1px solid rgba(255,255,255,0.06); |
| border-radius: 8px; |
| padding: 12px 14px; |
| } |
| |
| .exp-meta-label { |
| font-size: 10px; |
| text-transform: uppercase; |
| letter-spacing: 0.1em; |
| color: var(--text-muted); |
| margin-bottom: 4px; |
| } |
| |
| .exp-meta-value { |
| font-size: 15px; |
| font-weight: 600; |
| font-family: var(--mono); |
| color: var(--accent-exp); |
| } |
| |
| .exp-meta-value.neutral { |
| color: var(--text-primary); |
| font-size: 13px; |
| } |
| |
| |
| .ab-section { |
| margin-bottom: 24px; |
| } |
| |
| .ab-section-heading { |
| font-size: 12px; |
| font-weight: 700; |
| text-transform: uppercase; |
| letter-spacing: 0.1em; |
| color: var(--accent-exp); |
| margin-bottom: 14px; |
| } |
| |
| .ab-layout { |
| display: grid; |
| grid-template-columns: 1fr auto 1fr; |
| gap: 16px; |
| align-items: center; |
| } |
| |
| .agent-card { |
| background: var(--bg-card); |
| border-radius: 14px; |
| padding: 20px; |
| border: 1px solid rgba(255,255,255,0.07); |
| position: relative; |
| } |
| |
| .agent-card.baseline { |
| border-color: rgba(148, 163, 184, 0.2); |
| } |
| |
| .agent-card.injected { |
| border-color: rgba(16, 185, 129, 0.3); |
| background: rgba(16, 185, 129, 0.04); |
| } |
| |
| .agent-card-label { |
| font-size: 11px; |
| font-weight: 700; |
| text-transform: uppercase; |
| letter-spacing: 0.1em; |
| margin-bottom: 14px; |
| display: flex; |
| align-items: center; |
| gap: 8px; |
| } |
| |
| .agent-card.baseline .agent-card-label { color: var(--accent-baseline); } |
| .agent-card.injected .agent-card-label { color: var(--accent-injected); } |
| |
| .agent-card-label .label-dot { |
| width: 7px; |
| height: 7px; |
| border-radius: 50%; |
| flex-shrink: 0; |
| } |
| |
| .agent-card.baseline .label-dot { background: var(--accent-baseline); } |
| .agent-card.injected .label-dot { background: var(--accent-injected); box-shadow: 0 0 6px var(--accent-injected); } |
| |
| .agent-field { |
| margin-bottom: 10px; |
| } |
| |
| .agent-field-key { |
| font-size: 10px; |
| color: var(--text-muted); |
| text-transform: uppercase; |
| letter-spacing: 0.08em; |
| margin-bottom: 3px; |
| font-family: var(--mono); |
| } |
| |
| .agent-field-val { |
| font-size: 12px; |
| color: var(--text-secondary); |
| font-family: var(--mono); |
| background: rgba(0,0,0,0.25); |
| border-radius: 6px; |
| padding: 7px 10px; |
| border: 1px solid rgba(255,255,255,0.05); |
| } |
| |
| .agent-field-val.none-val { |
| color: var(--text-muted); |
| font-style: italic; |
| } |
| |
| .agent-field-val.injection-val { |
| color: #86efac; |
| border-color: rgba(16,185,129,0.2); |
| background: rgba(16,185,129,0.06); |
| } |
| |
| .vs-badge { |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| width: 44px; |
| height: 44px; |
| background: rgba(245,158,11,0.12); |
| border: 2px solid var(--accent-exp-border); |
| border-radius: 50%; |
| font-size: 13px; |
| font-weight: 800; |
| color: var(--accent-exp); |
| font-family: var(--mono); |
| flex-shrink: 0; |
| } |
| |
| .ab-footer { |
| text-align: center; |
| margin-top: 12px; |
| font-size: 12px; |
| color: var(--text-muted); |
| } |
| |
| .ab-footer .highlight { |
| color: var(--accent-exp); |
| font-weight: 600; |
| } |
| |
| |
| .scenarios-section { |
| margin-bottom: 24px; |
| } |
| |
| .scenarios-heading { |
| font-size: 12px; |
| font-weight: 700; |
| text-transform: uppercase; |
| letter-spacing: 0.1em; |
| color: var(--accent-exp); |
| margin-bottom: 14px; |
| } |
| |
| .scenarios-grid { |
| display: grid; |
| grid-template-columns: repeat(2, 1fr); |
| gap: 14px; |
| } |
| |
| .scenario-card { |
| background: var(--bg-card); |
| border: 1px solid rgba(255,255,255,0.07); |
| border-radius: 14px; |
| padding: 18px; |
| cursor: pointer; |
| transition: border-color var(--transition), background var(--transition), transform var(--transition); |
| user-select: none; |
| } |
| |
| .scenario-card:hover { |
| border-color: var(--accent-exp-border); |
| background: rgba(245,158,11,0.03); |
| transform: translateY(-1px); |
| } |
| |
| .scenario-card.open { |
| border-color: var(--accent-exp-border); |
| background: rgba(245,158,11,0.04); |
| } |
| |
| .scenario-header { |
| display: flex; |
| align-items: flex-start; |
| gap: 12px; |
| margin-bottom: 10px; |
| } |
| |
| .scenario-id { |
| font-family: var(--mono); |
| font-size: 11px; |
| font-weight: 700; |
| color: #000; |
| background: var(--accent-exp); |
| border-radius: 5px; |
| padding: 2px 8px; |
| flex-shrink: 0; |
| margin-top: 1px; |
| } |
| |
| .scenario-title-block { |
| flex: 1; |
| } |
| |
| .scenario-title { |
| font-size: 14px; |
| font-weight: 600; |
| color: var(--text-primary); |
| margin-bottom: 3px; |
| } |
| |
| .scenario-task-name { |
| font-family: var(--mono); |
| font-size: 11px; |
| color: var(--text-muted); |
| } |
| |
| .scenario-chevron { |
| color: var(--text-muted); |
| font-size: 12px; |
| flex-shrink: 0; |
| transition: transform var(--transition), color var(--transition); |
| margin-top: 2px; |
| } |
| |
| .scenario-card.open .scenario-chevron { |
| transform: rotate(180deg); |
| color: var(--accent-exp); |
| } |
| |
| .scenario-bug { |
| font-size: 12px; |
| color: var(--text-secondary); |
| margin-bottom: 0; |
| line-height: 1.55; |
| } |
| |
| .scenario-injection-panel { |
| overflow: hidden; |
| max-height: 0; |
| opacity: 0; |
| transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.2s ease, margin 0.2s ease; |
| margin-top: 0; |
| } |
| |
| .scenario-injection-panel.open { |
| max-height: 120px; |
| opacity: 1; |
| margin-top: 12px; |
| } |
| |
| .injection-box { |
| background: rgba(16,185,129,0.07); |
| border: 1px solid rgba(16,185,129,0.22); |
| border-radius: 7px; |
| padding: 10px 13px; |
| font-size: 12px; |
| color: #86efac; |
| font-style: italic; |
| line-height: 1.55; |
| } |
| |
| .injection-box-label { |
| font-size: 9px; |
| text-transform: uppercase; |
| letter-spacing: 0.12em; |
| color: var(--accent-injected); |
| font-style: normal; |
| font-weight: 700; |
| margin-bottom: 5px; |
| opacity: 0.8; |
| } |
| |
| |
| .flow-section { |
| margin-bottom: 0; |
| } |
| |
| .flow-heading { |
| font-size: 12px; |
| font-weight: 700; |
| text-transform: uppercase; |
| letter-spacing: 0.1em; |
| color: var(--accent-exp); |
| margin-bottom: 14px; |
| } |
| |
| .flow-diagram { |
| background: var(--bg-card); |
| border: 1px solid rgba(255,255,255,0.07); |
| border-radius: 14px; |
| padding: 22px 24px; |
| font-family: var(--mono); |
| font-size: 12px; |
| color: var(--text-secondary); |
| line-height: 1.9; |
| overflow-x: auto; |
| } |
| |
| .flow-node { |
| display: inline-block; |
| background: rgba(255,255,255,0.05); |
| border: 1px solid rgba(255,255,255,0.09); |
| border-radius: 6px; |
| padding: 2px 10px; |
| color: var(--text-primary); |
| font-size: 12px; |
| } |
| |
| .flow-node.exp-start { |
| background: var(--accent-exp-dim); |
| border-color: var(--accent-exp-border); |
| color: var(--accent-exp); |
| font-weight: 700; |
| } |
| |
| .flow-node.compare { |
| background: rgba(59,130,246,0.1); |
| border-color: rgba(59,130,246,0.25); |
| color: #7dd3fc; |
| } |
| |
| .flow-node.verdict { |
| background: rgba(168,85,247,0.1); |
| border-color: rgba(168,85,247,0.25); |
| color: #c084fc; |
| } |
| |
| .flow-node.baseline-node { |
| background: rgba(148,163,184,0.08); |
| border-color: rgba(148,163,184,0.2); |
| color: var(--accent-baseline); |
| } |
| |
| .flow-node.inject-node { |
| background: rgba(16,185,129,0.08); |
| border-color: rgba(16,185,129,0.22); |
| color: var(--accent-injected); |
| } |
| |
| .flow-arrow { |
| color: var(--text-muted); |
| margin: 0 2px; |
| } |
| |
| .flow-indent { |
| padding-left: 24px; |
| } |
| |
| .flow-indent-2 { |
| padding-left: 44px; |
| } |
| |
| .flow-row { |
| display: flex; |
| align-items: center; |
| gap: 6px; |
| flex-wrap: wrap; |
| min-height: 1.9em; |
| } |
| |
| .flow-branch-label { |
| color: var(--text-muted); |
| font-size: 11px; |
| } |
| |
| |
| .pipeline-divider { |
| max-width: 960px; |
| margin: 40px auto 0; |
| padding: 0 16px; |
| } |
| |
| .divider-inner { |
| display: flex; |
| align-items: center; |
| gap: 16px; |
| } |
| |
| .divider-line { |
| flex: 1; |
| height: 1px; |
| background: linear-gradient(to right, transparent, rgba(245,158,11,0.3), rgba(255,255,255,0.08), transparent); |
| } |
| |
| .divider-label { |
| font-size: 11px; |
| font-weight: 600; |
| letter-spacing: 0.1em; |
| text-transform: uppercase; |
| color: var(--text-muted); |
| white-space: nowrap; |
| flex-shrink: 0; |
| } |
| |
| |
| @media (max-width: 680px) { |
| .ab-layout { |
| grid-template-columns: 1fr; |
| } |
| .vs-badge { |
| margin: 0 auto; |
| transform: rotate(90deg); |
| } |
| .scenarios-grid { |
| grid-template-columns: 1fr; |
| } |
| } |
| |
| @media (max-width: 500px) { |
| .exp-overview { padding: 18px; } |
| .flow-diagram { font-size: 11px; padding: 16px; } |
| } |
| </style> |
| </head> |
| <body> |
|
|
| <div class="header"> |
| <div class="header-badge"> |
| <span class="dot"></span> |
| AgentArena · Benchmark Engine |
| </div> |
| <h1><span>AgentArena</span> — E8 Experiment + Run Pipeline</h1> |
| <p class="subtitle">Versuchsaufbau, A/B-Design und die 11-Schritte-Pipeline eines einzelnen Runs.</p> |
| </div> |
|
|
| |
| |
| |
|
|
| <div class="versuch-section"> |
|
|
| <div class="versuch-section-title"> |
| <span class="section-badge">Versuchsaufbau</span> |
| <h2>E8 — Domain Knowledge Experiment</h2> |
| </div> |
|
|
| |
| <div class="exp-overview"> |
| <div class="exp-overview-header"> |
| <div class="exp-id-badge">E8</div> |
| <h3>Domain Knowledge — Baseline vs Injection</h3> |
| </div> |
| <div class="exp-hypothesis"> |
| <strong>Hypothese:</strong> Domain-Knowledge-Injection (ein Satz Projektkontext via Sidecar-NG) ermöglicht Agents, projektspezifische Bugs zu lösen, die sie ohne Kontext nicht lösen können. |
| </div> |
| <div class="exp-meta-grid"> |
| <div class="exp-meta-item"> |
| <div class="exp-meta-label">Design</div> |
| <div class="exp-meta-value">4 × 2 × 3</div> |
| </div> |
| <div class="exp-meta-item"> |
| <div class="exp-meta-label">Szenarien</div> |
| <div class="exp-meta-value">4</div> |
| </div> |
| <div class="exp-meta-item"> |
| <div class="exp-meta-label">Agents</div> |
| <div class="exp-meta-value">2</div> |
| </div> |
| <div class="exp-meta-item"> |
| <div class="exp-meta-label">Runs gesamt</div> |
| <div class="exp-meta-value">24</div> |
| </div> |
| <div class="exp-meta-item"> |
| <div class="exp-meta-label">Est. Cost</div> |
| <div class="exp-meta-value">~$1.50</div> |
| </div> |
| <div class="exp-meta-item"> |
| <div class="exp-meta-label">Model</div> |
| <div class="exp-meta-value neutral">claude-sonnet-4-6</div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="ab-section"> |
| <div class="ab-section-heading">A/B Design — Der einzige Unterschied</div> |
| <div class="ab-layout"> |
|
|
| |
| <div class="agent-card baseline"> |
| <div class="agent-card-label"> |
| <span class="label-dot"></span> |
| Baseline Agent |
| </div> |
| <div class="agent-field"> |
| <div class="agent-field-key">CLAUDE.md</div> |
| <div class="agent-field-val">Use tools to solve tasks. Be concise.</div> |
| </div> |
| <div class="agent-field"> |
| <div class="agent-field-key">additional_context</div> |
| <div class="agent-field-val none-val">none</div> |
| </div> |
| </div> |
|
|
| <div class="vs-badge">VS</div> |
|
|
| |
| <div class="agent-card injected"> |
| <div class="agent-card-label"> |
| <span class="label-dot"></span> |
| Injected Agent |
| </div> |
| <div class="agent-field"> |
| <div class="agent-field-key">CLAUDE.md</div> |
| <div class="agent-field-val">Use tools to solve tasks. Be concise.</div> |
| </div> |
| <div class="agent-field"> |
| <div class="agent-field-key">additional_context</div> |
| <div class="agent-field-val injection-val">Ein Satz Domain-Wissen (szenario-spezifisch)</div> |
| </div> |
| </div> |
|
|
| </div> |
| <div class="ab-footer"> |
| Der <span class="highlight">einzige Unterschied</span>: ein Satz Projektkontext in <code style="color:#86efac;font-family:var(--mono);font-size:11px">additional_context</code> |
| </div> |
| </div> |
|
|
| |
| <div class="scenarios-section"> |
| <div class="scenarios-heading">Die 4 Szenarien</div> |
| <div class="scenarios-grid"> |
|
|
| |
| <div class="scenario-card" onclick="toggleScenario(this, 'inj-a')"> |
| <div class="scenario-header"> |
| <div class="scenario-id">E8a</div> |
| <div class="scenario-title-block"> |
| <div class="scenario-title">Enum Convention</div> |
| <div class="scenario-task-name">enum-convention-bug</div> |
| </div> |
| <div class="scenario-chevron">▼</div> |
| </div> |
| <div class="scenario-bug"> |
| Agent verwendet lowercase Enum-Werte, aber das Projekt verlangt UPPERCASE. |
| </div> |
| <div class="scenario-injection-panel" id="inj-a"> |
| <div class="injection-box"> |
| <div class="injection-box-label">Injection</div> |
| "In diesem Projekt verwenden alle Enums UPPERCASE Werte (z.B. 'ACTIVE', 'INACTIVE')." |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="scenario-card" onclick="toggleScenario(this, 'inj-b')"> |
| <div class="scenario-header"> |
| <div class="scenario-id">E8b</div> |
| <div class="scenario-title-block"> |
| <div class="scenario-title">Timeout Units</div> |
| <div class="scenario-task-name">timeout-unit-bug</div> |
| </div> |
| <div class="scenario-chevron">▼</div> |
| </div> |
| <div class="scenario-bug"> |
| Agent übergibt Sekunden für Timeout, aber die API verwendet Millisekunden. |
| </div> |
| <div class="scenario-injection-panel" id="inj-b"> |
| <div class="injection-box"> |
| <div class="injection-box-label">Injection</div> |
| "Die API-Client-Klasse verwendet Millisekunden für alle Timeout-Werte (timeout_ms), nicht Sekunden." |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="scenario-card" onclick="toggleScenario(this, 'inj-c')"> |
| <div class="scenario-header"> |
| <div class="scenario-id">E8c</div> |
| <div class="scenario-title-block"> |
| <div class="scenario-title">Breaking Change</div> |
| <div class="scenario-task-name">breaking-change-bug</div> |
| </div> |
| <div class="scenario-chevron">▼</div> |
| </div> |
| <div class="scenario-bug"> |
| Agent ruft <code style="color:#7dd3fc;font-size:11px">find_one()</code> auf, das in V2 zu <code style="color:#7dd3fc;font-size:11px">get_by_id()</code> umbenannt wurde. |
| </div> |
| <div class="scenario-injection-panel" id="inj-c"> |
| <div class="injection-box"> |
| <div class="injection-box-label">Injection</div> |
| "database.py wurde auf V2 migriert: find_one() heißt jetzt get_by_id()." |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="scenario-card" onclick="toggleScenario(this, 'inj-d')"> |
| <div class="scenario-header"> |
| <div class="scenario-id">E8d</div> |
| <div class="scenario-title-block"> |
| <div class="scenario-title">Implicit Null</div> |
| <div class="scenario-task-name">implicit-null-bug</div> |
| </div> |
| <div class="scenario-chevron">▼</div> |
| </div> |
| <div class="scenario-bug"> |
| Agent übergibt <code style="color:#7dd3fc;font-size:11px">None</code> für email, aber die DB hat einen NOT NULL Constraint. |
| </div> |
| <div class="scenario-injection-panel" id="inj-d"> |
| <div class="injection-box"> |
| <div class="injection-box-label">Injection</div> |
| "Das DB-Schema (schema.sql) hat NOT NULL Constraints auf email." |
| </div> |
| </div> |
| </div> |
|
|
| </div> |
| </div> |
|
|
| |
| <div class="flow-section"> |
| <div class="flow-heading">Ablauf des Experiments</div> |
| <div class="flow-diagram"> |
|
|
| <div class="flow-row"> |
| <span class="flow-node exp-start">Experiment Start</span> |
| </div> |
| <div class="flow-row flow-indent"> |
| <span class="flow-arrow">↓</span> |
| </div> |
| <div class="flow-row"> |
| <span style="color:var(--text-muted)">For each Scenario (</span> |
| <span class="flow-node">E8a</span> |
| <span class="flow-arrow">→</span> |
| <span class="flow-node">E8b</span> |
| <span class="flow-arrow">→</span> |
| <span class="flow-node">E8c</span> |
| <span class="flow-arrow">→</span> |
| <span class="flow-node">E8d</span> |
| <span style="color:var(--text-muted)">):</span> |
| </div> |
| <div class="flow-row flow-indent"> |
| <span style="color:var(--text-muted)">├──</span> |
| <span class="flow-node baseline-node">Baseline Agent</span> |
| <span style="color:var(--text-muted)">× 3 Runs (pass@3)</span> |
| <span class="flow-arrow">──→</span> |
| <span style="color:var(--text-muted)">[Run Pipeline × 3]</span> |
| </div> |
| <div class="flow-row flow-indent"> |
| <span style="color:var(--text-muted)">└──</span> |
| <span class="flow-node inject-node">Injected Agent</span> |
| <span style="color:var(--text-muted)">× 3 Runs (pass@3)</span> |
| <span class="flow-arrow">──→</span> |
| <span style="color:var(--text-muted)">[Run Pipeline × 3]</span> |
| </div> |
| <div class="flow-row flow-indent"> |
| <span class="flow-arrow">↓</span> |
| </div> |
| <div class="flow-row"> |
| <span class="flow-node compare">Compare: baseline pass@3 vs injected pass@3</span> |
| </div> |
| <div class="flow-row flow-indent"> |
| <span class="flow-arrow">↓</span> |
| </div> |
| <div class="flow-row"> |
| <span class="flow-node verdict">Verdict: Injection wirkt?</span> |
| <span style="color:var(--text-muted);font-size:11px"> (0→3 = stark · 3→3 = Task zu einfach)</span> |
| </div> |
|
|
| </div> |
| </div> |
|
|
| </div> |
|
|
| |
| |
| |
|
|
| <div class="pipeline-divider"> |
| <div class="divider-inner"> |
| <div class="divider-line"></div> |
| <div class="divider-label">Jeder einzelne Run durchläuft diese Pipeline</div> |
| <div class="divider-line"></div> |
| </div> |
| </div> |
|
|
| |
| |
| |
|
|
| <div class="stats-bar"> |
| <div class="stat-pill"> |
| <div class="stat-value">3</div> |
| <div class="stat-label">Phasen</div> |
| </div> |
| <div class="stat-pill"> |
| <div class="stat-value">11</div> |
| <div class="stat-label">Schritte</div> |
| </div> |
| <div class="stat-pill"> |
| <div class="stat-value">2</div> |
| <div class="stat-label">Sandboxes</div> |
| </div> |
| <div class="stat-pill"> |
| <div class="stat-value">k×</div> |
| <div class="stat-label">pass@k parallel</div> |
| </div> |
| </div> |
|
|
| <div class="legend"> |
| <div class="legend-item setup"> |
| <div class="legend-dot"></div> |
| Setup — Schritte 1–3 |
| </div> |
| <div class="legend-item exec"> |
| <div class="legend-dot"></div> |
| Execution — Schritte 4–6 |
| </div> |
| <div class="legend-item eval"> |
| <div class="legend-dot"></div> |
| Evaluation — Schritte 7–11 |
| </div> |
| </div> |
|
|
| <div class="pipeline-wrapper" id="pipeline"> |
|
|
| |
| <div class="phase-block setup"> |
| <div class="phase-label">Phase 1 · Setup</div> |
|
|
| <div class="step-wrapper"> |
| <div class="step" onclick="toggle(this, 1)"> |
| <div class="step-number">01</div> |
| <div class="step-icon">🗄️</div> |
| <div class="step-content"> |
| <div class="step-title">DB-Eintrag erstellen</div> |
| <div class="step-desc">Run-Record mit Status "running" in SQLite anlegen</div> |
| </div> |
| <div class="step-chevron">▼</div> |
| </div> |
| <div class="detail-panel" id="detail-1"> |
| <div class="detail-inner"> |
| Run-Record wird sofort angelegt, bevor irgendeine Sandbox existiert. |
| Status <code style="color:#86efac">running</code> blockiert parallele Runs auf demselben Task/Agent-Paar. |
| <div class="code-block"><span class="fn">Run</span>(<span class="str">task_id</span>=task.id, <span class="str">agent_id</span>=agent.id, |
| <span class="str">status</span>=<span class="str">"running"</span>, <span class="str">created_at</span>=<span class="fn">now</span>()) |
| <span class="cm"># → run.id für alle weiteren DB-Updates</span></div> |
| </div> |
| </div> |
| </div> |
|
|
| <div class="step-wrapper"> |
| <div class="step" onclick="toggle(this, 2)"> |
| <div class="step-number">02</div> |
| <div class="step-icon">📦</div> |
| <div class="step-content"> |
| <div class="step-title">Sandbox erstellen</div> |
| <div class="step-desc">Docker-Container mit dem Task-Repo geklont</div> |
| </div> |
| <div class="step-chevron">▼</div> |
| </div> |
| <div class="detail-panel" id="detail-2"> |
| <div class="detail-inner"> |
| Jeder Run bekommt einen isolierten Docker-Container. Das Task-Repo wird auf den spezifizierten Ref geklont. |
| Der Agent sieht exakt den Zustand, den der Task definiert. |
| <div class="code-block"><span class="fn">Sandbox</span>.<span class="fn">create</span>(task) |
| <span class="cm">↳</span> docker run --rm -it --network=none <image> |
| <span class="cm">↳</span> git clone <repo_url> --branch <ref> /workspace</div> |
| </div> |
| </div> |
| </div> |
|
|
| <div class="step-wrapper"> |
| <div class="step" onclick="toggle(this, 3)"> |
| <div class="step-number">03</div> |
| <div class="step-icon">🔌</div> |
| <div class="step-content"> |
| <div class="step-title">Adapter holen</div> |
| <div class="step-desc">claude_code Adapter mit Model + CLAUDE.md + optional additional_context</div> |
| </div> |
| <div class="step-chevron">▼</div> |
| </div> |
| <div class="detail-panel" id="detail-3"> |
| <div class="detail-inner"> |
| Der Adapter abstrahiert das Modell. Jede Konfiguration (Modell, Prompt-Mode, CLAUDE.md, Injections) |
| steckt im Adapter — der Runner ist modell-agnostisch. |
| <div class="code-block"><span class="fn">get_adapter</span>(<span class="str">"claude_code"</span>, config) |
| <span class="cm">→</span> Adapter( |
| model=<span class="str">"claude-sonnet-4-5"</span>, |
| prompt_mode=<span class="str">"architect"</span>, |
| claude_md=<span class="str">"/path/CLAUDE.md"</span>, |
| additional_context=<span class="kw">Optional</span>[str] |
| )</div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="phase-connector">↓</div> |
|
|
| |
| <div class="phase-block execution"> |
| <div class="phase-label">Phase 2 · Execution</div> |
|
|
| <div class="step-wrapper"> |
| <div class="step" onclick="toggle(this, 4)"> |
| <div class="step-number">04</div> |
| <div class="step-icon">🤖</div> |
| <div class="step-content"> |
| <div class="step-title">Agent laufen lassen</div> |
| <div class="step-desc">Claude Sonnet bekommt den Task-Prompt und arbeitet in der Sandbox</div> |
| </div> |
| <div class="step-chevron">▼</div> |
| </div> |
| <div class="detail-panel" id="detail-4"> |
| <div class="detail-inner"> |
| Der kritischste Schritt. Der Agent kann Dateien lesen, editieren, Tests ausführen. |
| Die Trajectory (alle Tool-Calls + Outputs) wird vollständig aufgezeichnet. |
| <div class="code-block"><span class="fn">adapter</span>.<span class="fn">run</span>(ctx, sandbox) |
| <span class="cm">→</span> RunResult( |
| diff_text=<span class="str">"..."</span>, <span class="cm"># was wurde geändert</span> |
| tokens=<span class="str">12450</span>, <span class="cm"># input + output</span> |
| cost_usd=<span class="str">0.043</span>, <span class="cm"># API-Kosten</span> |
| trajectory=[...] <span class="cm"># Tool-Calls + Outputs</span> |
| )</div> |
| </div> |
| </div> |
| </div> |
|
|
| <div class="step-wrapper"> |
| <div class="step" onclick="toggle(this, 5)"> |
| <div class="step-number">05</div> |
| <div class="step-icon">📋</div> |
| <div class="step-content"> |
| <div class="step-title">Diff einsammeln</div> |
| <div class="step-desc">Was hat der Agent geändert?</div> |
| </div> |
| <div class="step-chevron">▼</div> |
| </div> |
| <div class="detail-panel" id="detail-5"> |
| <div class="detail-inner"> |
| Der Diff ist das einzige, was vom Agent-Container in die Judge-Phase übertragen wird. |
| Kein shared state, kein shared filesystem — nur der Patch. |
| <div class="code-block">sandbox.<span class="fn">get_diff</span>() |
| <span class="cm"># oder</span> adapter_result.diff_text |
|
|
| <span class="cm">→</span> <span class="str">"""diff --git a/solution.py b/solution.py |
| @@ -12,3 +12,8 @@ def solve(): |
| + result = compute(data) |
| + return result |
| """</span></div> |
| </div> |
| </div> |
| </div> |
|
|
| <div class="step-wrapper"> |
| <div class="step" onclick="toggle(this, 6)"> |
| <div class="step-number">06</div> |
| <div class="step-icon">🗑️</div> |
| <div class="step-content"> |
| <div class="step-title">Agent-Container zerstören</div> |
| <div class="step-desc">Isolation: Judge darf nicht im selben Container laufen</div> |
| </div> |
| <div class="step-chevron">▼</div> |
| </div> |
| <div class="detail-panel" id="detail-6"> |
| <div class="detail-inner"> |
| Sicherheits- und Integritäts-kritisch: Der Judge muss auf einem sauberen Zustand evaluieren, |
| nicht auf dem möglicherweise beschädigten Workspace des Agents. |
| <div class="code-block">sandbox.<span class="fn">destroy</span>() |
| <span class="cm"># docker rm -f <container_id></span> |
|
|
| <span class="cm">⚠ Critical: judge must evaluate on clean state,</span> |
| <span class="cm"> not agent's messy workspace</span></div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="phase-connector">↓</div> |
|
|
| |
| <div class="phase-block evaluation"> |
| <div class="phase-label">Phase 3 · Evaluation</div> |
|
|
| <div class="step-wrapper"> |
| <div class="step" onclick="toggle(this, 7)"> |
| <div class="step-number">07</div> |
| <div class="step-icon">🧪</div> |
| <div class="step-content"> |
| <div class="step-title">Judge-Sandbox erstellen</div> |
| <div class="step-desc">Frischer Clone + Patch anwenden</div> |
| </div> |
| <div class="step-chevron">▼</div> |
| </div> |
| <div class="detail-panel" id="detail-7"> |
| <div class="detail-inner"> |
| Neuer Container, frischer Clone. Nur der Diff des Agents wird per <code style="color:#86efac">git apply</code> |
| eingespielt. Der Judge sieht exakt dasselbe, was ein Human Code Reviewer sehen würde. |
| <div class="code-block"><span class="fn">Sandbox</span>.<span class="fn">create_judge_sandbox</span>(task, diff_text) |
| <span class="cm">↳</span> docker run --rm -it <image> |
| <span class="cm">↳</span> git clone <repo_url> --branch <ref> /workspace |
| <span class="cm">↳</span> git apply <<< <span class="str">"$diff_text"</span></div> |
| </div> |
| </div> |
| </div> |
|
|
| <div class="step-wrapper"> |
| <div class="step" onclick="toggle(this, 8)"> |
| <div class="step-number">08</div> |
| <div class="step-icon">⚖️</div> |
| <div class="step-content"> |
| <div class="step-title">Judge bewerten</div> |
| <div class="step-desc">success_cmd ausführen (typisch: pytest), plus Lint, Regression, Complexity</div> |
| </div> |
| <div class="step-chevron">▼</div> |
| </div> |
| <div class="detail-panel" id="detail-8"> |
| <div class="detail-inner"> |
| Der Judge ist multi-dimensional: funktionale Korrektheit ist primär, aber Lint-Delta, |
| Regressions und Complexity gehen in den Composite Score ein. |
| <div class="code-block">judge.<span class="fn">judge_run</span>(sandbox, success_cmd) |
| <span class="cm">→</span> JudgeResult( |
| tests_passed=<span class="str">8</span>, tests_total=<span class="str">10</span>, |
| regressions=[...], <span class="cm"># vorher grüne Tests die jetzt rot sind</span> |
| lint_delta=<span class="str">-2</span>, <span class="cm"># verbessert (-) oder verschlechtert (+)</span> |
| complexity_delta=<span class="str">+1</span>, <span class="cm"># zyklomatische Komplexität</span> |
| )</div> |
| </div> |
| </div> |
| </div> |
|
|
| <div class="step-wrapper"> |
| <div class="step" onclick="toggle(this, 9)"> |
| <div class="step-number">09</div> |
| <div class="step-icon">📊</div> |
| <div class="step-content"> |
| <div class="step-title">Metrics berechnen</div> |
| <div class="step-desc">Composite Score aus functionality + trajectory + efficiency + diff</div> |
| </div> |
| <div class="step-chevron">▼</div> |
| </div> |
| <div class="detail-panel" id="detail-9"> |
| <div class="detail-inner"> |
| Der Composite Score verdichtet mehrere Dimensionen in einen vergleichbaren Score [0.0–1.0]. |
| Funktionale Korrektheit dominiert; Effizienz und Direktheit differenzieren bei Gleichstand. |
| <div class="code-block"><span class="fn">compute_composite_score</span>() |
| <span class="cm">Weights:</span> |
| functionality <span class="str">0.45</span> <span class="cm"># tests_passed / tests_total</span> |
| directness <span class="str">0.15</span> <span class="cm"># kein Overshooting, sauberer Diff</span> |
| efficiency <span class="str">0.15</span> <span class="cm"># cost_usd normalisiert</span> |
| self_correction <span class="str">0.10</span> <span class="cm"># Retry-Loops im Trajectory</span> |
| churn <span class="str">0.10</span> <span class="cm"># revert-and-redo Patterns</span> |
| loops <span class="str">0.05</span> <span class="cm"># zyklische Tool-Calls</span></div> |
| </div> |
| </div> |
| </div> |
|
|
| <div class="step-wrapper"> |
| <div class="step" onclick="toggle(this, 10)"> |
| <div class="step-number">10</div> |
| <div class="step-icon">💾</div> |
| <div class="step-content"> |
| <div class="step-title">DB updaten</div> |
| <div class="step-desc">Alles speichern: Status, Tokens, Score, Trajectory</div> |
| </div> |
| <div class="step-chevron">▼</div> |
| </div> |
| <div class="detail-panel" id="detail-10"> |
| <div class="detail-inner"> |
| Atomarer Write: alle Felder in einem Update. Falls dieser Schritt schreitert, |
| bleibt der Run auf <code style="color:#fbbf24">status=error</code> — kein Partial-Write. |
| <div class="code-block">run.<span class="fn">update</span>( |
| status=<span class="str">"completed"</span>, |
| duration_s=<span class="str">47.3</span>, |
| tokens=<span class="str">12450</span>, cost_usd=<span class="str">0.043</span>, |
| tests_passed=<span class="str">8</span>, tests_total=<span class="str">10</span>, |
| tool_calls=<span class="str">23</span>, |
| diff_text=<span class="str">"..."</span>, trajectory=<span class="str">[...]</span>, |
| judge_score=<span class="str">0.84</span>, |
| metrics_json=<span class="str">{...}</span> |
| )</div> |
| </div> |
| </div> |
| </div> |
|
|
| <div class="step-wrapper"> |
| <div class="step" onclick="toggle(this, 11)"> |
| <div class="step-number">11</div> |
| <div class="step-icon">🧹</div> |
| <div class="step-content"> |
| <div class="step-title">Aufräumen</div> |
| <div class="step-desc">Judge-Container zerstören — immer, auch bei Fehler</div> |
| </div> |
| <div class="step-chevron">▼</div> |
| </div> |
| <div class="detail-panel" id="detail-11"> |
| <div class="detail-inner"> |
| Der Cleanup läuft im <code style="color:#c084fc">finally</code>-Block — er wird garantiert ausgeführt, |
| egal ob die Pipeline erfolgreich war oder mit Exception abgebrochen hat. |
| Kein Container-Leak auch bei Crashes. |
| <div class="code-block"><span class="kw">finally</span>: |
| judge_sandbox.<span class="fn">destroy</span>() |
| <span class="cm"># docker rm -f <judge_container_id></span> |
| <span class="cm"># Always runs — no container leak on error</span></div> |
| </div> |
| </div> |
| </div> |
|
|
| </div> |
| </div> |
|
|
| |
| <div class="footer-note"> |
| <div class="footer-card"> |
| <div class="footer-icon">⚡</div> |
| <div class="footer-text"> |
| <strong>pass@k</strong>: Diese Pipeline läuft <strong>k-mal parallel</strong> |
| (<strong>asyncio.gather</strong>) pro Agent — jeder Run bekommt seine eigene isolierte Sandbox. |
| k=1 für Determinismus-Tests, k=5–10 für statistische Robustheit. Der pass@k-Score |
| gibt an, wie oft der Agent in k Versuchen mindestens einmal erfolgreich ist. |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| const activeSteps = {}; |
| |
| function toggle(stepEl, id) { |
| const panel = document.getElementById('detail-' + id); |
| const isOpen = panel.classList.contains('open'); |
| |
| if (isOpen) { |
| panel.classList.remove('open'); |
| stepEl.classList.remove('active'); |
| delete activeSteps[id]; |
| } else { |
| panel.classList.add('open'); |
| stepEl.classList.add('active'); |
| activeSteps[id] = true; |
| } |
| } |
| |
| function toggleScenario(cardEl, panelId) { |
| const panel = document.getElementById(panelId); |
| const isOpen = panel.classList.contains('open'); |
| |
| if (isOpen) { |
| panel.classList.remove('open'); |
| cardEl.classList.remove('open'); |
| } else { |
| panel.classList.add('open'); |
| cardEl.classList.add('open'); |
| } |
| } |
| |
| |
| document.querySelectorAll('.step').forEach((step, i) => { |
| step.setAttribute('tabindex', '0'); |
| step.addEventListener('keydown', (e) => { |
| if (e.key === 'Enter' || e.key === ' ') { |
| e.preventDefault(); |
| step.click(); |
| } |
| }); |
| }); |
| |
| |
| document.querySelectorAll('.scenario-card').forEach((card) => { |
| card.setAttribute('tabindex', '0'); |
| card.addEventListener('keydown', (e) => { |
| if (e.key === 'Enter' || e.key === ' ') { |
| e.preventDefault(); |
| card.click(); |
| } |
| }); |
| }); |
| </script> |
| </body> |
| </html> |
|
|