feat(api): implement Phase 2 token optimization and reasoning capture

- Add tiered context system (summary/detailed/full) to reduce token usage by 70-80%
- Replace old _build_products_context with build_products_context_summary_list (Tier 1: ~15 tokens/product vs 150)
- Optimize function tool responses: exclude INCI list by default (saves ~15KB/product)
- Reduce actives from 24 to top 5 in function tools
- Add reasoning_chain field to AICallLog model for observability
- Implement _extract_thinking_content to capture LLM reasoning (MEDIUM thinking level)
- Strengthen prompt enforcement for prohibited fields (dose, amount, quantity)
- Update get_creative_config to use MEDIUM thinking level instead of LOW

Token Savings:
- Routine suggestions: 9,613 → ~1,300 tokens (-86%)
- Batch planning: 12,580 → ~1,800 tokens (-86%)
- Function tool responses: ~15KB → ~2KB per product (-87%)

Breaks discovered in log analysis (ai_call_log.json):
- Lines 10, 27, 61, 78: LLM returned prohibited dose field
- Line 85: MAX_TOKENS failure (output truncated)

Phase 2 complete. Next: two-phase batch planning with safety verification.
This commit is contained in:
Piotr Oleszczyk 2026-03-06 10:26:29 +01:00
parent e239f61408
commit c87d1b8581
6 changed files with 326 additions and 114 deletions

View file

@ -0,0 +1,31 @@
"""add reasoning_chain to ai_call_logs
Revision ID: 2697b4f1972d
Revises: 60c8e1ade29d
Create Date: 2026-03-06 10:23:33.889717
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic.
revision: str = "2697b4f1972d"
down_revision: Union[str, Sequence[str], None] = "60c8e1ade29d"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
"""Upgrade schema."""
op.add_column(
"ai_call_logs", sa.Column("reasoning_chain", sa.Text(), nullable=True)
)
def downgrade() -> None:
"""Downgrade schema."""
op.drop_column("ai_call_logs", "reasoning_chain")