771 lines
33 KiB
Markdown
771 lines
33 KiB
Markdown
# DIDI Platform - Audit Complet: Prompt-uri, Separare Lingvistica, Parametri
|
|
|
|
**Data audit**: 2026-03-23
|
|
**Scope**: Toate prompt-urile LLM din agent-v3, fluxul de date Framework->Redis->Executor, separare lingvistica RO/EN, parametri injectati, formate raspuns, probleme gasite.
|
|
|
|
---
|
|
|
|
## CUPRINS
|
|
|
|
1. [Arhitectura generala prompt-uri](#1-arhitectura-generala)
|
|
2. [Inventar complet prompt-uri](#2-inventar-complet)
|
|
3. [Techniques - Screening + Deep Analysis](#3-techniques)
|
|
4. [AI-Tampered - Disclosure + Screening + Deep + Image](#4-ai-tampered)
|
|
5. [Claims - Extraction + Verification](#5-claims)
|
|
6. [Source Assessment - Extraction + Evaluation](#6-source-assessment)
|
|
7. [Verdict - Calculator + Explanation + Virality](#7-verdict)
|
|
8. [Vision + Transcription (media pipeline)](#8-media-pipeline)
|
|
9. [Fluxul PG -> Redis -> Executor](#9-flux-pg-redis)
|
|
10. [Audit Separare Lingvistica](#10-separare-lingvistica)
|
|
11. [Probleme Gasite (32 issues)](#11-probleme)
|
|
12. [Recomandari](#12-recomandari)
|
|
|
|
---
|
|
|
|
## 1. ARHITECTURA GENERALA
|
|
|
|
### Cum ajung prompt-urile la LLM
|
|
|
|
```
|
|
Admin Dashboard (UI)
|
|
|
|
|
v
|
|
didiFramework PUT /api/providers/prompts/:id
|
|
|
|
|
v
|
|
PostgreSQL: bos_parammgmt.component_prompt
|
|
| (component_code, stage_code, system_prompt, user_template)
|
|
|
|
|
v
|
|
POST /api/sync-redis (manual trigger)
|
|
|
|
|
v
|
|
Redis: didi:config:{component}:{version}:prompts:{stage}
|
|
| JSON: { "system": "...", "user_template": "..." }
|
|
|
|
|
v
|
|
agent-v3 Executor: loadFromRedis() / loadConfig() / loadPrompt()
|
|
|
|
|
v
|
|
Template variable replacement: {{text}}, {{dimensions_list}}, etc.
|
|
|
|
|
v
|
|
wrapUserContent() - securitate anti-injection
|
|
|
|
|
v
|
|
LLM API call (model cascade: primary -> fallback_1 -> fallback_2 -> fallback_3)
|
|
|
|
|
v
|
|
JSON parse + Zod schema validation
|
|
```
|
|
|
|
### Trei tipuri de prompt-uri
|
|
|
|
| Tip | Descriere | Editabil din UI? | Exemple |
|
|
|-----|-----------|------------------|---------|
|
|
| **Redis-only** | Incarcat din Redis, FARA fallback hardcodat | Da | Techniques screening/deep, AI-Tampered screening/deep, Claims extraction/verification |
|
|
| **Redis + Fallback** | Redis override cu default hardcodat in cod | Da | Source Assessment extraction/evaluation, Vision prompts, Verdict explanation |
|
|
| **Hardcodat** | Fix in cod, nu poate fi modificat din UI | Nu | AI Image detection, Disclosure patterns (regex), Virality calculator |
|
|
|
|
---
|
|
|
|
## 2. INVENTAR COMPLET PROMPT-URI
|
|
|
|
### 15 prompt-uri LLM identificate
|
|
|
|
| # | Componenta | Etapa | Redis Key | Fallback? | Limba | Fisier |
|
|
|---|-----------|-------|-----------|-----------|-------|--------|
|
|
| 1 | Techniques | Screening | `didi:config:techniques:v3:prompts:screening` | NU | EN (Redis) | executor.ts:322 |
|
|
| 2 | Techniques | Deep Analysis | `didi:config:techniques:v3:prompts:deep_analysis` | NU | EN (Redis) | executor.ts:380 |
|
|
| 3 | AI-Tampered | Screening | `didi:config:ai-tampered:v1:prompts:screening` | NU | EN (Redis) | executor.ts:519 |
|
|
| 4 | AI-Tampered | Deep Analysis | `didi:config:ai-tampered:v1:prompts:deep_analysis` | NU | EN (Redis) | executor.ts:579 |
|
|
| 5 | AI-Tampered | Image Detection | N/A (hardcodat) | N/A | EN | ai-tampered-routes.ts:634 |
|
|
| 6 | Claims | Extraction | `didi:config:claims:v1:prompts:extraction` | NU | EN (Redis) | executor.ts:358 |
|
|
| 7 | Claims | Verification | `didi:config:claims:v1:prompts:verification` | NU | EN (Redis) | executor.ts:406 |
|
|
| 8 | Source Assess. | Extraction | `didi:config:source-assessment:v1:prompts:extraction` | DA | EN | executor.ts:124-154 |
|
|
| 9 | Source Assess. | Evaluation | `didi:config:source-assessment:v1:prompts:evaluation` | DA | EN | executor.ts:156-209 |
|
|
| 10 | Verdict | Explanation | `didi:config:pipeline:v1:prompts:verdict_explanation` | DA | EN prompt, RO+EN output | verdict-explanation.ts:88-131 |
|
|
| 11 | Vision | Text Extraction | `didi:config:vision:v1:prompts:extraction` | DA | EN | pipeline-routes.ts:103 |
|
|
| 12 | Vision | Video Frames | `didi:config:vision:v1:prompts:video_frames` | DA | EN | video-processor.ts |
|
|
| 13 | Vision | AI Detection (video) | `didi:config:vision:v1:prompts:ai_detection` | DA | EN | video-processor.ts |
|
|
| 14 | AI-Tampered | Disclosure Check | N/A (regex) | N/A | EN | executor.ts:190-231 |
|
|
| 15 | Verdict | Virality Calc | N/A (algoritm) | N/A | N/A | virality-calculator.ts |
|
|
|
|
### 3 prompt-uri NON-LLM (regex/algoritm)
|
|
|
|
| # | Ce face | Tip | Configurabil? |
|
|
|---|---------|-----|---------------|
|
|
| 14 | Disclosure detection (ChatGPT, Claude, etc.) | Regex patterns | NU (hardcodat) |
|
|
| 15 | Virality score (emotie, urgenta, reach) | Algoritm numeric | NU |
|
|
| - | Domain analysis (varsta, SSL, blacklist) | API extern + scoring | Partial (Redis) |
|
|
|
|
---
|
|
|
|
## 3. TECHNIQUES
|
|
|
|
### 3.1 Screening (Etapa 1)
|
|
|
|
**Scop**: Detectie rapida a dimensiunilor de manipulare prezente in text.
|
|
|
|
**Redis Key**: `didi:config:techniques:v3:prompts:screening`
|
|
|
|
**Variabile injectate**:
|
|
- `{{dimensions_list}}` - Lista celor 8 dimensiuni, format: `- D1: Emotional Manipulation - short_description`
|
|
- `{{text}}` - Primele 3000 caractere, wrappate in `<analyzed_content>...</analyzed_content>`
|
|
|
|
**Sursa dimensiuni**: `didi:framework:dimensions_compact` sau `didi:config:techniques:v3:dimensions_compact`
|
|
|
|
**Format raspuns asteptat** (Zod validated):
|
|
```json
|
|
{
|
|
"detected_dimensions": ["D1", "D3"],
|
|
"confidence_per_dimension": { "D1": 85, "D3": 72 },
|
|
"quick_reasoning": "Text shows emotional appeals and logical fallacies"
|
|
}
|
|
```
|
|
|
|
**Early exit**: Daca 0 dimensiuni detectate, se opreste (nu ruleaza deep analysis).
|
|
|
|
### 3.2 Deep Analysis (Etapa 2)
|
|
|
|
**Scop**: Per dimensiune detectata, identifica tehnicile specifice de manipulare.
|
|
|
|
**Redis Key**: `didi:config:techniques:v3:prompts:deep_analysis`
|
|
|
|
**Variabile injectate**:
|
|
- `{{dimension_name}}` - ex: "Emotional Manipulation"
|
|
- `{{dimension_code}}` - ex: "D1" (replaced global)
|
|
- `{{techniques_list}}` - Ierarhie completa: subdimensiuni -> tehnici -> indicatori, format markdown
|
|
- `{{text}}` - Primele 12000 caractere, wrappate in `<analyzed_content>`
|
|
|
|
**Format raspuns asteptat** (Zod validated):
|
|
```json
|
|
{
|
|
"detected_techniques": [
|
|
{
|
|
"technique_id": 12,
|
|
"technique_name": "Appeal to Authority",
|
|
"confidence": 82,
|
|
"intensity": 7,
|
|
"evidence": "Uses unnamed experts to claim credibility"
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
**Paralelizare**: Cate un call LLM per dimensiune detectata, toate in paralel.
|
|
|
|
### 3.3 Model Cascade
|
|
Configurat in Redis `didi:config:techniques:v3:stage_assignments`:
|
|
- Primary + 3 fallbacks per etapa
|
|
- Fiecare model are: temperature, max_tokens, timeout_ms
|
|
|
|
### 3.4 Scoring (post-LLM)
|
|
Din Redis `didi:config:techniques:v3:scoring_config`:
|
|
- count_scaler, intensity_weight, severe_threshold
|
|
- manipulation_score = f(tehnici detectate, intensitate, severitate)
|
|
|
|
---
|
|
|
|
## 4. AI-TAMPERED
|
|
|
|
### 4.1 Disclosure Check (Etapa 0 - fara LLM)
|
|
|
|
**Tip**: Regex pattern matching, hardcodat in executor.ts:190-231
|
|
|
|
**Patterns detectate**:
|
|
- AI Tool names: ChatGPT, GPT-3/4, Claude, Bard, Llama, Gemini, Copilot, Jasper, Writesonic, Copy.ai, Notion AI, Bing Chat
|
|
- Explicit disclosure: `[AI-generated]`, `This content was AI generated`, etc.
|
|
- Partial disclosure: `AI tools`, `AI assistance`, `used AI`
|
|
|
|
**Output**: `{ type: 'explicit' | 'partial' | 'implied' | 'none', text?: string }`
|
|
|
|
**PROBLEMA**: Patterns hardcodate, nu pot fi actualizate din UI. Nu detecteaza tool-uri noi (Sora, Udio, etc.).
|
|
|
|
### 4.2 Screening (Etapa 1)
|
|
|
|
**Redis Key**: `didi:config:ai-tampered:v1:prompts:screening`
|
|
|
|
**Variabile injectate**:
|
|
- `{{categories_list}}` - Categorii AI detection: `- CODE: NAME - SHORT_DESCRIPTION`
|
|
- `{{text}}` - Text wrappat, truncat la SCREENING_TEXT_LIMIT
|
|
|
|
**Format raspuns**:
|
|
```json
|
|
{
|
|
"ai_probability": 75,
|
|
"detected_categories": ["SYNTAX", "STYLE"],
|
|
"confidence_per_category": { "SYNTAX": 80, "STYLE": 65 },
|
|
"quick_indicators": ["uniform sentence length", "lack of typos"],
|
|
"quick_reasoning": "Text exhibits AI-like patterns"
|
|
}
|
|
```
|
|
|
|
**Early exit**: Daca ai_probability < 20 AND no disclosure AND no categories -> skip deep analysis.
|
|
|
|
### 4.3 Deep Analysis (Etapa 2)
|
|
|
|
**Redis Key**: `didi:config:ai-tampered:v1:prompts:deep_analysis`
|
|
|
|
**Variabile injectate**:
|
|
- `{{category_name}}`, `{{category_code}}`
|
|
- `{{indicators_list}}` - Indicatori per categorie: `- ID: NAME\n DESCRIPTION`
|
|
- `{{text}}` - Text complet (fara truncare)
|
|
|
|
**Format raspuns**:
|
|
```json
|
|
{
|
|
"category": "SYNTAX",
|
|
"detected_indicators": [
|
|
{ "indicator_id": "SYN_01", "confidence": 85, "evidence": "..." }
|
|
]
|
|
}
|
|
```
|
|
|
|
### 4.4 Image AI Detection (Vision)
|
|
|
|
**Tip**: HARDCODAT in ai-tampered-routes.ts:634-653
|
|
|
|
**Prompt complet**:
|
|
```
|
|
Analyze this image to determine if it was AI-generated (by DALL-E, Midjourney,
|
|
Stable Diffusion, etc.) or is a real photograph/human-created image.
|
|
|
|
Look for these AI generation indicators:
|
|
1. Anatomical errors: Extra fingers, merged hands, distorted faces
|
|
2. Texture anomalies: Overly smooth skin, plastic-like appearance
|
|
3. Background artifacts: Blurred or nonsensical backgrounds
|
|
4. Lighting inconsistencies: Shadows going different directions
|
|
5. Text/writing errors: Garbled text, nonsensical letters
|
|
6. Repetitive patterns: Unnatural repetition in textures
|
|
7. Watermarks/signatures: AI tool watermarks
|
|
8. Style indicators: Characteristic AI art styles
|
|
9. Edge artifacts: Unnatural edges, halos
|
|
10. Composition issues: Unnatural object placement
|
|
|
|
Return JSON only:
|
|
{ "ai_generated_probability": 75, "indicators": [...], "evidence": "..." }
|
|
```
|
|
|
|
**Vision Cascade**: Qwen Local (10.11.10.17:14011) -> Gemini Flash -> GPT-4o
|
|
**Fallback daca toate esueaza**: Returns neutral 50% probability
|
|
**PROBLEMA**: Nu este configurabil din Redis (key definit in keys.ts dar nefolosit).
|
|
|
|
### 4.5 Scoring (post-LLM)
|
|
Din Redis `didi:config:ai-tampered:v1:scoring_config`:
|
|
- blend_weights (screening vs deep)
|
|
- disclosure_impact multipliers
|
|
- thresholds for verdict categories
|
|
|
|
---
|
|
|
|
## 5. CLAIMS
|
|
|
|
### 5.1 Extraction (Etapa 1)
|
|
|
|
**Redis Key**: `didi:config:claims:v1:prompts:extraction`
|
|
|
|
**System Prompt** (din seed 002):
|
|
```
|
|
You are a claim extraction expert. Extract all verifiable factual claims from
|
|
the given text. A claim is a statement that can potentially be verified as true
|
|
or false. DO NOT include opinions, questions, or subjective statements unless
|
|
they are presented as facts.
|
|
```
|
|
|
|
**Variabile injectate**:
|
|
- `{{types_list}}` - Tipuri claim din framework: `- VF: Verifiable Fact - Can be checked (Web Search)`
|
|
- `{{text}}` - Max 10000 caractere, wrappat in `<analyzed_content>`
|
|
|
|
**Tipuri claim** (9): EF, VF, RE, SC, QA, CC, PC, OF, VC
|
|
|
|
**Format raspuns**:
|
|
```json
|
|
{
|
|
"claims": [
|
|
{ "text": "exact claim", "type": "VF", "priority": "high", "context": "..." }
|
|
]
|
|
}
|
|
```
|
|
|
|
**IMPORTANT**: Max 7 claims verificate (restul silentios filtrate). Claims cu priority='low' sunt sarite.
|
|
|
|
### 5.2 Verification (Etapa 2)
|
|
|
|
**Redis Key**: `didi:config:claims:v1:prompts:verification`
|
|
|
|
**Flux**: Per claim extras -> M17 Web Search -> LLM verification
|
|
|
|
**M17 Web Search API**: `POST http://10.11.10.17:51100/v1/gather`
|
|
```json
|
|
{ "claim": "...", "max_search_results": 5, "auto_fallback": true,
|
|
"include_full_text": true, "timeout_seconds": 90, "language": "auto" }
|
|
```
|
|
|
|
**Variabile injectate in prompt verificare**:
|
|
- `{{claim}}` - Text claim, wrappat in `<extracted_data type="claim">`
|
|
- `{{claim_type}}` - ex: "VF - Verifiable Fact"
|
|
- `{{evidence}}` - Rezultate web search formatate: `[1] title\nURL: ...\nSource: ...\nContent: ...`
|
|
- `{{statuses}}` - Status codes: VT, LT, UV, LF, VF, OP, NV
|
|
|
|
**Format raspuns**:
|
|
```json
|
|
{
|
|
"sources_analysis": [
|
|
{ "url": "...", "stance": "SUPPORTS|CONTRADICTS|NEUTRAL", "reliability": "official|news|blog|unknown" }
|
|
],
|
|
"agreement_score": 75,
|
|
"confidence": 80,
|
|
"status": "VT",
|
|
"reasoning": "explanation"
|
|
}
|
|
```
|
|
|
|
**IMPORTANT**: Server-ul IGNORA status-ul si agreement_score de la LLM si le recalculeaza din stances! LLM-ul furnizeaza doar analiza surselor, nu decizia finala.
|
|
|
|
### 5.3 Scoring (post-LLM)
|
|
Din Redis `didi:config:claims:v1:scoring_config`:
|
|
- status_thresholds (VT: min_confidence 85, min_agreement 85, etc.)
|
|
- source_reliability_weights (official: 1.2, news: 1.0, blog: 0.7, unknown: 0.5)
|
|
- claim_type_weights (EF: 0.95, VF: 0.85, etc.)
|
|
|
|
---
|
|
|
|
## 6. SOURCE ASSESSMENT
|
|
|
|
### 6.1 Extraction (Etapa 1)
|
|
|
|
**Redis Key**: `didi:config:source-assessment:v1:prompts:extraction`
|
|
**Fallback hardcodat**: DA (DEFAULT_EXTRACTION_PROMPT, executor.ts:124-154)
|
|
|
|
**System**: "You extract source attribution metadata from text. Output ONLY valid JSON."
|
|
|
|
**Variabile**:
|
|
- `{{text}}` - Primele 2000 caractere
|
|
- `{{url_context}}` - URL daca exista
|
|
|
|
**Output**: `{ publication, author, platform_code, content_type, url_found, queries[] }`
|
|
|
|
### 6.2 Evaluation (Etapa 2)
|
|
|
|
**Redis Key**: `didi:config:source-assessment:v1:prompts:evaluation`
|
|
**Fallback hardcodat**: DA (DEFAULT_EVALUATION_PROMPT, executor.ts:156-209)
|
|
|
|
**Variabile**:
|
|
- `{{publication}}`, `{{author}}`, `{{content_type}}`, `{{platform_code}}`
|
|
- `{{domain_context}}` - Rezultat Domain Check API
|
|
- `{{evidence_summary}}` - Rezultate M17 search
|
|
- `{{source_type_options}}`, `{{author_options}}`, `{{platform_options}}`
|
|
- `{{credibility_indicators}}`
|
|
|
|
**Output**: `{ source_type_id, author_classification_code, platform_code, credibility_indicators[], publication_confirmed, author_confirmed, reasoning }`
|
|
|
|
### 6.3 Scoring
|
|
Din Redis `didi:config:source-assessment:v1:scoring_config`:
|
|
- axis_weights: publication 0.35, domain 0.25, author 0.25, platform 0.15
|
|
- verdict_thresholds: TRUSTED >=70, NEUTRAL >=50, SUSPICIOUS >=30, else UNTRUSTED
|
|
|
|
### 6.4 API-uri externe
|
|
- M17 Search: `POST http://10.11.10.17:51100/v1/search` (timeout 20s)
|
|
- Domain Check: `POST http://<domain-check-host>:11000/api/v1/check/check` (timeout 15s)
|
|
|
|
---
|
|
|
|
## 7. VERDICT
|
|
|
|
### 7.1 Verdict Calculator (algoritm, fara LLM)
|
|
|
|
**Fisier**: verdict-calculator.ts
|
|
|
|
**Formula de baza**:
|
|
```
|
|
risk_score = SUM(component_score * weight) pentru fiecare componenta activa
|
|
```
|
|
|
|
**Ponderi default** (din Redis `didi:framework:weights`):
|
|
- manipulation (techniques): 35%
|
|
- claims: 25%
|
|
- source: 20%
|
|
- ai_tampered: 10%
|
|
- context: 10%
|
|
|
|
**Input Profiles** (din Redis `didi:config:pipeline:v1:input_profiles`):
|
|
6 profiluri: text_no_url, text_with_url, url, image, audio, video
|
|
Fiecare profil defineste:
|
|
- Ponderi per componenta (suprascriu default-urile)
|
|
- Reguli INCONCLUSIVE (min_components, required_any, primary_components)
|
|
- Override-uri (false_claims, severe_techniques, undisclosed_ai, untrusted_domain)
|
|
- AI disclosure multipliers (explicit, partial, implied, none)
|
|
|
|
**Overrides** (bonusuri la risk_score):
|
|
- false_claims: +15 per claim fals, max +40
|
|
- severe_techniques: +10 daca >= 2 tehnici severe
|
|
- undisclosed_ai: +15 daca AI nedezvaltuit
|
|
- untrusted_domain: +20/+10/+25 (untrusted/suspicious/blacklisted)
|
|
- domain_red_flags: +5 per flag, max +15
|
|
- synergy: +5 per componenta peste threshold, max +15
|
|
|
|
**Categorii verdict** (din Redis `didi:framework:verdicts`):
|
|
RELIABLE (0-15), MOSTLY_RELIABLE (16-30), MIXED (31-55), QUESTIONABLE (56-75), UNRELIABLE (76-90), DISINFORMATION (91-100), INCONCLUSIVE (special)
|
|
|
|
### 7.2 Verdict Explanation (LLM review)
|
|
|
|
**Redis Key**: `didi:config:pipeline:v1:prompts:verdict_explanation`
|
|
**Fallback hardcodat**: DA (verdict-explanation.ts:88-131)
|
|
|
|
**System Prompt** (esenta):
|
|
```
|
|
You are the final judge. Use your own knowledge to evaluate.
|
|
Treat unverified claims as suspicious if verifiable.
|
|
Do NOT rubber-stamp the algorithm. Override when reasoning demands it.
|
|
```
|
|
|
|
**Variabile injectate**:
|
|
- `{{framework_params}}` - Categorii, ponderi, flow algoritm, nivele confidence
|
|
- `{{component_results}}` - Rezultate per componenta: [RAN]/[CRASHED]/[SKIPPED] + scoruri
|
|
- `{{math_verdict}}` - Verdict algoritmic: risk_score, confidence, severity, weights, overrides
|
|
- `{{max_adjustment}}` - Cat poate ajusta (default 30 puncte)
|
|
- `{{baseline_score}}` - Scorul matematic de referinta
|
|
- `{{valid_categories}}` - RELIABLE, MOSTLY_RELIABLE, MIXED, QUESTIONABLE, UNRELIABLE, DISINFORMATION, INCONCLUSIVE
|
|
|
|
**FORMAT RASPUNS** (singurul cu output bilingv):
|
|
```json
|
|
{
|
|
"risk_score": 0-100,
|
|
"risk_category": "UNRELIABLE",
|
|
"confidence": 0-100,
|
|
"explanation_ro": "3-5 propozitii in romana",
|
|
"explanation_en": "3-5 sentences in English",
|
|
"adjusted": true,
|
|
"reasoning": "1-2 sentences why adjustment was made"
|
|
}
|
|
```
|
|
|
|
**Fallback parsing**: Daca JSON fail, regex: `RO: ...` si `EN: ...`
|
|
|
|
**Modele** (din Redis `didi:config:verdict:v1:available_models`):
|
|
1. local:qwen3-235b (primary, temp=0.1, 2000 tokens, 45s)
|
|
2. openrouter:gemini-flash (fallback, temp=0.1, 2000 tokens, 30s)
|
|
3. openrouter:gpt-4o-mini (fallback, temp=0.1, 2000 tokens, 30s)
|
|
|
|
**IMPORTANT**: LLM-ul poate AJUSTA scorul cu max +-30 puncte. Ajustarea e clamped la baseline +/- maxAdjustment.
|
|
|
|
### 7.3 Virality Calculator (algoritm, fara LLM)
|
|
Factori: emotie, urgenta, reach, controversy
|
|
Output: virality_score 0-100, virality_level, virality_factors
|
|
|
|
---
|
|
|
|
## 8. MEDIA PIPELINE
|
|
|
|
### 8.1 Vision - Text Extraction (OCR)
|
|
|
|
**Redis Key**: `didi:config:vision:v1:prompts:extraction`
|
|
**Fallback**:
|
|
- System: "You are a text extraction specialist. Extract only the meaningful content from images..."
|
|
- User: "Extract the main text content from this image. Return ONLY the actual message... If no meaningful text, respond with NO_TEXT_FOUND."
|
|
|
|
**Folosit de**: pipeline-routes.ts, claims-routes.ts, routes.ts, component-runner.ts, source-assessment-routes.ts
|
|
|
|
### 8.2 Vision - Video Frames (Misinformation)
|
|
|
|
**Redis Key**: `didi:config:vision:v1:prompts:video_frames`
|
|
**Fallback**:
|
|
- System: "You are a video frame analyst specializing in misinformation detection..."
|
|
- User: "Analyze these {{frame_count}} video frames in sequence. Focus on: text overlays, visual manipulation, narrative..."
|
|
|
|
### 8.3 Vision - Video AI Detection
|
|
|
|
**Redis Key**: `didi:config:vision:v1:prompts:ai_detection`
|
|
**Fallback**:
|
|
- System: "You are a video frame analyst specializing in detecting AI-generated content..."
|
|
- User: "Analyze these {{frame_count}} frames for: face consistency, lighting coherence, background stability, texture anomalies, motion artifacts... End with AI_CONFIDENCE: <0-100>"
|
|
|
|
### 8.4 Vision Model Cascade
|
|
|
|
| Order | Model | Provider | Endpoint | Timeout |
|
|
|-------|-------|----------|----------|---------|
|
|
| 1 | Qwen3.5-397B-A17B | qwen-local | http://10.11.10.17:14011/v1/chat/completions | 60s |
|
|
| 2 | gemini-2.0-flash-001 | openrouter | https://openrouter.ai/api/v1/chat/completions | 60s |
|
|
| 3 | gpt-4o | openrouter | https://openrouter.ai/api/v1/chat/completions | 60s |
|
|
|
|
Configurabil din Redis: `didi:config:ai-tampered:v1:vision_models`
|
|
|
|
### 8.5 Transcription (Audio/Video)
|
|
|
|
| Order | Provider | Model | Endpoint | Timeout |
|
|
|-------|----------|-------|----------|---------|
|
|
| 1 | M17-Whisper | whisper-large-v3 | http://10.11.10.17:11000/audio/v1/transcriptions | 180s |
|
|
| 2 | Groq-Whisper | whisper-large-v3-turbo | https://api.groq.com/openai/v1/audio/transcriptions | 120s |
|
|
| 3 | OpenAI-Whisper | whisper-1 | https://api.openai.com/v1/audio/transcriptions | 120s |
|
|
|
|
- Limba: auto-detect (Whisper)
|
|
- Limba detectata returnata dar NU folosita downstream
|
|
- Min transcript: 10 caractere (sub = fallback la urmatorul provider)
|
|
|
|
### 8.6 Video Processing Pipeline
|
|
1. Download video (yt-dlp / direct fetch)
|
|
2. Check durata (max 180s)
|
|
3. Extract frames ffmpeg (interval 5s, max 10 frames, min 3)
|
|
4. Extract audio ffmpeg -> transcribe
|
|
5. Analyze frames via vision cascade
|
|
6. Merge: `[AUDIO TRANSCRIPT]\n...\n\n[VISUAL ANALYSIS]\n...`
|
|
|
|
---
|
|
|
|
## 9. FLUX PG -> REDIS -> EXECUTOR
|
|
|
|
### Tabelul component_prompt (PostgreSQL)
|
|
```sql
|
|
bos_parammgmt.component_prompt (
|
|
prompt_id SERIAL PK,
|
|
component_code VARCHAR(50), -- 'techniques', 'ai-tampered', 'claims', etc.
|
|
stage_code VARCHAR(50), -- 'techniques_screening', 'claims_extraction', etc.
|
|
system_prompt TEXT,
|
|
user_template TEXT,
|
|
description TEXT,
|
|
UNIQUE (component_code, stage_code)
|
|
)
|
|
```
|
|
|
|
### Sync Redis (sync-redis.ts)
|
|
```
|
|
fetchPrompts() -> SELECT * FROM component_prompt
|
|
|
|
|
v
|
|
Group by component_code -> { "techniques": { "screening": {system, user_template} } }
|
|
|
|
|
v
|
|
For each component+stage:
|
|
shortStage = stage_code.replace(component_prefix, '')
|
|
redis.SET("didi:config:{comp}:{version}:prompts:{shortStage}", JSON)
|
|
```
|
|
|
|
### Version Map
|
|
```
|
|
techniques -> v3
|
|
ai-tampered -> v1
|
|
claims -> v1
|
|
source-assessment -> v1
|
|
pipeline -> v1
|
|
vision -> v1
|
|
```
|
|
|
|
### Executor Loading Patterns
|
|
|
|
| Componenta | Pattern | Fallback? |
|
|
|-----------|---------|-----------|
|
|
| Techniques | `loadFromRedis('prompts:screening')` -> throw if missing | NU |
|
|
| AI-Tampered | `loadFromRedis('prompts:screening')` -> throw if missing | NU |
|
|
| Claims | `loadConfig('prompts:extraction')` -> throw if missing | NU |
|
|
| Source Assessment | `loadPrompt('extraction', DEFAULT)` -> return default | DA |
|
|
| Verdict Explanation | `redis.get(key)` -> use hardcoded | DA |
|
|
| Vision prompts | `redis.get(key)` -> use hardcoded | DA |
|
|
|
|
**PROBLEMA CRITICA**: Techniques, AI-Tampered si Claims CRAPA daca Redis nu are prompt-urile. Source Assessment si Verdict au fallback.
|
|
|
|
---
|
|
|
|
## 10. AUDIT SEPARARE LINGVISTICA
|
|
|
|
### Matrice limba per componenta
|
|
|
|
| Componenta | Limba System Prompt | Limba User Template | Limba LLM Output | Limba Finala User |
|
|
|-----------|--------------------|--------------------|-------------------|-------------------|
|
|
| Techniques Screening | EN | EN + data any lang | EN (JSON codes) | Coduri dimensiuni (D1-D8) |
|
|
| Techniques Deep | EN | EN + data any lang | EN (JSON codes) | Tehnici: id + name EN |
|
|
| AI-Tampered Screening | EN | EN + data any lang | EN (JSON codes) | Categorii: codes |
|
|
| AI-Tampered Deep | EN | EN + data any lang | EN (JSON codes) | Indicatori: codes |
|
|
| AI-Tampered Image | EN | EN | EN (JSON) | ai_probability + evidence EN |
|
|
| Claims Extraction | EN | EN + data any lang | EN (JSON) | Claims in limba originala textului |
|
|
| Claims Verification | EN | EN + evidence any lang | EN (JSON) | Status codes + reasoning EN |
|
|
| Source Extraction | EN | EN + data any lang | EN (JSON) | Publication/author names |
|
|
| Source Evaluation | EN | EN + evidence any lang | EN (JSON) | Codes + reasoning EN |
|
|
| **Verdict Explanation** | **EN** | **EN** | **RO + EN** | **explanation_ro + explanation_en** |
|
|
| Vision Text Extraction | EN | EN | Any (text content) | Text extras in limba imaginii |
|
|
| Vision Video Frames | EN | EN | EN | Analiza vizuala EN |
|
|
| Vision AI Detection | EN | EN | EN | Evidence EN |
|
|
|
|
### Constatari cheie
|
|
|
|
1. **SINGURUL output bilingv este Verdict Explanation** - produce `explanation_ro` + `explanation_en`
|
|
2. **Toate prompt-urile sunt in engleza** - indiferent de limba textului analizat
|
|
3. **Textul utilizatorului poate fi in orice limba** - LLM-ul primeste text RO/EN/etc wrappat in `<analyzed_content>`
|
|
4. **Claims sunt extrase in limba originala** - daca textul e in romana, claims sunt in romana
|
|
5. **Evidence de la web search poate fi in orice limba** - M17 are `language: 'auto'`
|
|
6. **Codurile sunt language-neutral** - D1, VT, SYNTAX etc. nu depind de limba
|
|
7. **Descrierile tehnicilor** din framework prefera `.en` hardcodat (executor.ts:475): `tech.description?.en`
|
|
8. **Categoriile verdict** din framework au descrieri in ROMANA (din seed)
|
|
9. **Nu exista parametru de limba** pasat la niciun executor
|
|
|
|
### Probleme lingvistice identificate
|
|
|
|
| # | Problema | Severitate | Locatie |
|
|
|---|---------|------------|---------|
|
|
| L1 | Claims extrase in RO dar verificate cu prompt EN - LLM poate confunda | MEDIE | claims/executor.ts |
|
|
| L2 | Technique descriptions hardcodat `.en` - nu exista fallback `.ro` | MICA | techniques/executor.ts:475 |
|
|
| L3 | Evidence M17 poate fi in RO dar prompt-ul de verificare e EN | MICA | claims/executor.ts:474 |
|
|
| L4 | Verdict explanation cere RO+EN dar nu specifica "Romanian" explicit in prompt | MEDIE | verdict-explanation.ts |
|
|
| L5 | Disclosure patterns doar EN (nu detecteaza "generat de AI" in romana) | MEDIE | ai-tampered/executor.ts:190 |
|
|
| L6 | Vision prompts doar EN - nu specifica limba textului din imagine | MICA | vision.ts |
|
|
| L7 | Transcription detecteaza limba dar nu o paseaza downstream | MICA | transcription.ts |
|
|
| L8 | Framework verdict categories au descrieri RO in DB dar coduri EN - mixing | INFO | didiFramework seed |
|
|
|
|
---
|
|
|
|
## 11. PROBLEME GASITE (32 issues)
|
|
|
|
### CRITICE (3)
|
|
|
|
| # | Problema | Impact | Locatie |
|
|
|---|---------|--------|---------|
|
|
| C1 | Techniques/AI-Tampered/Claims CRAPA daca prompt-urile lipsesc din Redis (no fallback) | Serviciul devine inoperabil dupa un flush Redis | techniques/executor.ts, ai-tampered/executor.ts, claims/executor.ts |
|
|
| C2 | Float gap in verdict categories: 90.x nu se potriveste UNRELIABLE(76-90) nici DISINFORMATION(91-100) -> RELIABLE | Verdic complet gresit (deja documentat in VERDICT_BUGS_AUDIT.md Bug #1) | verdict-calculator.ts |
|
|
| C3 | Sync Redis este MANUAL - nu exista auto-sync la update prompt | Dupa editare prompt din UI, trebuie trigger manual POST /api/sync-redis | sync-redis.ts |
|
|
|
|
### MARI (10)
|
|
|
|
| # | Problema | Impact | Locatie |
|
|
|---|---------|--------|---------|
|
|
| M1 | Image AI detection prompt HARDCODAT, nu foloseste Redis key (definit dar nefolosit) | Nu poate fi actualizat fara deploy | ai-tampered-routes.ts:634 |
|
|
| M2 | Disclosure patterns HARDCODATE (nu detecteaza tool-uri noi: Sora, Udio, Flux) | False negatives pe AI tool-uri noi | ai-tampered/executor.ts:190-231 |
|
|
| M3 | Max 7 claims verificate, restul silentios filtrate (utilizatorul nu stie) | Texte lungi pierd claims importante | claims/executor.ts:415 |
|
|
| M4 | Claims cu priority='low' sarite silentios fara indicator in raspuns | Utilizatorul nu stie ce a fost exclus | claims/executor.ts:408 |
|
|
| M5 | Server ignora status-ul LLM si agreement_score dar nu logeaza discrepanta | Debug dificil cand server si LLM dau rezultate diferite | claims/executor.ts:507 |
|
|
| M6 | Techniques descriptions hardcodat `.en` prefer English, fara fallback `.ro` | Daca prompt-ul e RO dar descrierile sunt EN = mixing | techniques/executor.ts:475 |
|
|
| M7 | Prompt keys Techniques nu sunt in keys.ts (missing from registry) | Greu de auditat, inconsistenta cod | shared/redis/keys.ts |
|
|
| M8 | Text truncat silentios (3000/10000/12000 chars) fara log sau avertizare | Context pierdut pentru texte lungi, utilizator neinformat | techniques/executor.ts, claims/executor.ts |
|
|
| M9 | Disclosure patterns doar EN - nu detecteaza "generat de AI" sau "creat cu inteligenta artificiala" | Miss pe continut romanesc | ai-tampered/executor.ts:190 |
|
|
| M10 | Transcription detecteaza limba dar NU o paseaza la executor | Executorul nu stie ca textul e RO/EN/FR | transcription.ts, video-processor.ts |
|
|
|
|
### MEDII (12)
|
|
|
|
| # | Problema | Impact | Locatie |
|
|
|---|---------|--------|---------|
|
|
| m1 | Zod schemas folosesc `.passthrough()` - extra fields trec nevalidate | LLM hallucinations trec netectate | toate executoarele |
|
|
| m2 | Fallback defaults prea generice: ai_probability=0 vs "analysis failed" | Nu se poate distinge 0% real de eroare | ai-tampered/executor.ts |
|
|
| m3 | Evidence formatata ca text plain, nu JSON structurat | LLM poate interpreta gresit | claims/executor.ts:462 |
|
|
| m4 | Indicators din framework incarcati dar NU pasati in prompt (Techniques) | LLM nu stie ce indicatori sa caute | techniques/executor.ts:473 |
|
|
| m5 | Toate modelele fallback primesc acelasi prompt (no model-specific tuning) | Modele slabe pot esua pe prompt complex | toate executoarele |
|
|
| m6 | Verdict explanation parsing are fallback regex dar e fragil | Daca LLM nu respecta formatul, pierde explicatia | verdict-explanation.ts:523 |
|
|
| m7 | Verdict explanation cere RO+EN dar "Romanian" nu apare explicit in prompt | Depinde de LLM sa ghiceasca limba din "explanation_ro" field name | verdict-explanation.ts:101 |
|
|
| m8 | Video AI detection prompt cere "AI_CONFIDENCE: X" la final - fragil | Orice variatie in format pierde scorul | video-processor.ts |
|
|
| m9 | Temperature fixe per etapa, nu per complexitate text | Text scurt vs lung poate necesita temperature diferite | toate executoarele |
|
|
| m10 | Status code mismatch: prompt Claims listeaza 7 coduri (incl NV) dar framework poate avea 6 | LLM poate returna cod inexistent | claims seed vs framework |
|
|
| m11 | Vision model Qwen converteste URL-uri public->internal dar Gemini/GPT nu pot accesa MinIO intern | Fallback la Gemini/GPT poate esua pe imagini MinIO | vision.ts:189-196 |
|
|
| m12 | Source Assessment models au timeout 15s - prea scurt pentru modele lente | Timeout prematur pe Qwen local daca e incarcat | source-assessment/executor.ts |
|
|
|
|
### MICI / INFORMATIONALE (7)
|
|
|
|
| # | Problema | Impact | Locatie |
|
|
|---|---------|--------|---------|
|
|
| i1 | Nu exista versionare prompt-uri (nu se stie ce versiune ruleaza) | Rollback imposibil | component_prompt table |
|
|
| i2 | Console logging in engleza cu emoji-uri, nu structured logging | Parse dificil in monitoring | toate executoarele |
|
|
| i3 | Framework categories verdict au descrieri RO in seed dar coduri EN | Inconsistenta cosmetica | didiFramework seed |
|
|
| i4 | Claim types au 9 coduri dar unele rareori folosite (PC, VC) | Polueaza prompt-ul de extragere | claims framework |
|
|
| i5 | wrapUserContent() elimina `</analyzed_content>` dar nu alte tag-uri XML | Injection partial posibil cu alte tag-uri | prompt-safety.ts |
|
|
| i6 | Video frames: min 3, max 10, interval 5s - hardcodat | Nu se poate ajusta per analiza | video-processor.ts |
|
|
| i7 | Redis keys permanente (no TTL) - daca sync esueaza, date vechi raman la infinit | Date potentiale stale | sync-redis.ts |
|
|
|
|
---
|
|
|
|
## 12. RECOMANDARI
|
|
|
|
### Prioritate 1 - Fix imediat (fara impact frontend)
|
|
|
|
1. **Adauga fallback prompts la Techniques, AI-Tampered, Claims** (ca Source Assessment)
|
|
- Hardcodeaza default-uri in executor care se folosesc daca Redis e gol
|
|
- Estimare: 1-2 ore per componenta
|
|
|
|
2. **Muta Image AI detection prompt in Redis** (foloseste ConfigKeys.visionPromptAiDetection deja definit)
|
|
- Estimare: 30 min
|
|
|
|
3. **Adauga disclosure patterns in romana**
|
|
- "generat de AI", "creat cu inteligenta artificiala", "produs de ChatGPT" etc.
|
|
- Estimare: 1 ora
|
|
|
|
4. **Fix keys.ts** - adauga prompt keys lipsa pentru Techniques
|
|
- Estimare: 15 min
|
|
|
|
### Prioritate 2 - Imbunatatiri lingvistice
|
|
|
|
5. **Adauga parametru `language` la toate executoarele**
|
|
- Detectat automat din transcription sau configurat per analiza
|
|
- Pasează limba in prompt: "The text is in {{language}}. Analyze accordingly."
|
|
- Estimare: 2-3 ore
|
|
|
|
6. **Specifica explicit "Romanian" in verdict explanation prompt**
|
|
- "Write explanation_ro in Romanian language" nu doar field name
|
|
- Estimare: 30 min (in Redis via UI)
|
|
|
|
7. **Paseaza limba detectata de transcription la executor**
|
|
- transcription.ts deja returneaza `language` - trebuie propagat
|
|
- Estimare: 1 ora
|
|
|
|
### Prioritate 3 - Imbunatatiri calitate
|
|
|
|
8. **Logeaza text truncation** - cand textul depaseste limita, log + metadata in raspuns
|
|
9. **Logeaza discrepanta LLM vs server** la Claims verification (cand server overrides LLM)
|
|
10. **Indica in raspuns claims sarite** - adauga `skipped_claims_count` in output
|
|
11. **Auto-sync Redis la update prompt** (webhook sau trigger in providers.ts)
|
|
12. **Adauga prompt versioning** - `version` column in component_prompt + Redis key cu versiune
|
|
|
|
### Prioritate 4 - Arhitecturala
|
|
|
|
13. **Standardizeaza pattern-ul de incarcare prompts** - toate executoarele sa foloseasca acelasi mecanism (cu fallback)
|
|
14. **Adauga health check prompt-uri** - endpoint care verifica ca toate prompt-urile exista in Redis
|
|
15. **Structured logging** - JSON logs cu session_id, component, stage, model, duration
|
|
16. **Model-specific prompt variations** - prompt-uri optimizate per tier de model
|
|
|
|
---
|
|
|
|
## ANEXA: Redis Keys Complete Map
|
|
|
|
```
|
|
# Framework data (permanent, synced manual)
|
|
didi:framework:techniques # Ierarhie completa tehnici
|
|
didi:framework:dimensions_compact # Lista compacta dimensiuni
|
|
didi:framework:claims # Tipuri, statusuri, confidence claims
|
|
didi:framework:verdicts # Categorii verdict, risk mappings
|
|
didi:framework:weights # Ponderi componente + scenarii
|
|
didi:framework:sources # Evaluare surse
|
|
didi:framework:providers # Config LLM providers + API keys
|
|
|
|
# Prompt-uri per componenta (permanent, synced manual)
|
|
didi:config:techniques:v3:prompts:screening
|
|
didi:config:techniques:v3:prompts:deep_analysis
|
|
didi:config:ai-tampered:v1:prompts:screening
|
|
didi:config:ai-tampered:v1:prompts:deep_analysis
|
|
didi:config:claims:v1:prompts:extraction
|
|
didi:config:claims:v1:prompts:verification
|
|
didi:config:source-assessment:v1:prompts:extraction
|
|
didi:config:source-assessment:v1:prompts:evaluation
|
|
didi:config:pipeline:v1:prompts:verdict_explanation
|
|
didi:config:vision:v1:prompts:extraction
|
|
didi:config:vision:v1:prompts:video_frames
|
|
didi:config:vision:v1:prompts:ai_detection
|
|
|
|
# Stage assignments (modele LLM per etapa)
|
|
didi:config:techniques:v3:stage_assignments
|
|
didi:config:ai-tampered:v1:stage_assignments
|
|
didi:config:claims:v1:stage_assignments
|
|
didi:config:source-assessment:v1:stage_assignments
|
|
|
|
# Scoring configs
|
|
didi:config:techniques:v3:scoring_config
|
|
didi:config:ai-tampered:v1:scoring_config
|
|
didi:config:claims:v1:scoring_config
|
|
didi:config:source-assessment:v1:scoring_config
|
|
|
|
# Pipeline config
|
|
didi:config:pipeline:v1:component_config
|
|
didi:config:pipeline:v1:input_profiles
|
|
didi:config:pipeline:v1:verdict_config
|
|
didi:config:pipeline:v1:session_config
|
|
|
|
# Vision models
|
|
didi:config:ai-tampered:v1:vision_models
|
|
|
|
# Verdict models
|
|
didi:config:verdict:v1:available_models
|
|
```
|