From 91001493edbfc1b59c2aa78582f035c9d1f10eb4 Mon Sep 17 00:00:00 2001 From: waleedlatif1 Date: Sun, 12 Oct 2025 04:51:01 +0000 Subject: [PATCH] feat(i18n): update translations --- .../content/docs/de/blocks/guardrails.mdx | 317 ++++++++++++++++++ apps/docs/content/docs/de/execution/costs.mdx | 40 ++- apps/docs/content/docs/de/sdks/python.mdx | 4 +- apps/docs/content/docs/de/sdks/typescript.mdx | 240 +++++++++---- apps/docs/content/docs/de/triggers/api.mdx | 115 +++++-- apps/docs/content/docs/de/triggers/chat.mdx | 29 +- .../content/docs/es/blocks/guardrails.mdx | 317 ++++++++++++++++++ apps/docs/content/docs/es/execution/costs.mdx | 44 ++- apps/docs/content/docs/es/sdks/python.mdx | 2 +- apps/docs/content/docs/es/sdks/typescript.mdx | 255 ++++++++++---- apps/docs/content/docs/es/triggers/api.mdx | 101 ++++-- apps/docs/content/docs/es/triggers/chat.mdx | 27 +- .../content/docs/fr/blocks/guardrails.mdx | 317 ++++++++++++++++++ apps/docs/content/docs/fr/execution/costs.mdx | 48 ++- apps/docs/content/docs/fr/sdks/python.mdx | 6 +- apps/docs/content/docs/fr/sdks/typescript.mdx | 253 ++++++++++---- apps/docs/content/docs/fr/triggers/api.mdx | 105 ++++-- apps/docs/content/docs/fr/triggers/chat.mdx | 31 +- .../content/docs/ja/blocks/guardrails.mdx | 317 ++++++++++++++++++ apps/docs/content/docs/ja/execution/costs.mdx | 48 ++- apps/docs/content/docs/ja/sdks/python.mdx | 4 +- apps/docs/content/docs/ja/sdks/typescript.mdx | 253 ++++++++++---- apps/docs/content/docs/ja/triggers/api.mdx | 107 ++++-- apps/docs/content/docs/ja/triggers/chat.mdx | 27 +- .../content/docs/zh/blocks/guardrails.mdx | 317 ++++++++++++++++++ apps/docs/content/docs/zh/execution/costs.mdx | 38 ++- apps/docs/content/docs/zh/sdks/python.mdx | 4 +- apps/docs/content/docs/zh/sdks/typescript.mdx | 236 +++++++++---- apps/docs/content/docs/zh/triggers/api.mdx | 69 +++- apps/docs/content/docs/zh/triggers/chat.mdx | 31 +- apps/docs/i18n.lock | 308 +++++++++++------ 31 files changed, 3387 insertions(+), 623 deletions(-) create mode 100644 apps/docs/content/docs/de/blocks/guardrails.mdx create mode 100644 apps/docs/content/docs/es/blocks/guardrails.mdx create mode 100644 apps/docs/content/docs/fr/blocks/guardrails.mdx create mode 100644 apps/docs/content/docs/ja/blocks/guardrails.mdx create mode 100644 apps/docs/content/docs/zh/blocks/guardrails.mdx diff --git a/apps/docs/content/docs/de/blocks/guardrails.mdx b/apps/docs/content/docs/de/blocks/guardrails.mdx new file mode 100644 index 0000000000..1c3a531895 --- /dev/null +++ b/apps/docs/content/docs/de/blocks/guardrails.mdx @@ -0,0 +1,317 @@ +--- +title: Guardrails +--- + +import { Callout } from 'fumadocs-ui/components/callout' +import { Step, Steps } from 'fumadocs-ui/components/steps' +import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Image } from '@/components/ui/image' +import { Video } from '@/components/ui/video' + +Der Guardrails-Block validiert und schützt Ihre KI-Workflows, indem er Inhalte anhand mehrerer Validierungstypen überprüft. Stellen Sie die Datenqualität sicher, verhindern Sie Halluzinationen, erkennen Sie personenbezogene Daten und erzwingen Sie Formatanforderungen, bevor Inhalte durch Ihren Workflow fließen. + +
+ Guardrails Block +
+ +## Überblick + +Mit dem Guardrails-Block können Sie: + + + + JSON-Struktur validieren: Stellen Sie sicher, dass LLM-Ausgaben gültiges JSON sind, bevor sie geparst werden + + + Regex-Muster abgleichen: Überprüfen Sie, ob Inhalte bestimmten Formaten entsprechen (E-Mails, Telefonnummern, URLs usw.) + + + Halluzinationen erkennen: Verwenden Sie RAG + LLM-Scoring, um KI-Ausgaben anhand von Wissensdatenbankinhalten zu validieren + + + PII erkennen: Identifizieren und optional maskieren Sie personenbezogene Daten über 40+ Entitätstypen hinweg + + + +## Validierungstypen + +### JSON-Validierung + +Überprüft, ob Inhalte korrekt formatiertes JSON sind. Perfekt, um sicherzustellen, dass strukturierte LLM-Ausgaben sicher geparst werden können. + +**Anwendungsfälle:** +- Validieren von JSON-Antworten aus Agent-Blöcken vor dem Parsen +- Sicherstellen, dass API-Payloads korrekt formatiert sind +- Überprüfen der Integrität strukturierter Daten + +**Ausgabe:** +- `passed`: `true` bei gültigem JSON, sonst `false` +- `error`: Fehlermeldung bei fehlgeschlagener Validierung (z.B. "Ungültiges JSON: Unerwartetes Token...") + +### Regex-Validierung + +Prüft, ob Inhalte einem bestimmten regulären Ausdrucksmuster entsprechen. + +**Anwendungsfälle:** +- Validieren von E-Mail-Adressen +- Überprüfen von Telefonnummernformaten +- Verifizieren von URLs oder benutzerdefinierten Kennungen +- Durchsetzen spezifischer Textmuster + +**Konfiguration:** +- **Regex-Muster**: Der reguläre Ausdruck, der abgeglichen werden soll (z.B. `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}--- +title: Guardrails +--- + +import { Callout } from 'fumadocs-ui/components/callout' +import { Step, Steps } from 'fumadocs-ui/components/steps' +import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Image } from '@/components/ui/image' +import { Video } from '@/components/ui/video' + +Der Guardrails-Block validiert und schützt Ihre KI-Workflows, indem er Inhalte anhand mehrerer Validierungstypen überprüft. Stellen Sie die Datenqualität sicher, verhindern Sie Halluzinationen, erkennen Sie personenbezogene Daten und erzwingen Sie Formatanforderungen, bevor Inhalte durch Ihren Workflow fließen. + +
+ Guardrails Block +
+ +## Überblick + +Mit dem Guardrails-Block können Sie: + + + + JSON-Struktur validieren: Stellen Sie sicher, dass LLM-Ausgaben gültiges JSON sind, bevor sie geparst werden + + + Regex-Muster abgleichen: Überprüfen Sie, ob Inhalte bestimmten Formaten entsprechen (E-Mails, Telefonnummern, URLs usw.) + + + Halluzinationen erkennen: Verwenden Sie RAG + LLM-Scoring, um KI-Ausgaben anhand von Wissensdatenbankinhalten zu validieren + + + PII erkennen: Identifizieren und optional maskieren Sie personenbezogene Daten über 40+ Entitätstypen hinweg + + + +## Validierungstypen + +### JSON-Validierung + +Überprüft, ob Inhalte korrekt formatiertes JSON sind. Perfekt, um sicherzustellen, dass strukturierte LLM-Ausgaben sicher geparst werden können. + +**Anwendungsfälle:** +- Validieren von JSON-Antworten aus Agent-Blöcken vor dem Parsen +- Sicherstellen, dass API-Payloads korrekt formatiert sind +- Überprüfen der Integrität strukturierter Daten + +**Ausgabe:** +- `passed`: `true` bei gültigem JSON, sonst `false` +- `error`: Fehlermeldung bei fehlgeschlagener Validierung (z.B. "Ungültiges JSON: Unerwartetes Token...") + +### Regex-Validierung + +Prüft, ob Inhalte einem bestimmten regulären Ausdrucksmuster entsprechen. + +**Anwendungsfälle:** +- Validieren von E-Mail-Adressen +- Überprüfen von Telefonnummernformaten +- Verifizieren von URLs oder benutzerdefinierten Kennungen +- Durchsetzen spezifischer Textmuster + +**Konfiguration:** +- **Regex-Muster**: Der reguläre Ausdruck, der abgeglichen werden soll (z.B. für E-Mails) + +**Ausgabe:** +- `passed`: `true` wenn der Inhalt dem Muster entspricht, `false` andernfalls +- `error`: Fehlermeldung, wenn die Validierung fehlschlägt + +### Halluzinationserkennung + +Verwendet Retrieval-Augmented Generation (RAG) mit LLM-Bewertung, um zu erkennen, wann KI-generierte Inhalte im Widerspruch zu Ihrer Wissensdatenbank stehen oder nicht darin begründet sind. + +**Funktionsweise:** +1. Durchsucht Ihre Wissensdatenbank nach relevantem Kontext +2. Sendet sowohl die KI-Ausgabe als auch den abgerufenen Kontext an ein LLM +3. LLM weist einen Konfidenzwert zu (Skala 0-10) + - **0** = Vollständige Halluzination (völlig unbegründet) + - **10** = Vollständig begründet (komplett durch die Wissensdatenbank gestützt) +4. Validierung besteht, wenn der Wert ≥ Schwellenwert (Standard: 3) + +**Konfiguration:** +- **Wissensdatenbank**: Auswahl aus Ihren vorhandenen Wissensdatenbanken +- **Modell**: LLM für die Bewertung auswählen (erfordert starke Argumentationsfähigkeit - GPT-4o, Claude 3.7 Sonnet empfohlen) +- **API-Schlüssel**: Authentifizierung für den ausgewählten LLM-Anbieter (automatisch ausgeblendet für gehostete/Ollama-Modelle) +- **Konfidenz-Schwellenwert**: Mindestwert zum Bestehen (0-10, Standard: 3) +- **Top K** (Erweitert): Anzahl der abzurufenden Wissensdatenbank-Chunks (Standard: 10) + +**Ausgabe:** +- `passed`: `true` wenn Konfidenzwert ≥ Schwellenwert +- `score`: Konfidenzwert (0-10) +- `reasoning`: Erklärung des LLM für den Wert +- `error`: Fehlermeldung, wenn die Validierung fehlschlägt + +**Anwendungsfälle:** +- Validierung von Agent-Antworten anhand der Dokumentation +- Sicherstellung der faktischen Richtigkeit von Kundendienstantworten +- Überprüfung, ob generierte Inhalte mit dem Quellmaterial übereinstimmen +- Qualitätskontrolle für RAG-Anwendungen + +### PII-Erkennung + +Erkennt personenbezogene Daten mit Microsoft Presidio. Unterstützt über 40 Entitätstypen in mehreren Ländern und Sprachen. + +
+
+ +**Funktionsweise:** +1. Scannt Inhalte nach PII-Entitäten mittels Mustererkennung und NLP +2. Gibt erkannte Entitäten mit Positionen und Konfidenzwerten zurück +3. Maskiert optional erkannte PII in der Ausgabe + +**Konfiguration:** +- **Zu erkennende PII-Typen**: Auswahl aus gruppierten Kategorien über Modal-Selektor + - **Allgemein**: Personenname, E-Mail, Telefon, Kreditkarte, IP-Adresse usw. + - **USA**: SSN, Führerschein, Reisepass usw. + - **UK**: NHS-Nummer, Sozialversicherungsnummer + - **Spanien**: NIF, NIE, CIF + - **Italien**: Steuernummer, Führerschein, Umsatzsteuer-ID + - **Polen**: PESEL, NIP, REGON + - **Singapur**: NRIC/FIN, UEN + - **Australien**: ABN, ACN, TFN, Medicare + - **Indien**: Aadhaar, PAN, Reisepass, Wählernummer +- **Modus**: + - **Erkennen**: Nur PII identifizieren (Standard) + - **Maskieren**: Erkannte PII durch maskierte Werte ersetzen +- **Sprache**: Erkennungssprache (Standard: Englisch) + +**Ausgabe:** +- `passed`: `false` wenn ausgewählte PII-Typen erkannt werden +- `detectedEntities`: Array erkannter PII mit Typ, Position und Konfidenz +- `maskedText`: Inhalt mit maskierter PII (nur wenn Modus = "Maskieren") +- `error`: Fehlermeldung bei fehlgeschlagener Validierung + +**Anwendungsfälle:** +- Blockieren von Inhalten mit sensiblen persönlichen Informationen +- Maskieren von PII vor der Protokollierung oder Speicherung von Daten +- Einhaltung von DSGVO, HIPAA und anderen Datenschutzbestimmungen +- Bereinigung von Benutzereingaben vor der Verarbeitung + +## Konfiguration + +### Zu validierender Inhalt + +Der zu validierende Eingabeinhalt. Dieser stammt typischerweise aus: +- Ausgaben von Agent-Blöcken: `` +- Ergebnisse von Funktionsblöcken: `` +- API-Antworten: `` +- Jede andere Blockausgabe + +### Validierungstyp + +Wählen Sie aus vier Validierungstypen: +- **Gültiges JSON**: Prüfen, ob der Inhalt korrekt formatiertes JSON ist +- **Regex-Übereinstimmung**: Überprüfen, ob der Inhalt einem Regex-Muster entspricht +- **Halluzinationsprüfung**: Validierung gegen Wissensdatenbank mit LLM-Bewertung +- **PII-Erkennung**: Erkennen und optional Maskieren personenbezogener Daten + +## Ausgaben + +Alle Validierungstypen liefern: + +- **``**: Boolean, der angibt, ob die Validierung erfolgreich war +- **``**: Die Art der durchgeführten Validierung +- **``**: Die ursprüngliche Eingabe, die validiert wurde +- **``**: Fehlermeldung, wenn die Validierung fehlgeschlagen ist (optional) + +Zusätzliche Ausgaben nach Typ: + +**Halluzinationsprüfung:** +- **``**: Konfidenzwert (0-10) +- **``**: Erklärung des LLM + +**PII-Erkennung:** +- **``**: Array erkannter PII-Entitäten +- **``**: Inhalt mit maskierter PII (wenn Modus = "Mask") + +## Beispielanwendungsfälle + +### JSON vor dem Parsen validieren + +
+

Szenario: Sicherstellen, dass die Agent-Ausgabe gültiges JSON ist

+
    +
  1. Agent generiert strukturierte JSON-Antwort
  2. +
  3. Guardrails validiert das JSON-Format
  4. +
  5. Bedingungsblock prüft ``
  6. +
  7. Bei Erfolg → Daten parsen und verwenden, Bei Misserfolg → Wiederholen oder Fehler behandeln
  8. +
+
+ +### Halluzinationen verhindern + +
+

Szenario: Validierung von Kundendienstantworten

+
    +
  1. Agent generiert Antwort auf Kundenfrage
  2. +
  3. Guardrails prüft anhand der Support-Dokumentationswissensbasis
  4. +
  5. Wenn Konfidenzwert ≥ 3 → Antwort senden
  6. +
  7. Wenn Konfidenzwert \< 3 → Für manuelle Überprüfung markieren
  8. +
+
+ +### PII in Benutzereingaben blockieren + +
+

Szenario: Bereinigung von benutzerübermittelten Inhalten

+
    +
  1. Benutzer reicht Formular mit Textinhalt ein
  2. +
  3. Guardrails erkennt PII (E-Mails, Telefonnummern, Sozialversicherungsnummern usw.)
  4. +
  5. Bei erkannter PII → Einreichung ablehnen oder sensible Daten maskieren
  6. +
  7. Ohne PII → Normal verarbeiten
  8. +
+
+ +
+
+ +### E-Mail-Format validieren + +
+

Szenario: E-Mail-Adressformat prüfen

+
    +
  1. Agent extrahiert E-Mail aus Text
  2. +
  3. Guardrails validiert mit Regex-Muster
  4. +
  5. Bei Gültigkeit → E-Mail für Benachrichtigung verwenden
  6. +
  7. Bei Ungültigkeit → Korrektur anfordern
  8. +
+
+ +## Best Practices + +- **Verkettung mit Condition-Blöcken**: Verwende `` um Workflow-Logik basierend auf Validierungsergebnissen zu verzweigen +- **JSON-Validierung vor dem Parsen verwenden**: Validiere immer die JSON-Struktur, bevor du versuchst, LLM-Ausgaben zu parsen +- **Passende PII-Typen auswählen**: Wähle nur die PII-Entitätstypen aus, die für deinen Anwendungsfall relevant sind, um bessere Leistung zu erzielen +- **Vernünftige Konfidenz-Schwellenwerte festlegen**: Passe für die Halluzinationserkennung den Schwellenwert basierend auf deinen Genauigkeitsanforderungen an (höher = strenger) +- **Starke Modelle für Halluzinationserkennung verwenden**: GPT-4o oder Claude 3.7 Sonnet bieten genauere Konfidenz-Bewertungen +- **PII für Logging maskieren**: Verwende den "Mask"-Modus, wenn du Inhalte protokollieren oder speichern musst, die PII enthalten könnten +- **Regex-Muster testen**: Validiere deine Regex-Muster gründlich, bevor du sie in der Produktion einsetzt +- **Validierungsfehler überwachen**: Verfolge `` Nachrichten, um häufige Validierungsprobleme zu identifizieren + + + Guardrails-Validierung erfolgt synchron in deinem Workflow. Für die Halluzinationserkennung solltest du schnellere Modelle (wie GPT-4o-mini) wählen, wenn Latenz kritisch ist. + diff --git a/apps/docs/content/docs/de/execution/costs.mdx b/apps/docs/content/docs/de/execution/costs.mdx index 385ebd6699..32d05e2601 100644 --- a/apps/docs/content/docs/de/execution/costs.mdx +++ b/apps/docs/content/docs/de/execution/costs.mdx @@ -170,17 +170,49 @@ Verschiedene Abonnementpläne haben unterschiedliche Nutzungslimits: | **Team** | $500 (gepoolt) | 50 sync, 100 async | | **Enterprise** | Individuell | Individuell | +## Abrechnungsmodell + +Sim verwendet ein Abrechnungsmodell mit **Basisabonnement + Mehrverbrauch**: + +### Wie es funktioniert + +**Pro-Plan (20 €/Monat):** +- Monatliches Abonnement beinhaltet 20 € Nutzung +- Nutzung unter 20 € → Keine zusätzlichen Kosten +- Nutzung über 20 € → Zahlung des Mehrverbrauchs am Monatsende +- Beispiel: 35 € Nutzung = 20 € (Abonnement) + 15 € (Mehrverbrauch) + +**Team-Plan (40 €/Nutzer/Monat):** +- Gemeinsame Nutzung für alle Teammitglieder +- Mehrverbrauch wird auf Basis der gesamten Teamnutzung berechnet +- Organisationsinhaber erhält eine Rechnung + +**Enterprise-Pläne:** +- Fester monatlicher Preis, kein Mehrverbrauch +- Individuelle Nutzungslimits gemäß Vereinbarung + +### Schwellenwertabrechnung + +Wenn der nicht abgerechnete Mehrverbrauch 50 € erreicht, berechnet Sim automatisch den gesamten nicht abgerechneten Betrag. + +**Beispiel:** +- Tag 10: 70 € Mehrverbrauch → Sofortige Abrechnung von 70 € +- Tag 15: Zusätzliche 35 € Nutzung (insgesamt 105 €) → Bereits abgerechnet, keine Aktion +- Tag 20: Weitere 50 € Nutzung (insgesamt 155 €, 85 € nicht abgerechnet) → Sofortige Abrechnung von 85 € + +Dies verteilt hohe Mehrverbrauchskosten über den Monat, anstatt eine große Rechnung am Periodenende zu stellen. + ## Best Practices für Kostenmanagement -1. **Regelmäßig überwachen**: Prüfen Sie Ihr Nutzungs-Dashboard häufig, um Überraschungen zu vermeiden +1. **Regelmäßige Überwachung**: Prüfen Sie Ihr Nutzungs-Dashboard häufig, um Überraschungen zu vermeiden 2. **Budgets festlegen**: Nutzen Sie Planlimits als Leitplanken für Ihre Ausgaben 3. **Workflows optimieren**: Überprüfen Sie kostenintensive Ausführungen und optimieren Sie Prompts oder Modellauswahl -4. **Passende Modelle verwenden**: Stimmen Sie die Modellkomplexität auf die Aufgabenanforderungen ab +4. **Geeignete Modelle verwenden**: Passen Sie die Modellkomplexität an die Aufgabenanforderungen an 5. **Ähnliche Aufgaben bündeln**: Kombinieren Sie wenn möglich mehrere Anfragen, um den Overhead zu reduzieren ## Nächste Schritte - Überprüfen Sie Ihre aktuelle Nutzung unter [Einstellungen → Abonnement](https://sim.ai/settings/subscription) - Erfahren Sie mehr über [Logging](/execution/logging), um Ausführungsdetails zu verfolgen -- Erkunden Sie die [Externe API](/execution/api) für programmatische Kostenüberwachung -- Sehen Sie sich [Workflow-Optimierungstechniken](/blocks) an, um Kosten zu reduzieren \ No newline at end of file +- Erkunden Sie die [externe API](/execution/api) für programmatische Kostenüberwachung +- Sehen Sie sich [Workflow-Optimierungstechniken](/blocks) zur Kostenreduzierung an \ No newline at end of file diff --git a/apps/docs/content/docs/de/sdks/python.mdx b/apps/docs/content/docs/de/sdks/python.mdx index 368010f430..c185733f85 100644 --- a/apps/docs/content/docs/de/sdks/python.mdx +++ b/apps/docs/content/docs/de/sdks/python.mdx @@ -387,7 +387,7 @@ Behandeln Sie verschiedene Fehlertypen, die während der Workflow-Ausführung au from simstudio import SimStudioClient, SimStudioError import os -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) +client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) def execute_with_error_handling(): try: @@ -600,7 +600,7 @@ Führe Workflows mit Echtzeit-Streaming-Antworten aus: from simstudio import SimStudioClient import os -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) +client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) def execute_with_streaming(): """Execute workflow with streaming enabled.""" diff --git a/apps/docs/content/docs/de/sdks/typescript.mdx b/apps/docs/content/docs/de/sdks/typescript.mdx index 55e36ce7e2..28fadba397 100644 --- a/apps/docs/content/docs/de/sdks/typescript.mdx +++ b/apps/docs/content/docs/de/sdks/typescript.mdx @@ -604,28 +604,114 @@ async function executeClientSideWorkflow() { }); console.log('Workflow result:', result); - + // Update UI with result - document.getElementById('result')!.textContent = + document.getElementById('result')!.textContent = JSON.stringify(result.output, null, 2); } catch (error) { console.error('Error:', error); } } +``` + +### Datei-Upload + +Dateiobjekte werden automatisch erkannt und in das base64-Format konvertiert. Fügen Sie sie in Ihrer Eingabe unter dem Feldnamen ein, der dem API-Trigger-Eingabeformat Ihres Workflows entspricht. + +Das SDK konvertiert Dateiobjekte in dieses Format: + +```typescript +{ + type: 'file', + data: 'data:mime/type;base64,base64data', + name: 'filename', + mime: 'mime/type' +} +``` + +Alternativ können Sie Dateien manuell im URL-Format bereitstellen: + +```typescript +{ + type: 'url', + data: 'https://example.com/file.pdf', + name: 'file.pdf', + mime: 'application/pdf' +} +``` + + + + + ```typescript + import { SimStudioClient } from 'simstudio-ts-sdk'; + + const client = new SimStudioClient({ + apiKey: process.env.NEXT_PUBLIC_SIM_API_KEY! + }); + + // From file input + async function handleFileUpload(event: Event) { + const input = event.target as HTMLInputElement; + const files = Array.from(input.files || []); + + // Include files under the field name from your API trigger's input format + const result = await client.executeWorkflow('workflow-id', { + input: { + documents: files, // Must match your workflow's "files" field name + instructions: 'Analyze these documents' + } + }); + + console.log('Result:', result); + } + ``` + + + + + ```typescript + import { SimStudioClient } from 'simstudio-ts-sdk'; + import fs from 'fs'; + + const client = new SimStudioClient({ + apiKey: process.env.SIM_API_KEY! + }); + + // Read file and create File object + const fileBuffer = fs.readFileSync('./document.pdf'); + const file = new File([fileBuffer], 'document.pdf', { + type: 'application/pdf' + }); + + // Include files under the field name from your API trigger's input format + const result = await client.executeWorkflow('workflow-id', { + input: { + documents: [file], // Must match your workflow's "files" field name + query: 'Summarize this document' + } + }); + ``` + + + -// Attach to button click +// An Button-Klick anhängen document.getElementById('executeBtn')?.addEventListener('click', executeClientSideWorkflow); + ``` - Bei der Verwendung des SDK im Browser sollten Sie darauf achten, keine sensiblen API-Schlüssel offenzulegen. Erwägen Sie die Verwendung eines Backend-Proxys oder öffentlicher API-Schlüssel mit eingeschränkten Berechtigungen. + When using the SDK in the browser, be careful not to expose sensitive API keys. Consider using a backend proxy or public API keys with limited permissions. -### React Hook-Beispiel +### React Hook Example -Erstellen eines benutzerdefinierten React-Hooks für die Workflow-Ausführung: +Create a custom React hook for workflow execution: -```typescript +``` + +typescript import { useState, useCallback } from 'react'; import { SimStudioClient, WorkflowExecutionResult } from 'simstudio-ts-sdk'; @@ -671,7 +757,7 @@ export function useWorkflow(): UseWorkflowResult { }; } -// Usage in component +// Verwendung in Komponente function WorkflowComponent() { const { result, loading, error, executeWorkflow } = useWorkflow(); @@ -684,26 +770,29 @@ function WorkflowComponent() { return (
- {error &&
Error: {error.message}
} + {error &&
Fehler: {error.message}
} {result && (
-

Result:

+

Ergebnis:

{JSON.stringify(result, null, 2)}
)}
); } + ``` -### Asynchrone Workflow-Ausführung +### Async Workflow Execution -Führen Sie Workflows asynchron für lang laufende Aufgaben aus: +Execute workflows asynchronously for long-running tasks: -```typescript +``` + +typescript import { SimStudioClient, AsyncExecutionResult } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -712,47 +801,50 @@ const client = new SimStudioClient({ async function executeAsync() { try { - // Start async execution + // Starte asynchrone Ausführung const result = await client.executeWorkflow('workflow-id', { input: { data: 'large dataset' }, - async: true // Execute asynchronously + async: true // Asynchron ausführen }); - // Check if result is an async execution + // Prüfe, ob das Ergebnis eine asynchrone Ausführung ist if ('taskId' in result) { console.log('Task ID:', result.taskId); - console.log('Status endpoint:', result.links.status); + console.log('Status-Endpunkt:', result.links.status); - // Poll for completion + // Abfragen bis zur Fertigstellung let status = await client.getJobStatus(result.taskId); while (status.status === 'queued' || status.status === 'processing') { - console.log('Current status:', status.status); - await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds + console.log('Aktueller Status:', status.status); + await new Promise(resolve => setTimeout(resolve, 2000)); // Warte 2 Sekunden status = await client.getJobStatus(result.taskId); } if (status.status === 'completed') { - console.log('Workflow completed!'); - console.log('Output:', status.output); - console.log('Duration:', status.metadata.duration); + console.log('Workflow abgeschlossen!'); + console.log('Ausgabe:', status.output); + console.log('Dauer:', status.metadata.duration); } else { - console.error('Workflow failed:', status.error); + console.error('Workflow fehlgeschlagen:', status.error); } } } catch (error) { - console.error('Error:', error); + console.error('Fehler:', error); } } executeAsync(); + ``` -### Rate-Limiting und Wiederholungsversuche +### Rate Limiting and Retry -Automatische Behandlung von Rate-Limits mit exponentiellem Backoff: +Handle rate limits automatically with exponential backoff: -```typescript +``` + +typescript import { SimStudioClient, SimStudioError } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -761,7 +853,7 @@ const client = new SimStudioClient({ async function executeWithRetryHandling() { try { - // Automatically retries on rate limit + // Automatische Wiederholungsversuche bei Rate-Limit const result = await client.executeWithRetry('workflow-id', { input: { message: 'Process this' } }, { @@ -771,26 +863,29 @@ async function executeWithRetryHandling() { backoffMultiplier: 2 }); - console.log('Success:', result); + console.log('Erfolg:', result); } catch (error) { if (error instanceof SimStudioError && error.code === 'RATE_LIMIT_EXCEEDED') { - console.error('Rate limit exceeded after all retries'); + console.error('Rate-Limit nach allen Wiederholungsversuchen überschritten'); - // Check rate limit info + // Rate-Limit-Informationen prüfen const rateLimitInfo = client.getRateLimitInfo(); if (rateLimitInfo) { - console.log('Rate limit resets at:', new Date(rateLimitInfo.reset * 1000)); + console.log('Rate-Limit wird zurückgesetzt um:', new Date(rateLimitInfo.reset * 1000)); } } } } + ``` -### Nutzungsüberwachung +### Usage Monitoring -Überwachen Sie Ihre Kontonutzung und -limits: +Monitor your account usage and limits: -```typescript +``` + +typescript import { SimStudioClient } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -802,26 +897,45 @@ async function checkUsage() { const limits = await client.getUsageLimits(); console.log('=== Rate Limits ==='); - console.log('Sync requests:'); + console.log('Synchrone Anfragen:'); console.log(' Limit:', limits.rateLimit.sync.limit); - console.log(' Remaining:', limits.rateLimit.sync.remaining); - console.log(' Resets at:', limits.rateLimit.sync.resetAt); - console.log(' Is limited:', limits.rateLimit.sync.isLimited); + console.log(' Verbleibend:', limits.rateLimit.sync.remaining); + console.log(' Zurückgesetzt um:', limits.rateLimit.sync.resetAt); + console.log(' Ist limitiert:', limits.rateLimit.sync.isLimited); - console.log('\nAsync requests:'); + console.log('\nAsynchrone Anfragen:'); console.log(' Limit:', limits.rateLimit.async.limit); - console.log(' Remaining:', limits.rateLimit.async.remaining); - console.log(' Resets at:', limits.rateLimit.async.resetAt); - console.log(' Is limited:', limits.rateLimit.async.isLimited); + console.log(' Verbleibend:', limits.rateLimit.async.remaining); + console.log(' Zurückgesetzt um:', limits.rateLimit.async.resetAt); + console.log(' Ist limitiert:', limits.rateLimit.async.isLimited); - console.log('\n=== Usage ==='); - console.log('Current period cost: + console.log('\n=== Nutzung ==='); + console.log('Kosten der aktuellen Periode: $' + limits.usage.currentPeriodCost.toFixed(2)); + console.log('Limit: $' + limits.usage.limit.toFixed(2)); + console.log('Plan:', limits.usage.plan); + + const percentUsed = (limits.usage.currentPeriodCost / limits.usage.limit) * 100; + console.log('Nutzung: ' + percentUsed.toFixed(1) + '%'); + + if (percentUsed > 80) { + console.warn('⚠️ Warnung: Sie nähern sich Ihrem Nutzungslimit!'); + } + } catch (error) { + console.error('Fehler bei der Überprüfung der Nutzung:', error); + } +} + +checkUsage(); + +``` ### Streaming Workflow Execution Execute workflows with real-time streaming responses: -```typescript +``` + +typescript import { SimStudioClient } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -830,11 +944,11 @@ const client = new SimStudioClient({ async function executeWithStreaming() { try { - // Streaming für bestimmte Block-Ausgaben aktivieren + // Streaming für bestimmte Block-Outputs aktivieren const result = await client.executeWorkflow('workflow-id', { - input: { message: 'Count to five' }, + input: { message: 'Zähle bis fünf' }, stream: true, - selectedOutputs: ['agent1.content'] // Format blockName.attribute verwenden + selectedOutputs: ['agent1.content'] // Verwende das Format blockName.attribute }); console.log('Workflow-Ergebnis:', result); @@ -842,23 +956,28 @@ async function executeWithStreaming() { console.error('Fehler:', error); } } + ``` The streaming response follows the Server-Sent Events (SSE) format: ``` -data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":"One"} + +data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":"Eins"} data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":", zwei"} data: {"event":"done","success":true,"output":{},"metadata":{"duration":610}} data: [DONE] + ``` **React Streaming Example:** -```typescript +``` + +typescript import { useState, useEffect } from 'react'; function StreamingWorkflow() { @@ -870,7 +989,7 @@ function StreamingWorkflow() { setOutput(''); // WICHTIG: Führen Sie diesen API-Aufruf von Ihrem Backend-Server aus, nicht vom Browser - // Setzen Sie niemals Ihren API-Schlüssel im Client-seitigen Code frei + // Setzen Sie niemals Ihren API-Schlüssel im clientseitigen Code frei const response = await fetch('https://sim.ai/api/workflows/WORKFLOW_ID/execute', { method: 'POST', headers: { @@ -878,7 +997,7 @@ function StreamingWorkflow() { 'X-API-Key': process.env.SIM_API_KEY! // Nur serverseitige Umgebungsvariable }, body: JSON.stringify({ - message: 'Generate a story', + message: 'Generiere eine Geschichte', stream: true, selectedOutputs: ['agent1.content'] }) @@ -920,12 +1039,13 @@ function StreamingWorkflow() { return (
{output}
); } + ``` ## Getting Your API Key @@ -961,7 +1081,9 @@ function StreamingWorkflow() { The SDK is written in TypeScript and provides full type safety: -```typescript +``` + +typescript import { SimStudioClient, WorkflowExecutionResult, @@ -977,7 +1099,7 @@ const client: SimStudioClient = new SimStudioClient({ // Typsichere Workflow-Ausführung const result: WorkflowExecutionResult = await client.executeWorkflow('workflow-id', { input: { - message: 'Hello, TypeScript!' + message: 'Hallo, TypeScript!' } }); @@ -985,6 +1107,6 @@ const result: WorkflowExecutionResult = await client.executeWorkflow('workflow-i const status: WorkflowStatus = await client.getWorkflowStatus('workflow-id'); ``` -## License +## Lizenz Apache-2.0 \ No newline at end of file diff --git a/apps/docs/content/docs/de/triggers/api.mdx b/apps/docs/content/docs/de/triggers/api.mdx index 8dab4cfb38..c5990f52f8 100644 --- a/apps/docs/content/docs/de/triggers/api.mdx +++ b/apps/docs/content/docs/de/triggers/api.mdx @@ -22,9 +22,17 @@ Der API-Trigger stellt Ihren Workflow als sicheren HTTP-Endpunkt bereit. Senden /> -Fügen Sie für jeden Parameter ein Feld **Eingabeformat** hinzu. Die Ausgabeschlüssel zur Laufzeit spiegeln das Schema wider und sind auch unter `` verfügbar. +Füge ein **Eingabeformat**-Feld für jeden Parameter hinzu. Unterstützte Typen: -Manuelle Ausführungen im Editor verwenden die Spalte `value`, damit Sie testen können, ohne eine Anfrage zu senden. Während der Ausführung füllt der Resolver sowohl `` als auch `` aus. +- **string** - Textwerte +- **number** - Numerische Werte +- **boolean** - Wahr/Falsch-Werte +- **json** - JSON-Objekte +- **files** - Datei-Uploads (Zugriff über ``, ``, usw.) + +Laufzeit-Ausgabeschlüssel spiegeln das Schema wider und sind unter `` verfügbar. + +Manuelle Ausführungen im Editor verwenden die Spalte `value`, damit du testen kannst, ohne eine Anfrage zu senden. Während der Ausführung füllt der Resolver sowohl `` als auch ``. ## Anfrage-Beispiel @@ -40,22 +48,22 @@ Erfolgreiche Antworten geben das serialisierte Ausführungsergebnis vom Executor ## Streaming-Antworten -Aktivieren Sie Echtzeit-Streaming, um Workflow-Ausgaben zu erhalten, während sie zeichen-für-zeichen generiert werden. Dies ist nützlich, um KI-Antworten progressiv für Benutzer anzuzeigen. +Aktiviere Echtzeit-Streaming, um Workflow-Ausgaben während der Generierung zeichenweise zu erhalten. Dies ist nützlich, um KI-Antworten progressiv für Benutzer anzuzeigen. -### Anfrageparameter +### Anfrage-Parameter -Fügen Sie diese Parameter hinzu, um Streaming zu aktivieren: +Füge diese Parameter hinzu, um Streaming zu aktivieren: -- `stream` - Auf `true` setzen, um Server-Sent Events (SSE) Streaming zu aktivieren +- `stream` - Setze auf `true`, um Server-Sent Events (SSE) Streaming zu aktivieren - `selectedOutputs` - Array von Block-Ausgaben zum Streamen (z.B. `["agent1.content"]`) ### Block-Ausgabeformat -Verwenden Sie das `blockName.attribute` Format, um anzugeben, welche Block-Ausgaben gestreamt werden sollen: -- Format: `"blockName.attribute"` (z.B. Wenn Sie den Inhalt des Agent 1-Blocks streamen möchten, würden Sie `"agent1.content"` verwenden) +Verwende das Format `blockName.attribute`, um anzugeben, welche Block-Ausgaben gestreamt werden sollen: +- Format: `"blockName.attribute"` (z.B. wenn du den Inhalt des Agent 1-Blocks streamen möchtest, würdest du `"agent1.content"` verwenden) - Blocknamen sind nicht case-sensitive und Leerzeichen werden ignoriert -### Beispielanfrage +### Beispiel-Anfrage ```bash curl -X POST \ @@ -86,44 +94,89 @@ data: [DONE] ``` Jedes Ereignis enthält: -- **Streaming-Chunks**: `{"blockId": "...", "chunk": "text"}` - Echtzeit-Text während er generiert wird -- **Abschlussereignis**: `{"event": "done", ...}` - Ausführungsmetadaten und vollständige Ergebnisse +- **Streaming-Chunks**: `{"blockId": "...", "chunk": "text"}` - Echtzeit-Text während der Generierung +- **Finales Ereignis**: `{"event": "done", ...}` - Ausführungsmetadaten und vollständige Ergebnisse - **Terminator**: `[DONE]` - Signalisiert das Ende des Streams ### Streaming mehrerer Blöcke Wenn `selectedOutputs` mehrere Blöcke enthält, zeigt jeder Chunk an, welcher Block ihn erzeugt hat: -```bash -curl -X POST \ - https://sim.ai/api/workflows/WORKFLOW_ID/execute \ - -H 'Content-Type: application/json' \ - -H 'X-API-Key: YOUR_KEY' \ - -d '{ - "message": "Process this request", - "stream": true, - "selectedOutputs": ["agent1.content", "agent2.content"] - }' +```json +{ + "type": "block", + "blockType": "text", + "text": "Dies ist ein Textblock" +} ``` -Das Feld `blockId` in jedem Chunk ermöglicht es Ihnen, die Ausgabe zum richtigen UI-Element zu leiten: +Das Feld `blockId` in jedem Chunk ermöglicht es, die Ausgabe an das richtige UI-Element zu leiten: +```json +{ + "type": "block", + "blockType": "code", + "text": "console.log('Hallo Welt');" +} ``` -data: {"blockId":"agent1-uuid","chunk":"Processing..."} -data: {"blockId":"agent2-uuid","chunk":"Analyzing..."} +## Ausgabe-Referenz + +| Referenz | Beschreibung | +|-----------|-------------| +| `` | Feld, das im Eingabeformat definiert ist | +| `` | Gesamter strukturierter Anforderungstext | -data: {"blockId":"agent1-uuid","chunk":" complete"} +### Datei-Upload-Format + +Die API akzeptiert Dateien in zwei Formaten: + +**1. Base64-kodierte Dateien** (empfohlen für SDKs): + +```json +{ + "files": [{ + "data": "iVBORw0KGgoAAAANSUhEUgAA...", + "name": "image.png", + "mime": "image/png" + }] +} ``` -## Ausgabereferenz +- Maximale Dateigröße: 20MB pro Datei +- Dateien werden in den Cloud-Speicher hochgeladen und in UserFile-Objekte mit allen Eigenschaften umgewandelt -| Referenz | Beschreibung | -|-----------|-------------| -| `` | Im Eingabeformat definiertes Feld | -| `` | Gesamter strukturierter Anfragekörper | +**2. Direkte URL-Referenzen**: + +```json +{ + "files": [{ + "url": "https://example.com/image.png", + "name": "image.png", + "mime": "image/png" + }] +} +``` + +- Die Datei wird nicht hochgeladen, die URL wird direkt weitergegeben +- Nützlich für die Referenzierung bestehender Dateien + +### Datei-Eigenschaften + +Für Dateien können alle Eigenschaften abgerufen werden: + +| Eigenschaft | Beschreibung | Typ | +|----------|-------------|------| +| `` | Signierte Download-URL | string | +| `` | Ursprünglicher Dateiname | string | +| `` | Dateigröße in Bytes | number | +| `` | MIME-Typ | string | +| `` | Upload-Zeitstempel (ISO 8601) | string | +| `` | URL-Ablaufzeitstempel (ISO 8601) | string | + +Für URL-referenzierte Dateien sind dieselben Eigenschaften verfügbar, mit Ausnahme von `uploadedAt` und `expiresAt`, da die Datei nicht in unseren Speicher hochgeladen wird. -Wenn kein Eingabeformat definiert ist, stellt der Executor das rohe JSON nur unter `` zur Verfügung. +Wenn kein Eingabeformat definiert ist, stellt der Executor nur das rohe JSON unter `` zur Verfügung. Ein Workflow kann nur einen API-Trigger enthalten. Veröffentlichen Sie nach Änderungen eine neue Bereitstellung, damit der Endpunkt aktuell bleibt. diff --git a/apps/docs/content/docs/de/triggers/chat.mdx b/apps/docs/content/docs/de/triggers/chat.mdx index 129054a819..2349fc229f 100644 --- a/apps/docs/content/docs/de/triggers/chat.mdx +++ b/apps/docs/content/docs/de/triggers/chat.mdx @@ -24,20 +24,31 @@ Der Chat-Auslöser erstellt eine Konversationsschnittstelle für Ihren Workflow. Der Auslöser schreibt drei Felder, auf die nachfolgende Blöcke verweisen können: -| Referenz | Beschreibung | -|-----------|-------------| -| `` | Neueste Benutzernachricht | -| `` | Konversations-Thread-ID | -| `` | Optionale hochgeladene Dateien | +| Referenz | Beschreibung | Typ | +|-----------|-------------|------| +| `` | Letzte Benutzernachricht | string | +| `` | Konversations-Thread-ID | string | +| `` | Optionale hochgeladene Dateien | files array | -Dateien enthalten `name`, `mimeType` und einen signierten Download `url`. +### Dateieigenschaften + +Zugriff auf einzelne Dateieigenschaften über Array-Indizierung: + +| Eigenschaft | Beschreibung | Typ | +|----------|-------------|------| +| `` | Signierte Download-URL | string | +| `` | Ursprünglicher Dateiname | string | +| `` | Dateigröße in Bytes | number | +| `` | MIME-Typ | string | +| `` | Upload-Zeitstempel (ISO 8601) | string | +| `` | URL-Ablaufzeitstempel (ISO 8601) | string | ## Nutzungshinweise -1. Fügen Sie einen Chat-Auslöser-Block pro Workflow hinzu. +1. Fügen Sie einen Chat-Trigger-Block pro Workflow hinzu. 2. Stellen Sie den Workflow im Chat-Modus bereit. -3. Teilen Sie den Bereitstellungslink – jede Antwort verwendet die Konversations-ID wieder, sodass der Workflow den Kontext beibehalten kann. +3. Teilen Sie den Bereitstellungslink – jede Antwort verwendet dieselbe Konversations-ID, damit der Workflow den Kontext beibehalten kann. -Der Builder blockiert mehrere Chat-Auslöser-Blöcke im selben Workflow. +Der Builder blockiert mehrere Chat-Trigger-Blöcke im selben Workflow. diff --git a/apps/docs/content/docs/es/blocks/guardrails.mdx b/apps/docs/content/docs/es/blocks/guardrails.mdx new file mode 100644 index 0000000000..e7a6e3cb87 --- /dev/null +++ b/apps/docs/content/docs/es/blocks/guardrails.mdx @@ -0,0 +1,317 @@ +--- +title: Barreras de protección +--- + +import { Callout } from 'fumadocs-ui/components/callout' +import { Step, Steps } from 'fumadocs-ui/components/steps' +import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Image } from '@/components/ui/image' +import { Video } from '@/components/ui/video' + +El bloque de Barreras de protección valida y protege tus flujos de trabajo de IA comprobando el contenido contra múltiples tipos de validación. Asegura la calidad de los datos, previene alucinaciones, detecta información personal identificable (PII) y aplica requisitos de formato antes de que el contenido avance por tu flujo de trabajo. + +
+ Bloque de Barreras de protección +
+ +## Descripción general + +El bloque de Barreras de protección te permite: + + + + Validar estructura JSON: Asegura que las salidas de LLM sean JSON válido antes de analizarlas + + + Coincidir con patrones Regex: Verifica que el contenido coincida con formatos específicos (correos electrónicos, números de teléfono, URLs, etc.) + + + Detectar alucinaciones: Utiliza puntuación RAG + LLM para validar las salidas de IA contra el contenido de la base de conocimientos + + + Detectar PII: Identifica y opcionalmente enmascara información personal identificable en más de 40 tipos de entidades + + + +## Tipos de validación + +### Validación JSON + +Valida que el contenido tenga un formato JSON adecuado. Perfecto para garantizar que las salidas estructuradas de LLM puedan analizarse de forma segura. + +**Casos de uso:** +- Validar respuestas JSON de bloques de Agente antes de analizarlas +- Asegurar que las cargas útiles de API estén correctamente formateadas +- Comprobar la integridad de datos estructurados + +**Salida:** +- `passed`: `true` si es JSON válido, `false` en caso contrario +- `error`: Mensaje de error si la validación falla (p. ej., "JSON no válido: Token inesperado...") + +### Validación Regex + +Comprueba si el contenido coincide con un patrón de expresión regular especificado. + +**Casos de uso:** +- Validar direcciones de correo electrónico +- Comprobar formatos de números de teléfono +- Verificar URLs o identificadores personalizados +- Aplicar patrones de texto específicos + +**Configuración:** +- **Patrón Regex**: La expresión regular para comparar (p. ej., `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}--- +title: Barreras de protección +--- + +import { Callout } from 'fumadocs-ui/components/callout' +import { Step, Steps } from 'fumadocs-ui/components/steps' +import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Image } from '@/components/ui/image' +import { Video } from '@/components/ui/video' + +El bloque de Barreras de protección valida y protege tus flujos de trabajo de IA comprobando el contenido contra múltiples tipos de validación. Asegura la calidad de los datos, previene alucinaciones, detecta información personal identificable (PII) y aplica requisitos de formato antes de que el contenido avance por tu flujo de trabajo. + +
+ Bloque de Barreras de protección +
+ +## Descripción general + +El bloque de Barreras de protección te permite: + + + + Validar estructura JSON: Asegura que las salidas de LLM sean JSON válido antes de analizarlas + + + Coincidir con patrones Regex: Verifica que el contenido coincida con formatos específicos (correos electrónicos, números de teléfono, URLs, etc.) + + + Detectar alucinaciones: Utiliza puntuación RAG + LLM para validar las salidas de IA contra el contenido de la base de conocimientos + + + Detectar PII: Identifica y opcionalmente enmascara información personal identificable en más de 40 tipos de entidades + + + +## Tipos de validación + +### Validación JSON + +Valida que el contenido tenga un formato JSON adecuado. Perfecto para garantizar que las salidas estructuradas de LLM puedan analizarse de forma segura. + +**Casos de uso:** +- Validar respuestas JSON de bloques de Agente antes de analizarlas +- Asegurar que las cargas útiles de API estén correctamente formateadas +- Comprobar la integridad de datos estructurados + +**Salida:** +- `passed`: `true` si es JSON válido, `false` en caso contrario +- `error`: Mensaje de error si la validación falla (p. ej., "JSON no válido: Token inesperado...") + +### Validación Regex + +Comprueba si el contenido coincide con un patrón de expresión regular especificado. + +**Casos de uso:** +- Validar direcciones de correo electrónico +- Comprobar formatos de números de teléfono +- Verificar URLs o identificadores personalizados +- Aplicar patrones de texto específicos + +**Configuración:** +- **Patrón Regex**: La expresión regular para comparar (p. ej., para correos electrónicos) + +**Resultado:** +- `passed`: `true` si el contenido coincide con el patrón, `false` en caso contrario +- `error`: Mensaje de error si la validación falla + +### Detección de alucinaciones + +Utiliza generación aumentada por recuperación (RAG) con puntuación de LLM para detectar cuando el contenido generado por IA contradice o no está fundamentado en tu base de conocimientos. + +**Cómo funciona:** +1. Consulta tu base de conocimientos para obtener contexto relevante +2. Envía tanto la salida de la IA como el contexto recuperado a un LLM +3. El LLM asigna una puntuación de confianza (escala de 0-10) + - **0** = Alucinación completa (totalmente sin fundamento) + - **10** = Completamente fundamentado (totalmente respaldado por la base de conocimientos) +4. La validación se aprueba si la puntuación ≥ umbral (predeterminado: 3) + +**Configuración:** +- **Base de conocimientos**: Selecciona entre tus bases de conocimientos existentes +- **Modelo**: Elige LLM para la puntuación (requiere razonamiento sólido - se recomienda GPT-4o, Claude 3.7 Sonnet) +- **Clave API**: Autenticación para el proveedor de LLM seleccionado (se oculta automáticamente para modelos alojados/Ollama) +- **Umbral de confianza**: Puntuación mínima para aprobar (0-10, predeterminado: 3) +- **Top K** (Avanzado): Número de fragmentos de la base de conocimientos a recuperar (predeterminado: 10) + +**Resultado:** +- `passed`: `true` si la puntuación de confianza ≥ umbral +- `score`: Puntuación de confianza (0-10) +- `reasoning`: Explicación del LLM para la puntuación +- `error`: Mensaje de error si la validación falla + +**Casos de uso:** +- Validar respuestas de agentes contra documentación +- Asegurar que las respuestas de atención al cliente sean precisas +- Verificar que el contenido generado coincida con el material de origen +- Control de calidad para aplicaciones RAG + +### Detección de PII + +Detecta información de identificación personal utilizando Microsoft Presidio. Compatible con más de 40 tipos de entidades en múltiples países e idiomas. + +
+
+ +**Cómo funciona:** +1. Escanea el contenido en busca de entidades PII mediante coincidencia de patrones y PNL +2. Devuelve las entidades detectadas con ubicaciones y puntuaciones de confianza +3. Opcionalmente enmascara el PII detectado en el resultado + +**Configuración:** +- **Tipos de PII a detectar**: Seleccione de categorías agrupadas mediante selector modal + - **Común**: Nombre de persona, Correo electrónico, Teléfono, Tarjeta de crédito, Dirección IP, etc. + - **EE.UU.**: SSN, Licencia de conducir, Pasaporte, etc. + - **Reino Unido**: Número NHS, Número de seguro nacional + - **España**: NIF, NIE, CIF + - **Italia**: Código fiscal, Licencia de conducir, Código de IVA + - **Polonia**: PESEL, NIP, REGON + - **Singapur**: NRIC/FIN, UEN + - **Australia**: ABN, ACN, TFN, Medicare + - **India**: Aadhaar, PAN, Pasaporte, Número de votante +- **Modo**: + - **Detectar**: Solo identifica PII (predeterminado) + - **Enmascarar**: Reemplaza PII detectada con valores enmascarados +- **Idioma**: Idioma de detección (predeterminado: inglés) + +**Salida:** +- `passed`: `false` si se detectan los tipos de PII seleccionados +- `detectedEntities`: Array de PII detectada con tipo, ubicación y confianza +- `maskedText`: Contenido con PII enmascarada (solo si modo = "Mask") +- `error`: Mensaje de error si la validación falla + +**Casos de uso:** +- Bloquear contenido que contiene información personal sensible +- Enmascarar PII antes de registrar o almacenar datos +- Cumplimiento con GDPR, HIPAA y otras regulaciones de privacidad +- Sanear entradas de usuario antes del procesamiento + +## Configuración + +### Contenido a validar + +El contenido de entrada para validar. Esto típicamente proviene de: +- Salidas de bloques de agente: `` +- Resultados de bloques de función: `` +- Respuestas de API: `` +- Cualquier otra salida de bloque + +### Tipo de validación + +Elija entre cuatro tipos de validación: +- **JSON válido**: Comprueba si el contenido es JSON correctamente formateado +- **Coincidencia Regex**: Verifica si el contenido coincide con un patrón regex +- **Comprobación de alucinación**: Valida contra base de conocimiento con puntuación LLM +- **Detección de PII**: Detecta y opcionalmente enmascara información de identificación personal + +## Salidas + +Todos los tipos de validación devuelven: + +- **``**: Booleano que indica si la validación ha sido exitosa +- **``**: El tipo de validación realizada +- **``**: La entrada original que fue validada +- **``**: Mensaje de error si la validación falló (opcional) + +Salidas adicionales por tipo: + +**Verificación de alucinaciones:** +- **``**: Puntuación de confianza (0-10) +- **``**: Explicación del LLM + +**Detección de PII:** +- **``**: Array de entidades PII detectadas +- **``**: Contenido con PII enmascarado (si el modo = "Mask") + +## Ejemplos de casos de uso + +### Validar JSON antes de analizarlo + +
+

Escenario: asegurar que la salida del agente es JSON válido

+
    +
  1. El agente genera una respuesta JSON estructurada
  2. +
  3. Guardrails valida el formato JSON
  4. +
  5. El bloque de condición verifica ``
  6. +
  7. Si pasa → analizar y usar datos, si falla → reintentar o manejar el error
  8. +
+
+ +### Prevenir alucinaciones + +
+

Escenario: validar respuestas de atención al cliente

+
    +
  1. El agente genera una respuesta a la pregunta del cliente
  2. +
  3. Guardrails verifica contra la base de conocimiento de documentación de soporte
  4. +
  5. Si la puntuación de confianza ≥ 3 → enviar respuesta
  6. +
  7. Si la puntuación de confianza \< 3 → marcar para revisión humana
  8. +
+
+ +### Bloquear PII en entradas de usuario + +
+

Escenario: sanear contenido enviado por usuarios

+
    +
  1. El usuario envía un formulario con contenido de texto
  2. +
  3. Guardrails detecta PII (correos electrónicos, números de teléfono, SSN, etc.)
  4. +
  5. Si se detecta PII → rechazar el envío o enmascarar datos sensibles
  6. +
  7. Si no hay PII → procesar normalmente
  8. +
+
+ +
+
+ +### Validar formato de correo electrónico + +
+

Escenario: comprobar el formato de dirección de correo electrónico

+
    +
  1. El agente extrae el correo electrónico del texto
  2. +
  3. Guardrails valida con un patrón regex
  4. +
  5. Si es válido → usar el correo electrónico para notificación
  6. +
  7. Si no es válido → solicitar corrección
  8. +
+
+ +## Mejores prácticas + +- **Encadena con bloques de Condición**: Utiliza `` para ramificar la lógica del flujo de trabajo según los resultados de validación +- **Usa validación JSON antes de analizar**: Siempre valida la estructura JSON antes de intentar analizar las salidas de LLM +- **Elige los tipos de PII apropiados**: Selecciona solo los tipos de entidades PII relevantes para tu caso de uso para un mejor rendimiento +- **Establece umbrales de confianza razonables**: Para la detección de alucinaciones, ajusta el umbral según tus requisitos de precisión (más alto = más estricto) +- **Usa modelos potentes para la detección de alucinaciones**: GPT-4o o Claude 3.7 Sonnet proporcionan una puntuación de confianza más precisa +- **Enmascara PII para el registro**: Usa el modo "Mask" cuando necesites registrar o almacenar contenido que pueda contener PII +- **Prueba patrones regex**: Valida tus patrones de expresiones regulares minuciosamente antes de implementarlos en producción +- **Monitorea los fallos de validación**: Rastrea los mensajes `` para identificar problemas comunes de validación + + + La validación de Guardrails ocurre de forma sincrónica en tu flujo de trabajo. Para la detección de alucinaciones, elige modelos más rápidos (como GPT-4o-mini) si la latencia es crítica. + diff --git a/apps/docs/content/docs/es/execution/costs.mdx b/apps/docs/content/docs/es/execution/costs.mdx index 78daf6600b..40468da241 100644 --- a/apps/docs/content/docs/es/execution/costs.mdx +++ b/apps/docs/content/docs/es/execution/costs.mdx @@ -170,17 +170,49 @@ Los diferentes planes de suscripción tienen diferentes límites de uso: | **Equipo** | $500 (agrupado) | 50 síncronos, 100 asíncronos | | **Empresa** | Personalizado | Personalizado | +## Modelo de facturación + +Sim utiliza un modelo de facturación de **suscripción base + excedente**: + +### Cómo funciona + +**Plan Pro (20$/mes):** +- La suscripción mensual incluye 20$ de uso +- Uso por debajo de 20$ → Sin cargos adicionales +- Uso por encima de 20$ → Paga el excedente al final del mes +- Ejemplo: 35$ de uso = 20$ (suscripción) + 15$ (excedente) + +**Plan Team (40$/usuario/mes):** +- Uso compartido entre todos los miembros del equipo +- El excedente se calcula a partir del uso total del equipo +- El propietario de la organización recibe una única factura + +**Planes Enterprise:** +- Precio mensual fijo, sin excedentes +- Límites de uso personalizados según el acuerdo + +### Facturación por umbrales + +Cuando el excedente no facturado alcanza los 50$, Sim factura automáticamente el importe total no facturado. + +**Ejemplo:** +- Día 10: 70$ de excedente → Factura inmediata de 70$ +- Día 15: 35$ adicionales de uso (105$ en total) → Ya facturado, sin acción +- Día 20: Otros 50$ de uso (155$ en total, 85$ sin facturar) → Factura inmediata de 85$ + +Esto distribuye los cargos grandes por excedente a lo largo del mes en lugar de una factura grande al final del período. + ## Mejores prácticas para la gestión de costos -1. **Monitorear regularmente**: Revisa tu panel de uso frecuentemente para evitar sorpresas -2. **Establecer presupuestos**: Utiliza los límites del plan como guías para tu gasto -3. **Optimizar flujos de trabajo**: Revisa las ejecuciones de alto costo y optimiza los prompts o la selección de modelos -4. **Usar modelos apropiados**: Ajusta la complejidad del modelo a los requisitos de la tarea -5. **Agrupar tareas similares**: Combina múltiples solicitudes cuando sea posible para reducir la sobrecarga +1. **Monitoreo regular**: Revisa tu panel de uso con frecuencia para evitar sorpresas +2. **Establece presupuestos**: Utiliza los límites del plan como guía para tu gasto +3. **Optimiza flujos de trabajo**: Revisa las ejecuciones de alto costo y optimiza los prompts o la selección de modelos +4. **Usa modelos apropiados**: Ajusta la complejidad del modelo a los requisitos de la tarea +5. **Agrupa tareas similares**: Combina múltiples solicitudes cuando sea posible para reducir la sobrecarga ## Próximos pasos - Revisa tu uso actual en [Configuración → Suscripción](https://sim.ai/settings/subscription) - Aprende sobre [Registro](/execution/logging) para seguir los detalles de ejecución -- Explora la [API externa](/execution/api) para monitoreo programático de costos +- Explora la [API externa](/execution/api) para el monitoreo programático de costos - Consulta las [técnicas de optimización de flujo de trabajo](/blocks) para reducir costos \ No newline at end of file diff --git a/apps/docs/content/docs/es/sdks/python.mdx b/apps/docs/content/docs/es/sdks/python.mdx index 2edb110394..75b4f3777a 100644 --- a/apps/docs/content/docs/es/sdks/python.mdx +++ b/apps/docs/content/docs/es/sdks/python.mdx @@ -609,7 +609,7 @@ Ejecuta flujos de trabajo con respuestas en tiempo real: from simstudio import SimStudioClient import os -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) +client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) def execute_with_streaming(): """Execute workflow with streaming enabled.""" diff --git a/apps/docs/content/docs/es/sdks/typescript.mdx b/apps/docs/content/docs/es/sdks/typescript.mdx index fca8a9805f..20c589abff 100644 --- a/apps/docs/content/docs/es/sdks/typescript.mdx +++ b/apps/docs/content/docs/es/sdks/typescript.mdx @@ -604,28 +604,114 @@ async function executeClientSideWorkflow() { }); console.log('Workflow result:', result); - + // Update UI with result - document.getElementById('result')!.textContent = + document.getElementById('result')!.textContent = JSON.stringify(result.output, null, 2); } catch (error) { console.error('Error:', error); } } +``` + +### Carga de archivos + +Los objetos de archivo se detectan automáticamente y se convierten a formato base64. Inclúyelos en tu entrada bajo el nombre de campo que coincida con el formato de entrada del disparador API de tu flujo de trabajo. + +El SDK convierte los objetos File a este formato: + +```typescript +{ + type: 'file', + data: 'data:mime/type;base64,base64data', + name: 'filename', + mime: 'mime/type' +} +``` + +Alternativamente, puedes proporcionar archivos manualmente usando el formato URL: + +```typescript +{ + type: 'url', + data: 'https://example.com/file.pdf', + name: 'file.pdf', + mime: 'application/pdf' +} +``` -// Attach to button click + + + + ```typescript + import { SimStudioClient } from 'simstudio-ts-sdk'; + + const client = new SimStudioClient({ + apiKey: process.env.NEXT_PUBLIC_SIM_API_KEY! + }); + + // From file input + async function handleFileUpload(event: Event) { + const input = event.target as HTMLInputElement; + const files = Array.from(input.files || []); + + // Include files under the field name from your API trigger's input format + const result = await client.executeWorkflow('workflow-id', { + input: { + documents: files, // Must match your workflow's "files" field name + instructions: 'Analyze these documents' + } + }); + + console.log('Result:', result); + } + ``` + + + + + ```typescript + import { SimStudioClient } from 'simstudio-ts-sdk'; + import fs from 'fs'; + + const client = new SimStudioClient({ + apiKey: process.env.SIM_API_KEY! + }); + + // Read file and create File object + const fileBuffer = fs.readFileSync('./document.pdf'); + const file = new File([fileBuffer], 'document.pdf', { + type: 'application/pdf' + }); + + // Include files under the field name from your API trigger's input format + const result = await client.executeWorkflow('workflow-id', { + input: { + documents: [file], // Must match your workflow's "files" field name + query: 'Summarize this document' + } + }); + ``` + + + + +// Adjuntar al clic del botón document.getElementById('executeBtn')?.addEventListener('click', executeClientSideWorkflow); + ``` - Cuando uses el SDK en el navegador, ten cuidado de no exponer claves API sensibles. Considera usar un proxy de backend o claves API públicas con permisos limitados. + When using the SDK in the browser, be careful not to expose sensitive API keys. Consider using a backend proxy or public API keys with limited permissions. -### Ejemplo de hook de React +### React Hook Example -Crea un hook personalizado de React para la ejecución de flujos de trabajo: +Create a custom React hook for workflow execution: -```typescript +``` + +typescript import { useState, useCallback } from 'react'; import { SimStudioClient, WorkflowExecutionResult } from 'simstudio-ts-sdk'; @@ -671,7 +757,7 @@ export function useWorkflow(): UseWorkflowResult { }; } -// Usage in component +// Uso en componente function WorkflowComponent() { const { result, loading, error, executeWorkflow } = useWorkflow(); @@ -684,26 +770,29 @@ function WorkflowComponent() { return (
{error &&
Error: {error.message}
} {result && (
-

Result:

+

Resultado:

{JSON.stringify(result, null, 2)}
)}
); } + ``` -### Ejecución asíncrona de flujos de trabajo +### Async Workflow Execution -Ejecuta flujos de trabajo de forma asíncrona para tareas de larga duración: +Execute workflows asynchronously for long-running tasks: -```typescript +``` + +typescript import { SimStudioClient, AsyncExecutionResult } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -712,32 +801,32 @@ const client = new SimStudioClient({ async function executeAsync() { try { - // Start async execution + // Iniciar ejecución asíncrona const result = await client.executeWorkflow('workflow-id', { input: { data: 'large dataset' }, - async: true // Execute asynchronously + async: true // Ejecutar de forma asíncrona }); - // Check if result is an async execution + // Comprobar si el resultado es una ejecución asíncrona if ('taskId' in result) { - console.log('Task ID:', result.taskId); - console.log('Status endpoint:', result.links.status); + console.log('ID de tarea:', result.taskId); + console.log('Endpoint de estado:', result.links.status); - // Poll for completion + // Sondear hasta completar let status = await client.getJobStatus(result.taskId); while (status.status === 'queued' || status.status === 'processing') { - console.log('Current status:', status.status); - await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds + console.log('Estado actual:', status.status); + await new Promise(resolve => setTimeout(resolve, 2000)); // Esperar 2 segundos status = await client.getJobStatus(result.taskId); } if (status.status === 'completed') { - console.log('Workflow completed!'); - console.log('Output:', status.output); - console.log('Duration:', status.metadata.duration); + console.log('¡Flujo de trabajo completado!'); + console.log('Salida:', status.output); + console.log('Duración:', status.metadata.duration); } else { - console.error('Workflow failed:', status.error); + console.error('Flujo de trabajo fallido:', status.error); } } } catch (error) { @@ -746,13 +835,16 @@ async function executeAsync() { } executeAsync(); + ``` -### Límite de tasa y reintentos +### Rate Limiting and Retry -Maneja límites de tasa automáticamente con retroceso exponencial: +Handle rate limits automatically with exponential backoff: -```typescript +``` + +typescript import { SimStudioClient, SimStudioError } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -761,7 +853,7 @@ const client = new SimStudioClient({ async function executeWithRetryHandling() { try { - // Automatically retries on rate limit + // Reintenta automáticamente en caso de límite de tasa const result = await client.executeWithRetry('workflow-id', { input: { message: 'Process this' } }, { @@ -771,26 +863,29 @@ async function executeWithRetryHandling() { backoffMultiplier: 2 }); - console.log('Success:', result); + console.log('Éxito:', result); } catch (error) { if (error instanceof SimStudioError && error.code === 'RATE_LIMIT_EXCEEDED') { - console.error('Rate limit exceeded after all retries'); + console.error('Límite de tasa excedido después de todos los reintentos'); - // Check rate limit info + // Verificar información del límite de tasa const rateLimitInfo = client.getRateLimitInfo(); if (rateLimitInfo) { - console.log('Rate limit resets at:', new Date(rateLimitInfo.reset * 1000)); + console.log('El límite de tasa se restablece en:', new Date(rateLimitInfo.reset * 1000)); } } } } + ``` -### Monitoreo de uso +### Usage Monitoring -Monitorea el uso de tu cuenta y sus límites: +Monitor your account usage and limits: -```typescript +``` + +typescript import { SimStudioClient } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -801,27 +896,46 @@ async function checkUsage() { try { const limits = await client.getUsageLimits(); - console.log('=== Rate Limits ==='); - console.log('Sync requests:'); - console.log(' Limit:', limits.rateLimit.sync.limit); - console.log(' Remaining:', limits.rateLimit.sync.remaining); - console.log(' Resets at:', limits.rateLimit.sync.resetAt); - console.log(' Is limited:', limits.rateLimit.sync.isLimited); + console.log('=== Límites de tasa ==='); + console.log('Solicitudes síncronas:'); + console.log(' Límite:', limits.rateLimit.sync.limit); + console.log(' Restantes:', limits.rateLimit.sync.remaining); + console.log(' Se restablece en:', limits.rateLimit.sync.resetAt); + console.log(' Está limitado:', limits.rateLimit.sync.isLimited); + + console.log('\nSolicitudes asíncronas:'); + console.log(' Límite:', limits.rateLimit.async.limit); + console.log(' Restantes:', limits.rateLimit.async.remaining); + console.log(' Se restablece en:', limits.rateLimit.async.resetAt); + console.log(' Está limitado:', limits.rateLimit.async.isLimited); + + console.log('\n=== Uso ==='); + console.log('Costo del período actual: $' + limits.usage.currentPeriodCost.toFixed(2)); + console.log('Límite: $' + limits.usage.limit.toFixed(2)); + console.log('Plan:', limits.usage.plan); + + const percentUsed = (limits.usage.currentPeriodCost / limits.usage.limit) * 100; + console.log('Uso: ' + percentUsed.toFixed(1) + '%'); + + if (percentUsed > 80) { + console.warn('⚠️ Advertencia: ¡Estás acercándote a tu límite de uso!'); + } + } catch (error) { + console.error('Error al verificar el uso:', error); + } +} - console.log('\nAsync requests:'); - console.log(' Limit:', limits.rateLimit.async.limit); - console.log(' Remaining:', limits.rateLimit.async.remaining); - console.log(' Resets at:', limits.rateLimit.async.resetAt); - console.log(' Is limited:', limits.rateLimit.async.isLimited); +checkUsage(); - console.log('\n=== Usage ==='); - console.log('Current period cost: +``` ### Streaming Workflow Execution Execute workflows with real-time streaming responses: -```typescript +``` + +typescript import { SimStudioClient } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -830,11 +944,11 @@ const client = new SimStudioClient({ async function executeWithStreaming() { try { - // Habilita streaming para salidas de bloques específicos + // Habilitar streaming para salidas de bloques específicos const result = await client.executeWorkflow('workflow-id', { - input: { message: 'Count to five' }, + input: { message: 'Cuenta hasta cinco' }, stream: true, - selectedOutputs: ['agent1.content'] // Usa el formato blockName.attribute + selectedOutputs: ['agent1.content'] // Usar formato blockName.attribute }); console.log('Resultado del flujo de trabajo:', result); @@ -842,23 +956,28 @@ async function executeWithStreaming() { console.error('Error:', error); } } + ``` The streaming response follows the Server-Sent Events (SSE) format: ``` -data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":"One"} + +data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":"Uno"} data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":", dos"} data: {"event":"done","success":true,"output":{},"metadata":{"duration":610}} data: [DONE] + ``` **React Streaming Example:** -```typescript +``` + +typescript import { useState, useEffect } from 'react'; function StreamingWorkflow() { @@ -869,16 +988,16 @@ function StreamingWorkflow() { setLoading(true); setOutput(''); - // IMPORTANT: Make this API call from your backend server, not the browser - // Never expose your API key in client-side code + // IMPORTANTE: Haz esta llamada API desde tu servidor backend, no desde el navegador + // Nunca expongas tu clave API en código del lado del cliente const response = await fetch('https://sim.ai/api/workflows/WORKFLOW_ID/execute', { method: 'POST', headers: { 'Content-Type': 'application/json', - 'X-API-Key': process.env.SIM_API_KEY! // Server-side environment variable only + 'X-API-Key': process.env.SIM_API_KEY! // Variable de entorno solo del lado del servidor }, body: JSON.stringify({ - message: 'Generate a story', + message: 'Genera una historia', stream: true, selectedOutputs: ['agent1.content'] }) @@ -907,10 +1026,10 @@ function StreamingWorkflow() { if (parsed.chunk) { setOutput(prev => prev + parsed.chunk); } else if (parsed.event === 'done') { - console.log('Execution complete:', parsed.metadata); + console.log('Ejecución completa:', parsed.metadata); } } catch (e) { - // Skip invalid JSON + // Omitir JSON inválido } } } @@ -926,6 +1045,7 @@ function StreamingWorkflow() { ); } + ``` ## Getting Your API Key @@ -961,7 +1081,9 @@ function StreamingWorkflow() { The SDK is written in TypeScript and provides full type safety: -```typescript +``` + +typescript import { SimStudioClient, WorkflowExecutionResult, @@ -969,23 +1091,22 @@ import { SimStudioError } from 'simstudio-ts-sdk'; -// Type-safe client initialization +// Inicialización del cliente con seguridad de tipos const client: SimStudioClient = new SimStudioClient({ apiKey: process.env.SIM_API_KEY! }); -// Type-safe workflow execution +// Ejecución de flujo de trabajo con seguridad de tipos const result: WorkflowExecutionResult = await client.executeWorkflow('workflow-id', { input: { message: '¡Hola, TypeScript!' } }); -// Type-safe status checking +// Verificación de estado con seguridad de tipos const status: WorkflowStatus = await client.getWorkflowStatus('workflow-id'); ``` -## License - +## Licencia Apache-2.0 diff --git a/apps/docs/content/docs/es/triggers/api.mdx b/apps/docs/content/docs/es/triggers/api.mdx index 09ecda8971..ee6acbeb4e 100644 --- a/apps/docs/content/docs/es/triggers/api.mdx +++ b/apps/docs/content/docs/es/triggers/api.mdx @@ -22,9 +22,17 @@ El disparador de API expone tu flujo de trabajo como un punto de conexión HTTP /> -Añade un campo de **Formato de entrada** para cada parámetro. Las claves de salida en tiempo de ejecución reflejan el esquema y también están disponibles bajo ``. +Añade un campo de **Formato de entrada** para cada parámetro. Tipos admitidos: -Las ejecuciones manuales en el editor utilizan la columna `value` para que puedas realizar pruebas sin enviar una solicitud. Durante la ejecución, el resolutor completa tanto `` como ``. +- **string** - Valores de texto +- **number** - Valores numéricos +- **boolean** - Valores verdadero/falso +- **json** - Objetos JSON +- **files** - Carga de archivos (acceso mediante ``, ``, etc.) + +Las claves de salida en tiempo de ejecución reflejan el esquema y están disponibles bajo ``. + +Las ejecuciones manuales en el editor utilizan la columna `value` para que puedas realizar pruebas sin enviar una solicitud. Durante la ejecución, el resolutor completa tanto `` como ``. ## Ejemplo de solicitud @@ -40,7 +48,7 @@ Las respuestas exitosas devuelven el resultado de ejecución serializado del Eje ## Respuestas en streaming -Habilita el streaming en tiempo real para recibir la salida del flujo de trabajo a medida que se genera, carácter por carácter. Esto es útil para mostrar las respuestas de IA progresivamente a los usuarios. +Habilita el streaming en tiempo real para recibir la salida del flujo de trabajo a medida que se genera, carácter por carácter. Esto es útil para mostrar respuestas de IA progresivamente a los usuarios. ### Parámetros de solicitud @@ -51,7 +59,7 @@ Añade estos parámetros para habilitar el streaming: ### Formato de salida de bloque -Usa el formato `blockName.attribute` para especificar qué salidas de bloques transmitir: +Utiliza el formato `blockName.attribute` para especificar qué salidas de bloque transmitir: - Formato: `"blockName.attribute"` (p. ej., si quieres transmitir el contenido del bloque Agente 1, usarías `"agent1.content"`) - Los nombres de los bloques no distinguen entre mayúsculas y minúsculas y se ignoran los espacios @@ -86,34 +94,31 @@ data: [DONE] ``` Cada evento incluye: -- **Fragmentos de streaming**: `{"blockId": "...", "chunk": "text"}` - Texto en tiempo real a medida que se genera +- **Fragmentos en streaming**: `{"blockId": "...", "chunk": "text"}` - Texto en tiempo real a medida que se genera - **Evento final**: `{"event": "done", ...}` - Metadatos de ejecución y resultados completos -- **Terminador**: `[DONE]` - Señala el fin del stream +- **Terminador**: `[DONE]` - Indica el final del stream ### Streaming de múltiples bloques Cuando `selectedOutputs` incluye múltiples bloques, cada fragmento indica qué bloque lo produjo: -```bash -curl -X POST \ - https://sim.ai/api/workflows/WORKFLOW_ID/execute \ - -H 'Content-Type: application/json' \ - -H 'X-API-Key: YOUR_KEY' \ - -d '{ - "message": "Process this request", - "stream": true, - "selectedOutputs": ["agent1.content", "agent2.content"] - }' -``` - -El campo `blockId` en cada fragmento te permite dirigir la salida al elemento de UI correcto: - +```json +{ + "type": "block", + "blockType": "text", + "text": "Este es un bloque de texto" +} ``` -data: {"blockId":"agent1-uuid","chunk":"Processing..."} -data: {"blockId":"agent2-uuid","chunk":"Analyzing..."} +El campo `blockId` en cada fragmento te permite dirigir la salida al elemento de interfaz correcto: -data: {"blockId":"agent1-uuid","chunk":" complete"} +```json +{ + "type": "block", + "blockType": "code", + "text": "console.log('Hola mundo');", + "language": "javascript" +} ``` ## Referencia de salida @@ -121,10 +126,56 @@ data: {"blockId":"agent1-uuid","chunk":" complete"} | Referencia | Descripción | |-----------|-------------| | `` | Campo definido en el formato de entrada | -| `` | Cuerpo de solicitud estructurado completo | +| `` | Cuerpo completo de la solicitud estructurada | + +### Formato de carga de archivos + +La API acepta archivos en dos formatos: + +**1. Archivos codificados en Base64** (recomendado para SDKs): + +```json +{ + "files": [{ + "name": "example.pdf", + "data": "JVBERi0xLjMKJcTl8uXrp..." + }] +} +``` + +- Tamaño máximo de archivo: 20MB por archivo +- Los archivos se suben al almacenamiento en la nube y se convierten en objetos UserFile con todas las propiedades + +**2. Referencias directas de URL**: + +```json +{ + "files": [{ + "url": "https://example.com/file.pdf" + }] +} +``` + +- El archivo no se sube, la URL se pasa directamente +- Útil para referenciar archivos existentes + +### Propiedades de archivos + +Para archivos, accede a todas las propiedades: + +| Propiedad | Descripción | Tipo | +|----------|-------------|------| +| `` | URL de descarga firmada | string | +| `` | Nombre original del archivo | string | +| `` | Tamaño del archivo en bytes | number | +| `` | Tipo MIME | string | +| `` | Marca de tiempo de carga (ISO 8601) | string | +| `` | Marca de tiempo de caducidad de URL (ISO 8601) | string | + +Para archivos referenciados por URL, las mismas propiedades están disponibles excepto `uploadedAt` y `expiresAt` ya que el archivo no se sube a nuestro almacenamiento. Si no se define un formato de entrada, el ejecutor expone el JSON sin procesar solo en ``. -Un flujo de trabajo puede contener solo un disparador de API. Publica una nueva implementación después de los cambios para que el endpoint se mantenga actualizado. +Un flujo de trabajo solo puede contener un disparador de API. Publica una nueva implementación después de los cambios para que el punto de conexión se mantenga actualizado. diff --git a/apps/docs/content/docs/es/triggers/chat.mdx b/apps/docs/content/docs/es/triggers/chat.mdx index bfe4da9a7f..000926af9d 100644 --- a/apps/docs/content/docs/es/triggers/chat.mdx +++ b/apps/docs/content/docs/es/triggers/chat.mdx @@ -24,20 +24,31 @@ El disparador de Chat crea una interfaz conversacional para tu flujo de trabajo. El disparador escribe tres campos que los bloques posteriores pueden referenciar: -| Referencia | Descripción | -|-----------|-------------| -| `` | Último mensaje del usuario | -| `` | ID del hilo de conversación | -| `` | Archivos subidos opcionales | +| Referencia | Descripción | Tipo | +|-----------|-------------|------| +| `` | Último mensaje del usuario | string | +| `` | ID del hilo de conversación | string | +| `` | Archivos subidos opcionales | array de archivos | -Los archivos incluyen `name`, `mimeType`, y una descarga firmada `url`. +### Propiedades de archivo + +Accede a las propiedades individuales de los archivos usando indexación de arrays: + +| Propiedad | Descripción | Tipo | +|----------|-------------|------| +| `` | URL de descarga firmada | string | +| `` | Nombre original del archivo | string | +| `` | Tamaño del archivo en bytes | number | +| `` | Tipo MIME | string | +| `` | Marca de tiempo de subida (ISO 8601) | string | +| `` | Marca de tiempo de caducidad de la URL (ISO 8601) | string | ## Notas de uso -1. Añade un bloque de Disparador de Chat por flujo de trabajo. +1. Añade un bloque de Chat Trigger por flujo de trabajo. 2. Despliega el flujo de trabajo en modo chat. 3. Comparte el enlace de despliegue—cada respuesta reutiliza el ID de conversación para que el flujo de trabajo pueda mantener el contexto. -El constructor bloquea múltiples bloques de Disparador de Chat en el mismo flujo de trabajo. +El constructor bloquea múltiples bloques de Chat Trigger en el mismo flujo de trabajo. diff --git a/apps/docs/content/docs/fr/blocks/guardrails.mdx b/apps/docs/content/docs/fr/blocks/guardrails.mdx new file mode 100644 index 0000000000..0b0f0e33d7 --- /dev/null +++ b/apps/docs/content/docs/fr/blocks/guardrails.mdx @@ -0,0 +1,317 @@ +--- +title: Guardrails +--- + +import { Callout } from 'fumadocs-ui/components/callout' +import { Step, Steps } from 'fumadocs-ui/components/steps' +import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Image } from '@/components/ui/image' +import { Video } from '@/components/ui/video' + +Le bloc Guardrails valide et protège vos flux de travail IA en vérifiant le contenu selon plusieurs types de validation. Assurez la qualité des données, prévenez les hallucinations, détectez les PII et imposez des exigences de format avant que le contenu ne progresse dans votre flux de travail. + +
+ Bloc Guardrails +
+ +## Aperçu + +Le bloc Guardrails vous permet de : + + + + Valider la structure JSON : garantir que les sorties LLM sont en JSON valide avant l'analyse + + + Faire correspondre des modèles Regex : vérifier que le contenu correspond à des formats spécifiques (e-mails, numéros de téléphone, URL, etc.) + + + Détecter les hallucinations : utiliser le scoring RAG + LLM pour valider les sorties IA par rapport au contenu de la base de connaissances + + + Détecter les PII : identifier et éventuellement masquer les informations personnellement identifiables à travers plus de 40 types d'entités + + + +## Types de validation + +### Validation JSON + +Vérifie que le contenu est correctement formaté en JSON. Parfait pour s'assurer que les sorties LLM structurées peuvent être analysées en toute sécurité. + +**Cas d'utilisation :** +- Valider les réponses JSON des blocs Agent avant l'analyse +- S'assurer que les charges utiles API sont correctement formatées +- Vérifier l'intégrité des données structurées + +**Sortie :** +- `passed` : `true` si JSON valide, `false` sinon +- `error` : message d'erreur si la validation échoue (par ex., "JSON invalide : jeton inattendu...") + +### Validation Regex + +Vérifie si le contenu correspond à un modèle d'expression régulière spécifié. + +**Cas d'utilisation :** +- Valider les adresses e-mail +- Vérifier les formats de numéros de téléphone +- Vérifier les URL ou identifiants personnalisés +- Imposer des modèles de texte spécifiques + +**Configuration :** +- **Modèle Regex** : l'expression régulière à faire correspondre (par ex., `^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}--- +title: Guardrails +--- + +import { Callout } from 'fumadocs-ui/components/callout' +import { Step, Steps } from 'fumadocs-ui/components/steps' +import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Image } from '@/components/ui/image' +import { Video } from '@/components/ui/video' + +Le bloc Guardrails valide et protège vos flux de travail IA en vérifiant le contenu selon plusieurs types de validation. Assurez la qualité des données, prévenez les hallucinations, détectez les PII et imposez des exigences de format avant que le contenu ne progresse dans votre flux de travail. + +
+ Bloc Guardrails +
+ +## Aperçu + +Le bloc Guardrails vous permet de : + + + + Valider la structure JSON : garantir que les sorties LLM sont en JSON valide avant l'analyse + + + Faire correspondre des modèles Regex : vérifier que le contenu correspond à des formats spécifiques (e-mails, numéros de téléphone, URL, etc.) + + + Détecter les hallucinations : utiliser le scoring RAG + LLM pour valider les sorties IA par rapport au contenu de la base de connaissances + + + Détecter les PII : identifier et éventuellement masquer les informations personnellement identifiables à travers plus de 40 types d'entités + + + +## Types de validation + +### Validation JSON + +Vérifie que le contenu est correctement formaté en JSON. Parfait pour s'assurer que les sorties LLM structurées peuvent être analysées en toute sécurité. + +**Cas d'utilisation :** +- Valider les réponses JSON des blocs Agent avant l'analyse +- S'assurer que les charges utiles API sont correctement formatées +- Vérifier l'intégrité des données structurées + +**Sortie :** +- `passed` : `true` si JSON valide, `false` sinon +- `error` : message d'erreur si la validation échoue (par ex., "JSON invalide : jeton inattendu...") + +### Validation Regex + +Vérifie si le contenu correspond à un modèle d'expression régulière spécifié. + +**Cas d'utilisation :** +- Valider les adresses e-mail +- Vérifier les formats de numéros de téléphone +- Vérifier les URL ou identifiants personnalisés +- Imposer des modèles de texte spécifiques + +**Configuration :** +- **Modèle Regex** : l'expression régulière à faire correspondre (par ex., pour les e-mails) + +**Sortie :** +- `passed` : `true` si le contenu correspond au modèle, `false` sinon +- `error` : message d'erreur si la validation échoue + +### Détection d'hallucination + +Utilise la génération augmentée par récupération (RAG) avec notation par LLM pour détecter quand le contenu généré par IA contredit ou n'est pas fondé sur votre base de connaissances. + +**Comment ça fonctionne :** +1. Interroge votre base de connaissances pour obtenir un contexte pertinent +2. Envoie à la fois la sortie de l'IA et le contexte récupéré à un LLM +3. Le LLM attribue un score de confiance (échelle de 0 à 10) + - **0** = Hallucination complète (totalement non fondée) + - **10** = Entièrement fondé (complètement soutenu par la base de connaissances) +4. La validation réussit si le score ≥ seuil (par défaut : 3) + +**Configuration :** +- **Base de connaissances** : sélectionnez parmi vos bases de connaissances existantes +- **Modèle** : choisissez le LLM pour la notation (nécessite un raisonnement solide - GPT-4o, Claude 3.7 Sonnet recommandés) +- **Clé API** : authentification pour le fournisseur LLM sélectionné (masquée automatiquement pour les modèles hébergés/Ollama) +- **Seuil de confiance** : score minimum pour réussir (0-10, par défaut : 3) +- **Top K** (Avancé) : nombre de fragments de base de connaissances à récupérer (par défaut : 10) + +**Sortie :** +- `passed` : `true` si le score de confiance ≥ seuil +- `score` : score de confiance (0-10) +- `reasoning` : explication du LLM pour le score +- `error` : message d'erreur si la validation échoue + +**Cas d'utilisation :** +- Valider les réponses des agents par rapport à la documentation +- Assurer que les réponses du support client sont factuellement exactes +- Vérifier que le contenu généré correspond au matériel source +- Contrôle qualité pour les applications RAG + +### Détection de PII + +Détecte les informations personnellement identifiables à l'aide de Microsoft Presidio. Prend en charge plus de 40 types d'entités dans plusieurs pays et langues. + +
+
+ +**Comment ça fonctionne :** +1. Analyse le contenu pour détecter les entités PII à l'aide de correspondance de modèles et de NLP +2. Renvoie les entités détectées avec leurs emplacements et scores de confiance +3. Masque optionnellement les PII détectées dans la sortie + +**Configuration :** +- **Types de PII à détecter** : Sélectionnez parmi les catégories groupées via le sélecteur modal + - **Commun** : Nom de personne, Email, Téléphone, Carte de crédit, Adresse IP, etc. + - **USA** : SSN, Permis de conduire, Passeport, etc. + - **Royaume-Uni** : Numéro NHS, Numéro d'assurance nationale + - **Espagne** : NIF, NIE, CIF + - **Italie** : Code fiscal, Permis de conduire, Code TVA + - **Pologne** : PESEL, NIP, REGON + - **Singapour** : NRIC/FIN, UEN + - **Australie** : ABN, ACN, TFN, Medicare + - **Inde** : Aadhaar, PAN, Passeport, Numéro d'électeur +- **Mode** : + - **Détecter** : Identifier uniquement les PII (par défaut) + - **Masquer** : Remplacer les PII détectées par des valeurs masquées +- **Langue** : Langue de détection (par défaut : anglais) + +**Sortie :** +- `passed` : `false` si des types de PII sélectionnés sont détectés +- `detectedEntities` : Tableau des PII détectées avec type, emplacement et niveau de confiance +- `maskedText` : Contenu avec PII masquées (uniquement si mode = "Mask") +- `error` : Message d'erreur si la validation échoue + +**Cas d'utilisation :** +- Bloquer le contenu contenant des informations personnelles sensibles +- Masquer les PII avant de journaliser ou stocker des données +- Conformité avec le RGPD, HIPAA et autres réglementations sur la confidentialité +- Assainir les entrées utilisateur avant traitement + +## Configuration + +### Contenu à valider + +Le contenu d'entrée à valider. Cela provient généralement de : +- Sorties de blocs d'agent : `` +- Résultats de blocs de fonction : `` +- Réponses API : `` +- Toute autre sortie de bloc + +### Type de validation + +Choisissez parmi quatre types de validation : +- **JSON valide** : Vérifier si le contenu est au format JSON correctement formaté +- **Correspondance Regex** : Vérifier si le contenu correspond à un modèle regex +- **Vérification d'hallucination** : Valider par rapport à une base de connaissances avec notation LLM +- **Détection de PII** : Détecter et éventuellement masquer les informations personnellement identifiables + +## Sorties + +Tous les types de validation renvoient : + +- **``** : booléen indiquant si la validation a réussi +- **``** : le type de validation effectuée +- **``** : l'entrée originale qui a été validée +- **``** : message d'erreur si la validation a échoué (facultatif) + +Sorties supplémentaires par type : + +**Vérification d'hallucination :** +- **``** : score de confiance (0-10) +- **``** : explication du LLM + +**Détection de PII :** +- **``** : tableau des entités PII détectées +- **``** : contenu avec PII masquées (si mode = "Mask") + +## Exemples de cas d'utilisation + +### Valider le JSON avant l'analyse + +
+

Scénario : s'assurer que la sortie de l'agent est un JSON valide

+
    +
  1. L'agent génère une réponse JSON structurée
  2. +
  3. Guardrails valide le format JSON
  4. +
  5. Le bloc de condition vérifie ``
  6. +
  7. Si réussi → analyser et utiliser les données, si échoué → réessayer ou gérer l'erreur
  8. +
+
+ +### Prévenir les hallucinations + +
+

Scénario : valider les réponses du support client

+
    +
  1. L'agent génère une réponse à la question du client
  2. +
  3. Guardrails vérifie par rapport à la base de connaissances de la documentation d'assistance
  4. +
  5. Si le score de confiance ≥ 3 → envoyer la réponse
  6. +
  7. Si le score de confiance \< 3 → signaler pour révision humaine
  8. +
+
+ +### Bloquer les PII dans les entrées utilisateur + +
+

Scénario : assainir le contenu soumis par l'utilisateur

+
    +
  1. L'utilisateur soumet un formulaire avec du contenu textuel
  2. +
  3. Guardrails détecte les PII (emails, numéros de téléphone, numéros de sécurité sociale, etc.)
  4. +
  5. Si PII détectées → rejeter la soumission ou masquer les données sensibles
  6. +
  7. Si pas de PII → traiter normalement
  8. +
+
+ +
+
+ +### Valider le format d'email + +
+

Scénario : vérifier le format d'adresse email

+
    +
  1. L'agent extrait l'email du texte
  2. +
  3. Guardrails valide avec un modèle regex
  4. +
  5. Si valide → utiliser l'email pour la notification
  6. +
  7. Si invalide → demander une correction
  8. +
+
+ +## Bonnes pratiques + +- **Chaînez avec des blocs Condition** : Utilisez `` pour créer des branches dans la logique du workflow en fonction des résultats de validation +- **Validez le JSON avant de l'analyser** : Vérifiez toujours la structure JSON avant de tenter d'analyser les sorties du LLM +- **Choisissez les types de PII appropriés** : Sélectionnez uniquement les types d'entités PII pertinents pour votre cas d'utilisation afin d'améliorer les performances +- **Définissez des seuils de confiance raisonnables** : Pour la détection d'hallucinations, ajustez le seuil en fonction de vos exigences de précision (plus élevé = plus strict) +- **Utilisez des modèles performants pour la détection d'hallucinations** : GPT-4o ou Claude 3.7 Sonnet fournissent des scores de confiance plus précis +- **Masquez les PII pour la journalisation** : Utilisez le mode "Mask" lorsque vous devez journaliser ou stocker du contenu susceptible de contenir des PII +- **Testez les modèles regex** : Validez soigneusement vos modèles d'expressions régulières avant de les déployer en production +- **Surveillez les échecs de validation** : Suivez les messages `` pour identifier les problèmes de validation courants + + + La validation des guardrails s'effectue de manière synchrone dans votre workflow. Pour la détection d'hallucinations, choisissez des modèles plus rapides (comme GPT-4o-mini) si la latence est critique. + diff --git a/apps/docs/content/docs/fr/execution/costs.mdx b/apps/docs/content/docs/fr/execution/costs.mdx index 7ab7b0099f..6ccd8b0f92 100644 --- a/apps/docs/content/docs/fr/execution/costs.mdx +++ b/apps/docs/content/docs/fr/execution/costs.mdx @@ -170,17 +170,49 @@ Les différents forfaits d'abonnement ont des limites d'utilisation différentes | **Équipe** | 500 $ (mutualisé) | 50 sync, 100 async | | **Entreprise** | Personnalisé | Personnalisé | +## Modèle de facturation + +Sim utilise un modèle de facturation **abonnement de base + dépassement** : + +### Comment ça fonctionne + +**Forfait Pro (20 €/mois) :** +- L'abonnement mensuel inclut 20 € d'utilisation +- Utilisation inférieure à 20 € → Pas de frais supplémentaires +- Utilisation supérieure à 20 € → Paiement du dépassement en fin de mois +- Exemple : 35 € d'utilisation = 20 € (abonnement) + 15 € (dépassement) + +**Forfait Équipe (40 €/utilisateur/mois) :** +- Utilisation mutualisée entre tous les membres de l'équipe +- Dépassement calculé sur l'utilisation totale de l'équipe +- Le propriétaire de l'organisation reçoit une seule facture + +**Forfaits Entreprise :** +- Prix mensuel fixe, sans dépassements +- Limites d'utilisation personnalisées selon l'accord + +### Facturation par seuil + +Lorsque le dépassement non facturé atteint 50 €, Sim facture automatiquement le montant total non facturé. + +**Exemple :** +- Jour 10 : 70 € de dépassement → Facturation immédiate de 70 € +- Jour 15 : 35 € d'utilisation supplémentaire (105 € au total) → Déjà facturé, aucune action +- Jour 20 : 50 € d'utilisation supplémentaire (155 € au total, 85 € non facturés) → Facturation immédiate de 85 € + +Cela répartit les frais de dépassement importants tout au long du mois au lieu d'une seule grosse facture en fin de période. + ## Meilleures pratiques de gestion des coûts -1. **Surveillez régulièrement** : vérifiez fréquemment votre tableau de bord d'utilisation pour éviter les surprises -2. **Définissez des budgets** : utilisez les limites du plan comme garde-fous pour vos dépenses -3. **Optimisez les flux de travail** : examinez les exécutions à coût élevé et optimisez les prompts ou la sélection de modèles -4. **Utilisez des modèles appropriés** : adaptez la complexité du modèle aux exigences de la tâche -5. **Regroupez les tâches similaires** : combinez plusieurs requêtes lorsque c'est possible pour réduire les frais généraux +1. **Surveillance régulière** : Vérifiez fréquemment votre tableau de bord d'utilisation pour éviter les surprises +2. **Définir des budgets** : Utilisez les limites du forfait comme garde-fous pour vos dépenses +3. **Optimiser les flux de travail** : Examinez les exécutions à coût élevé et optimisez les prompts ou la sélection de modèles +4. **Utiliser les modèles appropriés** : Adaptez la complexité du modèle aux exigences de la tâche +5. **Regrouper les tâches similaires** : Combinez plusieurs requêtes lorsque c'est possible pour réduire les frais généraux ## Prochaines étapes -- Examinez votre utilisation actuelle dans [Paramètres → Abonnement](https://sim.ai/settings/subscription) -- Apprenez-en plus sur la [Journalisation](/execution/logging) pour suivre les détails d'exécution +- Consultez votre utilisation actuelle dans [Paramètres → Abonnement](https://sim.ai/settings/subscription) +- Découvrez la [Journalisation](/execution/logging) pour suivre les détails d'exécution - Explorez l'[API externe](/execution/api) pour la surveillance programmatique des coûts -- Découvrez les [techniques d'optimisation de flux de travail](/blocks) pour réduire les coûts \ No newline at end of file +- Consultez les [techniques d'optimisation des flux de travail](/blocks) pour réduire les coûts \ No newline at end of file diff --git a/apps/docs/content/docs/fr/sdks/python.mdx b/apps/docs/content/docs/fr/sdks/python.mdx index faf5f4b203..d3a8f11dcc 100644 --- a/apps/docs/content/docs/fr/sdks/python.mdx +++ b/apps/docs/content/docs/fr/sdks/python.mdx @@ -387,7 +387,7 @@ Gérez différents types d'erreurs qui peuvent survenir pendant l'exécution du from simstudio import SimStudioClient, SimStudioError import os -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) +client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) def execute_with_error_handling(): try: @@ -433,7 +433,7 @@ Exécutez plusieurs workflows efficacement : from simstudio import SimStudioClient import os -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) +client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) def execute_workflows_batch(workflow_data_pairs): """Execute multiple workflows with different input data.""" @@ -609,7 +609,7 @@ Exécutez des workflows avec des réponses en streaming en temps réel : from simstudio import SimStudioClient import os -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) +client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) def execute_with_streaming(): """Execute workflow with streaming enabled.""" diff --git a/apps/docs/content/docs/fr/sdks/typescript.mdx b/apps/docs/content/docs/fr/sdks/typescript.mdx index ca572c346e..204abd9b3f 100644 --- a/apps/docs/content/docs/fr/sdks/typescript.mdx +++ b/apps/docs/content/docs/fr/sdks/typescript.mdx @@ -604,28 +604,114 @@ async function executeClientSideWorkflow() { }); console.log('Workflow result:', result); - + // Update UI with result - document.getElementById('result')!.textContent = + document.getElementById('result')!.textContent = JSON.stringify(result.output, null, 2); } catch (error) { console.error('Error:', error); } } +``` + +### Téléchargement de fichiers + +Les objets de type File sont automatiquement détectés et convertis au format base64. Incluez-les dans votre entrée sous le nom de champ correspondant au format d'entrée du déclencheur API de votre workflow. + +Le SDK convertit les objets File dans ce format : + +```typescript +{ + type: 'file', + data: 'data:mime/type;base64,base64data', + name: 'filename', + mime: 'mime/type' +} +``` + +Alternativement, vous pouvez fournir manuellement des fichiers en utilisant le format URL : + +```typescript +{ + type: 'url', + data: 'https://example.com/file.pdf', + name: 'file.pdf', + mime: 'application/pdf' +} +``` + + + + + ```typescript + import { SimStudioClient } from 'simstudio-ts-sdk'; + + const client = new SimStudioClient({ + apiKey: process.env.NEXT_PUBLIC_SIM_API_KEY! + }); + + // From file input + async function handleFileUpload(event: Event) { + const input = event.target as HTMLInputElement; + const files = Array.from(input.files || []); + + // Include files under the field name from your API trigger's input format + const result = await client.executeWorkflow('workflow-id', { + input: { + documents: files, // Must match your workflow's "files" field name + instructions: 'Analyze these documents' + } + }); + + console.log('Result:', result); + } + ``` + + + -// Attach to button click + ```typescript + import { SimStudioClient } from 'simstudio-ts-sdk'; + import fs from 'fs'; + + const client = new SimStudioClient({ + apiKey: process.env.SIM_API_KEY! + }); + + // Read file and create File object + const fileBuffer = fs.readFileSync('./document.pdf'); + const file = new File([fileBuffer], 'document.pdf', { + type: 'application/pdf' + }); + + // Include files under the field name from your API trigger's input format + const result = await client.executeWorkflow('workflow-id', { + input: { + documents: [file], // Must match your workflow's "files" field name + query: 'Summarize this document' + } + }); + ``` + + + + +// Attacher au clic du bouton document.getElementById('executeBtn')?.addEventListener('click', executeClientSideWorkflow); + ``` - Lors de l'utilisation du SDK dans le navigateur, veillez à ne pas exposer de clés API sensibles. Envisagez d'utiliser un proxy backend ou des clés API publiques avec des permissions limitées. + When using the SDK in the browser, be careful not to expose sensitive API keys. Consider using a backend proxy or public API keys with limited permissions. -### Exemple de hook React +### React Hook Example -Créer un hook React personnalisé pour l'exécution de workflow : +Create a custom React hook for workflow execution: -```typescript +``` + +typescript import { useState, useCallback } from 'react'; import { SimStudioClient, WorkflowExecutionResult } from 'simstudio-ts-sdk'; @@ -671,7 +757,7 @@ export function useWorkflow(): UseWorkflowResult { }; } -// Usage in component +// Utilisation dans un composant function WorkflowComponent() { const { result, loading, error, executeWorkflow } = useWorkflow(); @@ -684,26 +770,29 @@ function WorkflowComponent() { return (
- {error &&
Error: {error.message}
} + {error &&
Erreur : {error.message}
} {result && (
-

Result:

+

Résultat :

{JSON.stringify(result, null, 2)}
)}
); } + ``` -### Exécution asynchrone de workflow +### Async Workflow Execution -Exécuter des workflows de manière asynchrone pour les tâches de longue durée : +Execute workflows asynchronously for long-running tasks: -```typescript +``` + +typescript import { SimStudioClient, AsyncExecutionResult } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -712,47 +801,50 @@ const client = new SimStudioClient({ async function executeAsync() { try { - // Start async execution + // Démarrer l'exécution asynchrone const result = await client.executeWorkflow('workflow-id', { input: { data: 'large dataset' }, - async: true // Execute asynchronously + async: true // Exécuter de manière asynchrone }); - // Check if result is an async execution + // Vérifier si le résultat est une exécution asynchrone if ('taskId' in result) { - console.log('Task ID:', result.taskId); - console.log('Status endpoint:', result.links.status); + console.log('ID de tâche :', result.taskId); + console.log('Point de terminaison de statut :', result.links.status); - // Poll for completion + // Interroger pour vérifier l'achèvement let status = await client.getJobStatus(result.taskId); while (status.status === 'queued' || status.status === 'processing') { - console.log('Current status:', status.status); - await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds + console.log('Statut actuel :', status.status); + await new Promise(resolve => setTimeout(resolve, 2000)); // Attendre 2 secondes status = await client.getJobStatus(result.taskId); } if (status.status === 'completed') { - console.log('Workflow completed!'); - console.log('Output:', status.output); - console.log('Duration:', status.metadata.duration); + console.log('Workflow terminé !'); + console.log('Sortie :', status.output); + console.log('Durée :', status.metadata.duration); } else { - console.error('Workflow failed:', status.error); + console.error('Échec du workflow :', status.error); } } } catch (error) { - console.error('Error:', error); + console.error('Erreur :', error); } } executeAsync(); + ``` -### Limitation de débit et nouvelle tentative +### Rate Limiting and Retry -Gérer automatiquement les limites de débit avec backoff exponentiel : +Handle rate limits automatically with exponential backoff: -```typescript +``` + +typescript import { SimStudioClient, SimStudioError } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -761,7 +853,7 @@ const client = new SimStudioClient({ async function executeWithRetryHandling() { try { - // Automatically retries on rate limit + // Réessaie automatiquement en cas de limite de débit const result = await client.executeWithRetry('workflow-id', { input: { message: 'Process this' } }, { @@ -771,26 +863,29 @@ async function executeWithRetryHandling() { backoffMultiplier: 2 }); - console.log('Success:', result); + console.log('Succès :', result); } catch (error) { if (error instanceof SimStudioError && error.code === 'RATE_LIMIT_EXCEEDED') { - console.error('Rate limit exceeded after all retries'); + console.error('Limite de débit dépassée après toutes les tentatives'); - // Check rate limit info + // Vérifier les informations de limite de débit const rateLimitInfo = client.getRateLimitInfo(); if (rateLimitInfo) { - console.log('Rate limit resets at:', new Date(rateLimitInfo.reset * 1000)); + console.log('La limite de débit se réinitialise à :', new Date(rateLimitInfo.reset * 1000)); } } } } + ``` -### Surveillance d'utilisation +### Usage Monitoring -Surveiller l'utilisation et les limites de votre compte : +Monitor your account usage and limits: -```typescript +``` + +typescript import { SimStudioClient } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -801,27 +896,46 @@ async function checkUsage() { try { const limits = await client.getUsageLimits(); - console.log('=== Rate Limits ==='); - console.log('Sync requests:'); - console.log(' Limit:', limits.rateLimit.sync.limit); - console.log(' Remaining:', limits.rateLimit.sync.remaining); - console.log(' Resets at:', limits.rateLimit.sync.resetAt); - console.log(' Is limited:', limits.rateLimit.sync.isLimited); + console.log('=== Limites de débit ==='); + console.log('Requêtes synchrones :'); + console.log(' Limite :', limits.rateLimit.sync.limit); + console.log(' Restant :', limits.rateLimit.sync.remaining); + console.log(' Réinitialisation à :', limits.rateLimit.sync.resetAt); + console.log(' Est limité :', limits.rateLimit.sync.isLimited); + + console.log('\nRequêtes asynchrones :'); + console.log(' Limite :', limits.rateLimit.async.limit); + console.log(' Restant :', limits.rateLimit.async.remaining); + console.log(' Réinitialisation à :', limits.rateLimit.async.resetAt); + console.log(' Est limité :', limits.rateLimit.async.isLimited); + + console.log('\n=== Utilisation ==='); + console.log('Coût de la période actuelle : ' + limits.usage.currentPeriodCost.toFixed(2) + ' €'); + console.log('Limite : ' + limits.usage.limit.toFixed(2) + ' €'); + console.log('Forfait :', limits.usage.plan); + + const percentUsed = (limits.usage.currentPeriodCost / limits.usage.limit) * 100; + console.log('Utilisation : ' + percentUsed.toFixed(1) + ' %'); + + if (percentUsed > 80) { + console.warn('⚠️ Attention : vous approchez de votre limite d'utilisation !'); + } + } catch (error) { + console.error('Erreur lors de la vérification de l'utilisation :', error); + } +} - console.log('\nAsync requests:'); - console.log(' Limit:', limits.rateLimit.async.limit); - console.log(' Remaining:', limits.rateLimit.async.remaining); - console.log(' Resets at:', limits.rateLimit.async.resetAt); - console.log(' Is limited:', limits.rateLimit.async.isLimited); +checkUsage(); - console.log('\n=== Usage ==='); - console.log('Current period cost: +``` ### Streaming Workflow Execution Execute workflows with real-time streaming responses: -```typescript +``` + +typescript import { SimStudioClient } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -842,23 +956,28 @@ async function executeWithStreaming() { console.error('Erreur :', error); } } + ``` The streaming response follows the Server-Sent Events (SSE) format: ``` -data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":"One"} + +data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":"Un"} data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":", deux"} data: {"event":"done","success":true,"output":{},"metadata":{"duration":610}} data: [DONE] + ``` **React Streaming Example:** -```typescript +``` + +typescript import { useState, useEffect } from 'react'; function StreamingWorkflow() { @@ -869,16 +988,16 @@ function StreamingWorkflow() { setLoading(true); setOutput(''); - // IMPORTANT: Make this API call from your backend server, not the browser - // Never expose your API key in client-side code + // IMPORTANT : Effectuez cet appel API depuis votre serveur backend, pas depuis le navigateur + // N'exposez jamais votre clé API dans le code côté client const response = await fetch('https://sim.ai/api/workflows/WORKFLOW_ID/execute', { method: 'POST', headers: { 'Content-Type': 'application/json', - 'X-API-Key': process.env.SIM_API_KEY! // Server-side environment variable only + 'X-API-Key': process.env.SIM_API_KEY! // Variable d'environnement côté serveur uniquement }, body: JSON.stringify({ - message: 'Generate a story', + message: 'Générer une histoire', stream: true, selectedOutputs: ['agent1.content'] }) @@ -907,10 +1026,10 @@ function StreamingWorkflow() { if (parsed.chunk) { setOutput(prev => prev + parsed.chunk); } else if (parsed.event === 'done') { - console.log('Execution complete:', parsed.metadata); + console.log('Exécution terminée :', parsed.metadata); } } catch (e) { - // Skip invalid JSON + // Ignorer le JSON invalide } } } @@ -926,6 +1045,7 @@ function StreamingWorkflow() { ); } + ``` ## Getting Your API Key @@ -961,7 +1081,9 @@ function StreamingWorkflow() { The SDK is written in TypeScript and provides full type safety: -```typescript +``` + +typescript import { SimStudioClient, WorkflowExecutionResult, @@ -969,23 +1091,22 @@ import { SimStudioError } from 'simstudio-ts-sdk'; -// Type-safe client initialization +// Initialisation du client avec typage const client: SimStudioClient = new SimStudioClient({ apiKey: process.env.SIM_API_KEY! }); -// Type-safe workflow execution +// Exécution de workflow avec typage const result: WorkflowExecutionResult = await client.executeWorkflow('workflow-id', { input: { message: 'Bonjour, TypeScript !' } }); -// Type-safe status checking +// Vérification de statut avec typage const status: WorkflowStatus = await client.getWorkflowStatus('workflow-id'); ``` -## License - +## Licence Apache-2.0 diff --git a/apps/docs/content/docs/fr/triggers/api.mdx b/apps/docs/content/docs/fr/triggers/api.mdx index 978ec55610..fa95fb0fb6 100644 --- a/apps/docs/content/docs/fr/triggers/api.mdx +++ b/apps/docs/content/docs/fr/triggers/api.mdx @@ -22,9 +22,17 @@ Le déclencheur d'API expose votre flux de travail en tant que point de terminai /> -Ajoutez un champ **Format d'entrée** pour chaque paramètre. Les clés de sortie d'exécution reflètent le schéma et sont également disponibles sous ``. +Ajoutez un champ **Format d'entrée** pour chaque paramètre. Types pris en charge : -Les exécutions manuelles dans l'éditeur utilisent la colonne `value` pour que vous puissiez tester sans envoyer de requête. Pendant l'exécution, le résolveur remplit à la fois `` et ``. +- **string** - Valeurs textuelles +- **number** - Valeurs numériques +- **boolean** - Valeurs vrai/faux +- **json** - Objets JSON +- **files** - Téléchargements de fichiers (accès via ``, ``, etc.) + +Les clés de sortie d'exécution reflètent le schéma et sont disponibles sous ``. + +Les exécutions manuelles dans l'éditeur utilisent la colonne `value` pour que vous puissiez tester sans envoyer de requête. Pendant l'exécution, le résolveur remplit à la fois `` et ``. ## Exemple de requête @@ -36,23 +44,23 @@ curl -X POST \ -d '{"userId":"demo-user","maxTokens":1024}' ``` -Les réponses réussies renvoient le résultat d'exécution sérialisé de l'exécuteur. Les erreurs révèlent des problèmes de validation, d'authentification ou d'échec du workflow. +Les réponses réussies renvoient le résultat d'exécution sérialisé de l'Exécuteur. Les erreurs révèlent des problèmes de validation, d'authentification ou d'échec de workflow. ## Réponses en streaming -Activez le streaming en temps réel pour recevoir les résultats du workflow au fur et à mesure qu'ils sont générés, caractère par caractère. Cela est utile pour afficher progressivement les réponses de l'IA aux utilisateurs. +Activez le streaming en temps réel pour recevoir la sortie du workflow au fur et à mesure qu'elle est générée, caractère par caractère. Cela est utile pour afficher progressivement les réponses d'IA aux utilisateurs. ### Paramètres de requête Ajoutez ces paramètres pour activer le streaming : - `stream` - Définissez à `true` pour activer le streaming Server-Sent Events (SSE) -- `selectedOutputs` - Tableau des sorties de blocs à diffuser en streaming (par exemple, `["agent1.content"]`) +- `selectedOutputs` - Tableau des sorties de bloc à diffuser en streaming (par ex., `["agent1.content"]`) ### Format de sortie de bloc -Utilisez le format `blockName.attribute` pour spécifier quelles sorties de blocs diffuser en streaming : -- Format : `"blockName.attribute"` (par exemple, si vous souhaitez diffuser en streaming le contenu du bloc Agent 1, vous utiliseriez `"agent1.content"`) +Utilisez le format `blockName.attribute` pour spécifier quelles sorties de bloc diffuser en streaming : +- Format : `"blockName.attribute"` (par ex., si vous souhaitez diffuser le contenu du bloc Agent 1, vous utiliseriez `"agent1.content"`) - Les noms de blocs ne sont pas sensibles à la casse et les espaces sont ignorés ### Exemple de requête @@ -85,8 +93,8 @@ data: {"event":"done","success":true,"output":{},"metadata":{"duration":610}} data: [DONE] ``` -Chaque événement comprend : -- **Fragments en streaming** : `{"blockId": "...", "chunk": "text"}` - Texte en temps réel au fur et à mesure qu'il est généré +Chaque événement inclut : +- **Fragments en streaming** : `{"blockId": "...", "chunk": "text"}` - Texte en temps réel au fur et à mesure de sa génération - **Événement final** : `{"event": "done", ...}` - Métadonnées d'exécution et résultats complets - **Terminateur** : `[DONE]` - Signale la fin du flux @@ -94,26 +102,22 @@ Chaque événement comprend : Lorsque `selectedOutputs` inclut plusieurs blocs, chaque fragment indique quel bloc l'a produit : -```bash -curl -X POST \ - https://sim.ai/api/workflows/WORKFLOW_ID/execute \ - -H 'Content-Type: application/json' \ - -H 'X-API-Key: YOUR_KEY' \ - -d '{ - "message": "Process this request", - "stream": true, - "selectedOutputs": ["agent1.content", "agent2.content"] - }' +```json +{ + "type": "block", + "blockType": "text", + "text": "Voici une réponse en streaming" +} ``` Le champ `blockId` dans chaque fragment vous permet d'acheminer la sortie vers l'élément d'interface utilisateur approprié : -``` -data: {"blockId":"agent1-uuid","chunk":"Processing..."} - -data: {"blockId":"agent2-uuid","chunk":"Analyzing..."} - -data: {"blockId":"agent1-uuid","chunk":" complete"} +```json +{ + "type": "block", + "blockType": "code", + "text": "console.log('Ceci est un bloc de code');" +} ``` ## Référence des sorties @@ -121,10 +125,57 @@ data: {"blockId":"agent1-uuid","chunk":" complete"} | Référence | Description | |-----------|-------------| | `` | Champ défini dans le format d'entrée | -| `` | Corps de requête structuré complet | +| `` | Corps complet de la requête structurée | + +### Format de téléchargement de fichiers + +L'API accepte les fichiers dans deux formats : + +**1. Fichiers encodés en Base64** (recommandé pour les SDK) : + +```json +{ + "file": { + "data": "data:application/pdf;base64,JVBERi0xLjMKJcTl8uXrp...", + "name": "document.pdf" + } +} +``` + +- Taille maximale de fichier : 20 Mo par fichier +- Les fichiers sont téléchargés vers le stockage cloud et convertis en objets UserFile avec toutes les propriétés + +**2. Références directes par URL** : + +```json +{ + "file": { + "url": "https://example.com/document.pdf", + "name": "document.pdf" + } +} +``` + +- Le fichier n'est pas téléchargé, l'URL est transmise directement +- Utile pour référencer des fichiers existants + +### Propriétés des fichiers + +Pour les fichiers, accédez à toutes les propriétés : + +| Propriété | Description | Type | +|----------|-------------|------| +| `` | URL de téléchargement signée | chaîne | +| `` | Nom de fichier original | chaîne | +| `` | Taille du fichier en octets | nombre | +| `` | Type MIME | chaîne | +| `` | Horodatage du téléchargement (ISO 8601) | chaîne | +| `` | Horodatage d'expiration de l'URL (ISO 8601) | chaîne | + +Pour les fichiers référencés par URL, les mêmes propriétés sont disponibles à l'exception de `uploadedAt` et `expiresAt` puisque le fichier n'est pas téléchargé dans notre stockage. Si aucun format d'entrée n'est défini, l'exécuteur expose uniquement le JSON brut à ``. -Un workflow ne peut contenir qu'un seul déclencheur API. Publiez un nouveau déploiement après les modifications pour que le point de terminaison reste à jour. +Un flux de travail ne peut contenir qu'un seul déclencheur d'API. Publiez un nouveau déploiement après les modifications pour que le point de terminaison reste à jour. diff --git a/apps/docs/content/docs/fr/triggers/chat.mdx b/apps/docs/content/docs/fr/triggers/chat.mdx index 56f04cb022..b7bc78122a 100644 --- a/apps/docs/content/docs/fr/triggers/chat.mdx +++ b/apps/docs/content/docs/fr/triggers/chat.mdx @@ -24,20 +24,31 @@ Le déclencheur de chat crée une interface conversationnelle pour votre flux de Le déclencheur écrit trois champs que les blocs en aval peuvent référencer : -| Référence | Description | -|-----------|-------------| -| `` | Dernier message de l'utilisateur | -| `` | ID du fil de conversation | -| `` | Fichiers téléchargés optionnels | +| Référence | Description | Type | +|-----------|-------------|------| +| `` | Dernier message de l'utilisateur | string | +| `` | ID du fil de conversation | string | +| `` | Fichiers téléchargés optionnels | tableau de fichiers | -Les fichiers incluent `name`, `mimeType`, et un `url` signé. +### Propriétés des fichiers + +Accédez aux propriétés individuelles des fichiers en utilisant l'indexation de tableau : + +| Propriété | Description | Type | +|----------|-------------|------| +| `` | URL de téléchargement signée | string | +| `` | Nom de fichier original | string | +| `` | Taille du fichier en octets | number | +| `` | Type MIME | string | +| `` | Horodatage du téléchargement (ISO 8601) | string | +| `` | Horodatage d'expiration de l'URL (ISO 8601) | string | ## Notes d'utilisation -1. Ajoutez un bloc Déclencheur de chat par flux de travail. -2. Déployez le flux de travail en mode chat. -3. Partagez le lien de déploiement — chaque réponse réutilise l'ID de conversation pour que le flux de travail puisse conserver le contexte. +1. Ajoutez un bloc Déclencheur de chat par workflow. +2. Déployez le workflow en mode chat. +3. Partagez le lien de déploiement — chaque réponse réutilise l'ID de conversation pour que le workflow puisse conserver le contexte. -Le constructeur bloque plusieurs blocs Déclencheur de chat dans le même flux de travail. +Le constructeur bloque plusieurs blocs Déclencheur de chat dans le même workflow. diff --git a/apps/docs/content/docs/ja/blocks/guardrails.mdx b/apps/docs/content/docs/ja/blocks/guardrails.mdx new file mode 100644 index 0000000000..b27ffbe94e --- /dev/null +++ b/apps/docs/content/docs/ja/blocks/guardrails.mdx @@ -0,0 +1,317 @@ +--- +title: ガードレール +--- + +import { Callout } from 'fumadocs-ui/components/callout' +import { Step, Steps } from 'fumadocs-ui/components/steps' +import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Image } from '@/components/ui/image' +import { Video } from '@/components/ui/video' + +ガードレールブロックは、複数の検証タイプに対してコンテンツをチェックすることで、AIワークフローを検証し保護します。データ品質の確保、ハルシネーション(幻覚)の防止、個人情報の検出、フォーマット要件の強制などをワークフローに組み込む前に行います。 + +
+ ガードレールブロック +
+ +## 概要 + +ガードレールブロックでは以下のことが可能です: + + + + JSON構造の検証:パース前にLLM出力が有効なJSONであることを確認 + + + 正規表現パターンの一致:コンテンツが特定のフォーマット(メール、電話番号、URLなど)に一致することを確認 + + + ハルシネーション(幻覚)の検出:RAG + LLMスコアリングを使用してAI出力をナレッジベースコンテンツと照合して検証 + + + 個人情報の検出:40種類以上のエンティティタイプにわたる個人を特定できる情報を識別し、オプションでマスク処理 + + + +## 検証タイプ + +### JSON検証 + +コンテンツが適切にフォーマットされたJSONであることを検証します。構造化されたLLM出力を安全にパースできることを確認するのに最適です。 + +**ユースケース:** +- パース前にエージェントブロックからのJSON応答を検証 +- APIペイロードが適切にフォーマットされていることを確認 +- 構造化データの整合性をチェック + +**出力:** +- `passed`:有効なJSONの場合は`true`、それ以外の場合は`false` +- `error`:検証が失敗した場合のエラーメッセージ(例:「無効なJSON:予期しないトークン...」) + +### 正規表現検証 + +コンテンツが指定された正規表現パターンに一致するかどうかをチェックします。 + +**ユースケース:** +- メールアドレスの検証 +- 電話番号フォーマットのチェック +- URLやカスタム識別子の確認 +- 特定のテキストパターンの強制 + +**設定:** +- **正規表現パターン**:一致させる正規表現(例:メールの場合は`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}--- +title: ガードレール +--- + +import { Callout } from 'fumadocs-ui/components/callout' +import { Step, Steps } from 'fumadocs-ui/components/steps' +import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Image } from '@/components/ui/image' +import { Video } from '@/components/ui/video' + +ガードレールブロックは、複数の検証タイプに対してコンテンツをチェックすることで、AIワークフローを検証し保護します。データ品質の確保、ハルシネーション(幻覚)の防止、個人情報の検出、フォーマット要件の強制などをワークフローに組み込む前に行います。 + +
+ ガードレールブロック +
+ +## 概要 + +ガードレールブロックでは以下のことが可能です: + + + + JSON構造の検証:パース前にLLM出力が有効なJSONであることを確認 + + + 正規表現パターンの一致:コンテンツが特定のフォーマット(メール、電話番号、URLなど)に一致することを確認 + + + ハルシネーション(幻覚)の検出:RAG + LLMスコアリングを使用してAI出力をナレッジベースコンテンツと照合して検証 + + + 個人情報の検出:40種類以上のエンティティタイプにわたる個人を特定できる情報を識別し、オプションでマスク処理 + + + +## 検証タイプ + +### JSON検証 + +コンテンツが適切にフォーマットされたJSONであることを検証します。構造化されたLLM出力を安全にパースできることを確認するのに最適です。 + +**ユースケース:** +- パース前にエージェントブロックからのJSON応答を検証 +- APIペイロードが適切にフォーマットされていることを確認 +- 構造化データの整合性をチェック + +**出力:** +- `passed`:有効なJSONの場合は`true`、それ以外の場合は`false` +- `error`:検証が失敗した場合のエラーメッセージ(例:「無効なJSON:予期しないトークン...」) + +### 正規表現検証 + +コンテンツが指定された正規表現パターンに一致するかどうかをチェックします。 + +**ユースケース:** +- メールアドレスの検証 +- 電話番号フォーマットのチェック +- URLやカスタム識別子の確認 +- 特定のテキストパターンの強制 + +**設定:** +- **正規表現パターン**:一致させる正規表現(例:メールの場合は) + +**出力:** +- `passed`: コンテンツがパターンに一致する場合は `true`、それ以外の場合は `false` +- `error`: 検証が失敗した場合のエラーメッセージ + +### 幻覚検出 + +LLMスコアリングを用いた検索拡張生成(RAG)を使用して、AI生成コンテンツがナレッジベースと矛盾している場合や、ナレッジベースに根拠がない場合を検出します。 + +**仕組み:** +1. 関連するコンテキストをナレッジベースから検索 +2. AI出力と検索されたコンテキストの両方をLLMに送信 +3. LLMが信頼度スコア(0〜10のスケール)を割り当て + - **0** = 完全な幻覚(まったく根拠なし) + - **10** = 完全に根拠あり(ナレッジベースで完全に裏付けられている) +4. スコアが閾値以上(デフォルト:3)であれば検証に合格 + +**設定:** +- **ナレッジベース**: 既存のナレッジベースから選択 +- **モデル**: スコアリング用のLLMを選択(強力な推論能力が必要 - GPT-4o、Claude 3.7 Sonnetを推奨) +- **APIキー**: 選択したLLMプロバイダーの認証(ホスト型/Ollamaモデルでは自動的に非表示) +- **信頼度閾値**: 合格するための最小スコア(0〜10、デフォルト:3) +- **Top K**(詳細設定): 取得するナレッジベースのチャンク数(デフォルト:10) + +**出力:** +- `passed`: 信頼度スコアが閾値以上の場合は `true` +- `score`: 信頼度スコア(0〜10) +- `reasoning`: スコアに対するLLMの説明 +- `error`: 検証が失敗した場合のエラーメッセージ + +**ユースケース:** +- エージェントの応答をドキュメントに対して検証 +- カスタマーサポートの回答が事実に基づいていることを確認 +- 生成されたコンテンツがソース資料と一致することを確認 +- RAGアプリケーションの品質管理 + +### PII検出 + +Microsoft Presidioを使用して個人を特定できる情報を検出します。複数の国と言語にわたる40以上のエンティティタイプをサポートしています。 + +
+
+ +**仕組み:** +1. パターンマッチングとNLPを使用してコンテンツ内のPIIエンティティをスキャン +2. 検出されたエンティティの位置と信頼度スコアを返す +3. オプションで出力内の検出されたPIIをマスク処理 + +**設定:** +- **検出するPIIタイプ**: モーダルセレクターを通じてグループ化されたカテゴリから選択 + - **一般**: 個人名、メールアドレス、電話番号、クレジットカード、IPアドレスなど + - **アメリカ**: 社会保障番号、運転免許証、パスポートなど + - **イギリス**: NHS番号、国民保険番号 + - **スペイン**: NIF、NIE、CIF + - **イタリア**: 納税者番号、運転免許証、VAT番号 + - **ポーランド**: PESEL、NIP、REGON + - **シンガポール**: NRIC/FIN、UEN + - **オーストラリア**: ABN、ACN、TFN、メディケア + - **インド**: Aadhaar、PAN、パスポート、有権者番号 +- **モード**: + - **検出**: PIIの識別のみ(デフォルト) + - **マスク**: 検出されたPIIをマスク値に置き換え +- **言語**: 検出言語(デフォルト:英語) + +**出力:** +- `passed`: 選択したPIIタイプが検出された場合は `false` +- `detectedEntities`: タイプ、位置、信頼度を含む検出されたPIIの配列 +- `maskedText`: PIIがマスクされたコンテンツ(モード = "Mask"の場合のみ) +- `error`: 検証が失敗した場合のエラーメッセージ + +**ユースケース:** +- 機密性の高い個人情報を含むコンテンツのブロック +- ログ記録やデータ保存前のPIIマスキング +- GDPR、HIPAAなどのプライバシー規制への準拠 +- 処理前のユーザー入力のサニタイズ + +## 設定 + +### 検証するコンテンツ + +検証する入力コンテンツ。通常、以下から取得されます: +- エージェントブロックの出力: `` +- 関数ブロックの結果: `` +- APIレスポンス: `` +- その他のブロック出力 + +### 検証タイプ + +4つの検証タイプから選択: +- **有効なJSON**: コンテンツが適切にフォーマットされたJSONかどうかを確認 +- **正規表現マッチ**: コンテンツが正規表現パターンに一致するか検証 +- **幻覚チェック**: LLMスコアリングによる知識ベースとの検証 +- **PII検出**: 個人を特定できる情報の検出と任意のマスキング + +## 出力 + +すべての検証タイプは以下を返します: + +- **``**: 検証が成功したかどうかを示すブール値 +- **``**: 実行された検証のタイプ +- **``**: 検証された元の入力 +- **``**: 検証が失敗した場合のエラーメッセージ(オプション) + +タイプ別の追加出力: + +**幻覚チェック:** +- **``**: 信頼度スコア(0〜10) +- **``**: LLMの説明 + +**PII検出:** +- **``**: 検出されたPIIエンティティの配列 +- **``**: PIIがマスクされたコンテンツ(モード = "Mask"の場合) + +## 使用例 + +### パース前にJSONを検証する + +
+

シナリオ:エージェントの出力が有効なJSONであることを確認

+
    +
  1. エージェントが構造化されたJSON応答を生成
  2. +
  3. ガードレールがJSON形式を検証
  4. +
  5. 条件ブロックが``をチェック
  6. +
  7. 成功した場合→データを解析して使用、失敗した場合→再試行またはエラー処理
  8. +
+
+ +### 幻覚を防止する + +
+

シナリオ:カスタマーサポートの回答を検証

+
    +
  1. エージェントが顧客の質問に対する回答を生成
  2. +
  3. ガードレールがサポートドキュメントのナレッジベースと照合
  4. +
  5. 信頼度スコアが3以上→回答を送信
  6. +
  7. 信頼度スコアが3未満→人間によるレビューにフラグ付け
  8. +
+
+ +### ユーザー入力のPIIをブロックする + +
+

シナリオ:ユーザー提出コンテンツの無害化

+
    +
  1. ユーザーがテキストコンテンツを含むフォームを提出
  2. +
  3. ガードレールがPII(メール、電話番号、社会保障番号など)を検出
  4. +
  5. PIIが検出された場合→提出を拒否または機密データをマスク
  6. +
  7. PIIがない場合→通常通り処理
  8. +
+
+ +
+
+ +### メール形式の検証 + +
+

シナリオ:メールアドレス形式のチェック

+
    +
  1. エージェントがテキストからメールを抽出
  2. +
  3. ガードレールが正規表現パターンで検証
  4. +
  5. 有効な場合→メールを通知に使用
  6. +
  7. 無効な場合→修正を要求
  8. +
+
+ +## ベストプラクティス + +- **条件ブロックと連携する**: `` を使用して検証結果に基づいてワークフローのロジックを分岐させる +- **JSONの解析前に検証する**: LLM出力を解析する前に、必ずJSON構造を検証する +- **適切なPIIタイプを選択する**: パフォーマンス向上のため、ユースケースに関連するPIIエンティティタイプのみを選択する +- **適切な信頼度しきい値を設定する**: 幻覚検出では、精度要件に基づいてしきい値を調整する(高いほど厳格) +- **幻覚検出には高性能モデルを使用する**: GPT-4oまたはClaude 3.7 Sonnetは、より正確な信頼度スコアリングを提供する +- **ログ記録のためのPIIマスキング**: PIIを含む可能性のあるコンテンツをログに記録または保存する必要がある場合は「マスク」モードを使用する +- **正規表現パターンをテストする**: 本番環境にデプロイする前に正規表現パターンを徹底的に検証する +- **検証失敗を監視する**: `` メッセージを追跡して一般的な検証問題を特定する + + + ガードレールの検証はワークフロー内で同期的に行われます。レイテンシーが重要な場合は、幻覚検出にはより高速なモデル(GPT-4o-miniなど)を選択してください。 + diff --git a/apps/docs/content/docs/ja/execution/costs.mdx b/apps/docs/content/docs/ja/execution/costs.mdx index 6f83172d2b..4842f4bf60 100644 --- a/apps/docs/content/docs/ja/execution/costs.mdx +++ b/apps/docs/content/docs/ja/execution/costs.mdx @@ -170,17 +170,49 @@ curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" htt | **チーム** | $500(プール) | 50同期、100非同期 | | **エンタープライズ** | カスタム | カスタム | +## 課金モデル + +Simは**基本サブスクリプション + 超過分**の課金モデルを使用しています: + +### 仕組み + +**Proプラン(月額$20):** +- 月額サブスクリプションには$20分の使用量が含まれます +- 使用量が$20未満 → 追加料金なし +- 使用量が$20を超える → 月末に超過分を支払い +- 例:$35の使用量 = $20(サブスクリプション)+ $15(超過分) + +**チームプラン($40/シート/月):** +- チームメンバー全体でプールされた使用量 +- チーム全体の使用量から超過分を計算 +- 組織のオーナーが一括で請求を受ける + +**エンタープライズプラン:** +- 固定月額料金、超過料金なし +- 契約に基づくカスタム使用制限 + +### しきい値課金 + +未請求の超過分が$50に達すると、Simは自動的に未請求の全額を請求します。 + +**例:** +- 10日目:$70の超過分 → 即時に$70を請求 +- 15日目:追加$35の使用(合計$105)→ すでに請求済み、アクションなし +- 20日目:さらに$50の使用(合計$155、未請求$85)→ 即時に$85を請求 + +これにより、期間終了時に大きな請求が一度にくるのではなく、月を通じて大きな超過料金が分散されます。 + ## コスト管理のベストプラクティス -1. **定期的な監視**: 予期せぬ事態を避けるため、使用状況ダッシュボードを頻繁に確認する -2. **予算の設定**: プランの制限を支出のガードレールとして使用する -3. **ワークフローの最適化**: コストの高い実行を見直し、プロンプトやモデル選択を最適化する -4. **適切なモデルの使用**: タスクの要件に合わせてモデルの複雑さを選択する -5. **類似タスクのバッチ処理**: 可能な場合は複数のリクエストを組み合わせてオーバーヘッドを削減する +1. **定期的な監視**:予想外の事態を避けるため、使用量ダッシュボードを頻繁にチェック +2. **予算設定**:支出の目安としてプラン制限を活用 +3. **ワークフローの最適化**:高コストの実行を見直し、プロンプトやモデル選択を最適化 +4. **適切なモデルの使用**:タスク要件に合わせたモデルの複雑さを選択 +5. **類似タスクのバッチ処理**:オーバーヘッドを減らすために可能な場合は複数のリクエストを組み合わせる ## 次のステップ -- [設定 → サブスクリプション](https://sim.ai/settings/subscription)で現在の使用状況を確認する +- [設定 → サブスクリプション](https://sim.ai/settings/subscription)で現在の使用状況を確認 - 実行詳細を追跡するための[ロギング](/execution/logging)について学ぶ -- プログラムによるコスト監視のための[外部API](/execution/api)を探索する -- コスト削減のための[ワークフロー最適化テクニック](/blocks)をチェックする \ No newline at end of file +- プログラムによるコスト監視のための[外部API](/execution/api)を探索 +- コスト削減のための[ワークフロー最適化テクニック](/blocks)をチェック \ No newline at end of file diff --git a/apps/docs/content/docs/ja/sdks/python.mdx b/apps/docs/content/docs/ja/sdks/python.mdx index b667a9f3d8..39fa75470d 100644 --- a/apps/docs/content/docs/ja/sdks/python.mdx +++ b/apps/docs/content/docs/ja/sdks/python.mdx @@ -433,7 +433,7 @@ with SimStudioClient(api_key=os.getenv("SIM_API_KEY")) as client: from simstudio import SimStudioClient import os -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) +client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) def execute_workflows_batch(workflow_data_pairs): """Execute multiple workflows with different input data.""" @@ -660,7 +660,7 @@ def stream_workflow(): 'https://sim.ai/api/workflows/WORKFLOW_ID/execute', headers={ 'Content-Type': 'application/json', - 'X-API-Key': os.getenv('SIM_API_KEY') + 'X-API-Key': os.getenv('SIM_API_KEY') }, json={ 'message': 'Generate a story', diff --git a/apps/docs/content/docs/ja/sdks/typescript.mdx b/apps/docs/content/docs/ja/sdks/typescript.mdx index 785f60b29d..b993812c25 100644 --- a/apps/docs/content/docs/ja/sdks/typescript.mdx +++ b/apps/docs/content/docs/ja/sdks/typescript.mdx @@ -604,28 +604,114 @@ async function executeClientSideWorkflow() { }); console.log('Workflow result:', result); - + // Update UI with result - document.getElementById('result')!.textContent = + document.getElementById('result')!.textContent = JSON.stringify(result.output, null, 2); } catch (error) { console.error('Error:', error); } } +``` + +### ファイルアップロード + +ファイルオブジェクトは自動的に検出され、base64形式に変換されます。ワークフローのAPIトリガー入力形式に一致するフィールド名の下に入力に含めてください。 + +SDKはファイルオブジェクトをこの形式に変換します: + +```typescript +{ + type: 'file', + data: 'data:mime/type;base64,base64data', + name: 'filename', + mime: 'mime/type' +} +``` + +または、URL形式を使用して手動でファイルを提供することもできます: + +```typescript +{ + type: 'url', + data: 'https://example.com/file.pdf', + name: 'file.pdf', + mime: 'application/pdf' +} +``` + + + + + ```typescript + import { SimStudioClient } from 'simstudio-ts-sdk'; + + const client = new SimStudioClient({ + apiKey: process.env.NEXT_PUBLIC_SIM_API_KEY! + }); + + // From file input + async function handleFileUpload(event: Event) { + const input = event.target as HTMLInputElement; + const files = Array.from(input.files || []); + + // Include files under the field name from your API trigger's input format + const result = await client.executeWorkflow('workflow-id', { + input: { + documents: files, // Must match your workflow's "files" field name + instructions: 'Analyze these documents' + } + }); + + console.log('Result:', result); + } + ``` + + + -// Attach to button click + ```typescript + import { SimStudioClient } from 'simstudio-ts-sdk'; + import fs from 'fs'; + + const client = new SimStudioClient({ + apiKey: process.env.SIM_API_KEY! + }); + + // Read file and create File object + const fileBuffer = fs.readFileSync('./document.pdf'); + const file = new File([fileBuffer], 'document.pdf', { + type: 'application/pdf' + }); + + // Include files under the field name from your API trigger's input format + const result = await client.executeWorkflow('workflow-id', { + input: { + documents: [file], // Must match your workflow's "files" field name + query: 'Summarize this document' + } + }); + ``` + + + + +// ボタンクリックにアタッチ document.getElementById('executeBtn')?.addEventListener('click', executeClientSideWorkflow); + ``` - ブラウザでSDKを使用する場合、機密性の高いAPIキーを公開しないよう注意してください。バックエンドプロキシや権限が制限された公開APIキーの使用を検討してください。 + When using the SDK in the browser, be careful not to expose sensitive API keys. Consider using a backend proxy or public API keys with limited permissions. -### Reactフックの例 +### React Hook Example -ワークフロー実行用のカスタムReactフックを作成: +Create a custom React hook for workflow execution: -```typescript +``` + +typescript import { useState, useCallback } from 'react'; import { SimStudioClient, WorkflowExecutionResult } from 'simstudio-ts-sdk'; @@ -671,7 +757,7 @@ export function useWorkflow(): UseWorkflowResult { }; } -// Usage in component +// コンポーネントでの使用 function WorkflowComponent() { const { result, loading, error, executeWorkflow } = useWorkflow(); @@ -684,26 +770,29 @@ function WorkflowComponent() { return (
- {error &&
Error: {error.message}
} + {error &&
エラー: {error.message}
} {result && (
-

Result:

+

結果:

{JSON.stringify(result, null, 2)}
)}
); } + ``` -### 非同期ワークフロー実行 +### Async Workflow Execution -長時間実行タスク向けに非同期でワークフローを実行: +Execute workflows asynchronously for long-running tasks: -```typescript +``` + +typescript import { SimStudioClient, AsyncExecutionResult } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -712,47 +801,50 @@ const client = new SimStudioClient({ async function executeAsync() { try { - // Start async execution + // 非同期実行を開始 const result = await client.executeWorkflow('workflow-id', { input: { data: 'large dataset' }, - async: true // Execute asynchronously + async: true // 非同期で実行 }); - // Check if result is an async execution + // 結果が非同期実行かどうかを確認 if ('taskId' in result) { - console.log('Task ID:', result.taskId); - console.log('Status endpoint:', result.links.status); + console.log('タスクID:', result.taskId); + console.log('ステータスエンドポイント:', result.links.status); - // Poll for completion + // 完了を確認するためのポーリング let status = await client.getJobStatus(result.taskId); while (status.status === 'queued' || status.status === 'processing') { - console.log('Current status:', status.status); - await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds + console.log('現在のステータス:', status.status); + await new Promise(resolve => setTimeout(resolve, 2000)); // 2秒待機 status = await client.getJobStatus(result.taskId); } if (status.status === 'completed') { - console.log('Workflow completed!'); - console.log('Output:', status.output); - console.log('Duration:', status.metadata.duration); + console.log('ワークフロー完了!'); + console.log('出力:', status.output); + console.log('所要時間:', status.metadata.duration); } else { - console.error('Workflow failed:', status.error); + console.error('ワークフロー失敗:', status.error); } } } catch (error) { - console.error('Error:', error); + console.error('エラー:', error); } } executeAsync(); + ``` -### レート制限とリトライ +### Rate Limiting and Retry -指数バックオフによるレート制限の自動処理: +Handle rate limits automatically with exponential backoff: -```typescript +``` + +typescript import { SimStudioClient, SimStudioError } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -761,7 +853,7 @@ const client = new SimStudioClient({ async function executeWithRetryHandling() { try { - // Automatically retries on rate limit + // レート制限時に自動的にリトライ const result = await client.executeWithRetry('workflow-id', { input: { message: 'Process this' } }, { @@ -771,26 +863,29 @@ async function executeWithRetryHandling() { backoffMultiplier: 2 }); - console.log('Success:', result); + console.log('成功:', result); } catch (error) { if (error instanceof SimStudioError && error.code === 'RATE_LIMIT_EXCEEDED') { - console.error('Rate limit exceeded after all retries'); + console.error('すべてのリトライ後もレート制限を超過'); - // Check rate limit info + // レート制限情報を確認 const rateLimitInfo = client.getRateLimitInfo(); if (rateLimitInfo) { - console.log('Rate limit resets at:', new Date(rateLimitInfo.reset * 1000)); + console.log('レート制限リセット時刻:', new Date(rateLimitInfo.reset * 1000)); } } } } + ``` -### 使用状況モニタリング +### Usage Monitoring -アカウントの使用状況と制限のモニタリング: +Monitor your account usage and limits: -```typescript +``` + +typescript import { SimStudioClient } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -801,27 +896,46 @@ async function checkUsage() { try { const limits = await client.getUsageLimits(); - console.log('=== Rate Limits ==='); - console.log('Sync requests:'); - console.log(' Limit:', limits.rateLimit.sync.limit); - console.log(' Remaining:', limits.rateLimit.sync.remaining); - console.log(' Resets at:', limits.rateLimit.sync.resetAt); - console.log(' Is limited:', limits.rateLimit.sync.isLimited); + console.log('=== レート制限 ==='); + console.log('同期リクエスト:'); + console.log(' 制限:', limits.rateLimit.sync.limit); + console.log(' 残り:', limits.rateLimit.sync.remaining); + console.log(' リセット時間:', limits.rateLimit.sync.resetAt); + console.log(' 制限中:', limits.rateLimit.sync.isLimited); + + console.log('\n非同期リクエスト:'); + console.log(' 制限:', limits.rateLimit.async.limit); + console.log(' 残り:', limits.rateLimit.async.remaining); + console.log(' リセット時間:', limits.rateLimit.async.resetAt); + console.log(' 制限中:', limits.rateLimit.async.isLimited); + + console.log('\n=== 使用状況 ==='); + console.log('現在期間のコスト: $' + limits.usage.currentPeriodCost.toFixed(2)); + console.log('制限: $' + limits.usage.limit.toFixed(2)); + console.log('プラン:', limits.usage.plan); + + const percentUsed = (limits.usage.currentPeriodCost / limits.usage.limit) * 100; + console.log('使用率: ' + percentUsed.toFixed(1) + '%'); + + if (percentUsed > 80) { + console.warn('⚠️ 警告: 使用制限に近づいています!'); + } + } catch (error) { + console.error('使用状況確認エラー:', error); + } +} - console.log('\nAsync requests:'); - console.log(' Limit:', limits.rateLimit.async.limit); - console.log(' Remaining:', limits.rateLimit.async.remaining); - console.log(' Resets at:', limits.rateLimit.async.resetAt); - console.log(' Is limited:', limits.rateLimit.async.isLimited); +checkUsage(); - console.log('\n=== Usage ==='); - console.log('Current period cost: +``` ### Streaming Workflow Execution Execute workflows with real-time streaming responses: -```typescript +``` + +typescript import { SimStudioClient } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -834,7 +948,7 @@ async function executeWithStreaming() { const result = await client.executeWorkflow('workflow-id', { input: { message: 'Count to five' }, stream: true, - selectedOutputs: ['agent1.content'] // blockName.attribute形式を使用 + selectedOutputs: ['agent1.content'] // blockName.attribute 形式を使用 }); console.log('ワークフロー結果:', result); @@ -842,11 +956,13 @@ async function executeWithStreaming() { console.error('エラー:', error); } } + ``` The streaming response follows the Server-Sent Events (SSE) format: ``` + data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":"One"} data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":", two"} @@ -854,11 +970,14 @@ data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":", two"} data: {"event":"done","success":true,"output":{},"metadata":{"duration":610}} data: [DONE] + ``` **React Streaming Example:** -```typescript +``` + +typescript import { useState, useEffect } from 'react'; function StreamingWorkflow() { @@ -869,13 +988,13 @@ function StreamingWorkflow() { setLoading(true); setOutput(''); - // IMPORTANT: Make this API call from your backend server, not the browser - // Never expose your API key in client-side code + // 重要: このAPIコールはブラウザではなくバックエンドサーバーから行ってください + // クライアントサイドのコードにAPIキーを公開しないでください const response = await fetch('https://sim.ai/api/workflows/WORKFLOW_ID/execute', { method: 'POST', headers: { 'Content-Type': 'application/json', - 'X-API-Key': process.env.SIM_API_KEY! // Server-side environment variable only + 'X-API-Key': process.env.SIM_API_KEY! // サーバーサイドの環境変数のみ }, body: JSON.stringify({ message: 'Generate a story', @@ -907,10 +1026,10 @@ function StreamingWorkflow() { if (parsed.chunk) { setOutput(prev => prev + parsed.chunk); } else if (parsed.event === 'done') { - console.log('Execution complete:', parsed.metadata); + console.log('実行完了:', parsed.metadata); } } catch (e) { - // Skip invalid JSON + // 無効なJSONをスキップ } } } @@ -920,12 +1039,13 @@ function StreamingWorkflow() { return (
{output}
); } + ``` ## Getting Your API Key @@ -961,7 +1081,9 @@ function StreamingWorkflow() { The SDK is written in TypeScript and provides full type safety: -```typescript +``` + +typescript import { SimStudioClient, WorkflowExecutionResult, @@ -969,23 +1091,22 @@ import { SimStudioError } from 'simstudio-ts-sdk'; -// Type-safe client initialization +// 型安全なクライアント初期化 const client: SimStudioClient = new SimStudioClient({ apiKey: process.env.SIM_API_KEY! }); -// Type-safe workflow execution +// 型安全なワークフロー実行 const result: WorkflowExecutionResult = await client.executeWorkflow('workflow-id', { input: { message: 'Hello, TypeScript!' } }); -// Type-safe status checking +// 型安全なステータス確認 const status: WorkflowStatus = await client.getWorkflowStatus('workflow-id'); ``` -## License - +## ライセンス Apache-2.0 diff --git a/apps/docs/content/docs/ja/triggers/api.mdx b/apps/docs/content/docs/ja/triggers/api.mdx index 931d4da25f..9191f0d70f 100644 --- a/apps/docs/content/docs/ja/triggers/api.mdx +++ b/apps/docs/content/docs/ja/triggers/api.mdx @@ -22,9 +22,17 @@ APIトリガーは、ワークフローを安全なHTTPエンドポイントと /> -各パラメータに**入力フォーマット**フィールドを追加します。実行時の出力キーはスキーマを反映し、``でも利用できます。 +各パラメータに**入力フォーマット**フィールドを追加します。サポートされている型: -エディタでの手動実行は `value` 列を使用するため、リクエストを送信せずにテストできます。実行中、リゾルバーは `` と `` の両方に値を設定します。 +- **string** - テキスト値 +- **number** - 数値 +- **boolean** - 真/偽の値 +- **json** - JSONオブジェクト +- **files** - ファイルアップロード(``、``などでアクセス) + +ランタイム出力キーはスキーマを反映し、``の下で利用できます。 + +エディタでの手動実行では、リクエストを送信せずにテストできるように`value`列を使用します。実行中、リゾルバは``と``の両方に値を設定します。 ## リクエスト例 @@ -36,23 +44,23 @@ curl -X POST \ -d '{"userId":"demo-user","maxTokens":1024}' ``` -成功したレスポンスはエグゼキュータからシリアル化された実行結果を返します。エラーは検証、認証、またはワークフローの失敗を表示します。 +成功したレスポンスはエグゼキュータからのシリアル化された実行結果を返します。エラーは検証、認証、またはワークフローの失敗を表示します。 ## ストリーミングレスポンス -リアルタイムストリーミングを有効にすると、ワークフローの出力が生成されるたびに文字単位で受信できます。これはAIの応答をユーザーに段階的に表示するのに役立ちます。 +リアルタイムストリーミングを有効にすると、生成されたワークフロー出力を文字単位でリアルタイムに受信できます。これはAIの応答をユーザーに段階的に表示するのに役立ちます。 ### リクエストパラメータ -ストリーミングを有効にするには、これらのパラメータを追加してください: +ストリーミングを有効にするには、これらのパラメータを追加します: -- `stream` - Server-Sent Events (SSE)ストリーミングを有効にするには `true` に設定します +- `stream` - Server-Sent Events(SSE)ストリーミングを有効にするには`true`に設定 - `selectedOutputs` - ストリーミングするブロック出力の配列(例:`["agent1.content"]`) ### ブロック出力フォーマット -`blockName.attribute` フォーマットを使用して、ストリーミングするブロック出力を指定します: -- フォーマット:`"blockName.attribute"`(例:Agent 1ブロックの内容をストリーミングしたい場合は、`"agent1.content"` を使用します) +`blockName.attribute`フォーマットを使用して、ストリーミングするブロック出力を指定します: +- フォーマット:`"blockName.attribute"`(例:Agent 1ブロックの内容をストリーミングしたい場合は、`"agent1.content"`を使用) - ブロック名は大文字小文字を区別せず、スペースは無視されます ### リクエスト例 @@ -71,7 +79,7 @@ curl -X POST \ ### レスポンスフォーマット -ストリーミングレスポンスはServer-Sent Events (SSE)フォーマットを使用します: +ストリーミングレスポンスはServer-Sent Events(SSE)フォーマットを使用します: ``` data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":"One"} @@ -88,32 +96,28 @@ data: [DONE] 各イベントには以下が含まれます: - **ストリーミングチャンク**:`{"blockId": "...", "chunk": "text"}` - 生成されるリアルタイムテキスト - **最終イベント**:`{"event": "done", ...}` - 実行メタデータと完全な結果 -- **ターミネーター**:`[DONE]` - ストリーム終了を示す信号 +- **ターミネータ**:`[DONE]` - ストリーム終了を示す信号 ### 複数ブロックのストリーミング -`selectedOutputs` に複数のブロックが含まれる場合、各チャンクはどのブロックから生成されたかを示します: +`selectedOutputs`に複数のブロックが含まれる場合、各チャンクはどのブロックがそれを生成したかを示します: -```bash -curl -X POST \ - https://sim.ai/api/workflows/WORKFLOW_ID/execute \ - -H 'Content-Type: application/json' \ - -H 'X-API-Key: YOUR_KEY' \ - -d '{ - "message": "Process this request", - "stream": true, - "selectedOutputs": ["agent1.content", "agent2.content"] - }' +```json +{ + "type": "block", + "blockId": "1", + "content": "こんにちは!" +} ``` 各チャンクの `blockId` フィールドを使用して、出力を正しいUI要素にルーティングできます: -``` -data: {"blockId":"agent1-uuid","chunk":"Processing..."} - -data: {"blockId":"agent2-uuid","chunk":"Analyzing..."} - -data: {"blockId":"agent1-uuid","chunk":" complete"} +```json +{ + "type": "block", + "blockId": "chart1", + "content": "..." +} ``` ## 出力リファレンス @@ -123,8 +127,55 @@ data: {"blockId":"agent1-uuid","chunk":" complete"} | `` | 入力フォーマットで定義されたフィールド | | `` | 構造化されたリクエスト本文全体 | +### ファイルアップロードフォーマット + +APIは2つの形式でファイルを受け付けます: + +**1. Base64エンコードされたファイル**(SDKには推奨): + +```json +{ + "files": [{ + "data": "data:application/pdf;base64,JVBERi0xLjMKJcTl8uXrp...", + "name": "document.pdf" + }] +} +``` + +- 最大ファイルサイズ:ファイルあたり20MB +- ファイルはクラウドストレージにアップロードされ、すべてのプロパティを持つUserFileオブジェクトに変換されます + +**2. 直接URLリファレンス**: + +```json +{ + "files": [{ + "url": "https://example.com/document.pdf", + "name": "document.pdf" + }] +} +``` + +- ファイルはアップロードされず、URLが直接渡されます +- 既存のファイルを参照する場合に便利です + +### ファイルプロパティ + +ファイルについては、すべてのプロパティにアクセスできます: + +| プロパティ | 説明 | 型 | +|----------|-------------|------| +| `` | 署名付きダウンロードURL | string | +| `` | 元のファイル名 | string | +| `` | ファイルサイズ(バイト) | number | +| `` | MIMEタイプ | string | +| `` | アップロードタイムスタンプ(ISO 8601) | string | +| `` | URL有効期限タイムスタンプ(ISO 8601) | string | + +URLで参照されるファイルの場合、ファイルは当社のストレージにアップロードされないため、`uploadedAt` と `expiresAt` を除く同じプロパティが利用可能です。 + 入力フォーマットが定義されていない場合、エグゼキューターは `` でのみ生のJSONを公開します。 -ワークフローには1つのAPIトリガーのみ含めることができます。変更後は新しいデプロイメントを公開して、エンドポイントを最新の状態に保ってください。 +ワークフローには1つのAPIトリガーしか含めることができません。変更後は新しいデプロイメントを公開して、エンドポイントを最新の状態に保ってください。 diff --git a/apps/docs/content/docs/ja/triggers/chat.mdx b/apps/docs/content/docs/ja/triggers/chat.mdx index 8c9b6a4e45..0b1140d492 100644 --- a/apps/docs/content/docs/ja/triggers/chat.mdx +++ b/apps/docs/content/docs/ja/triggers/chat.mdx @@ -24,19 +24,30 @@ import { Image } from '@/components/ui/image' このトリガーは、下流のブロックが参照できる3つのフィールドを書き込みます: -| 参照 | 説明 | -|-----------|-------------| -| `` | 最新のユーザーメッセージ | -| `` | 会話スレッドID | -| `` | オプションのアップロードファイル | +| リファレンス | 説明 | 型 | +|-----------|-------------|------| +| `` | 最新のユーザーメッセージ | string | +| `` | 会話スレッドID | string | +| `` | オプションのアップロードファイル | files配列 | -ファイルには `name`、`mimeType`、および署名付きダウンロード `url` が含まれます。 +### ファイルプロパティ + +配列インデックスを使用して個々のファイルプロパティにアクセスします: + +| プロパティ | 説明 | 型 | +|----------|-------------|------| +| `` | 署名付きダウンロードURL | string | +| `` | 元のファイル名 | string | +| `` | ファイルサイズ(バイト単位) | number | +| `` | MIMEタイプ | string | +| `` | アップロードタイムスタンプ(ISO 8601形式) | string | +| `` | URL有効期限タイムスタンプ(ISO 8601形式) | string | ## 使用上の注意 1. ワークフローごとにチャットトリガーブロックを1つ追加します。 -2. ワークフローをチャットモードでデプロイします。 -3. デプロイメントリンクを共有します—各返信は同じ会話IDを再利用するため、ワークフローはコンテキストを保持できます。 +2. チャットモードでワークフローをデプロイします。 +3. デプロイメントリンクを共有します—すべての返信は同じ会話IDを再利用するため、ワークフローはコンテキストを保持できます。 ビルダーは同じワークフロー内の複数のチャットトリガーブロックをブロックします。 diff --git a/apps/docs/content/docs/zh/blocks/guardrails.mdx b/apps/docs/content/docs/zh/blocks/guardrails.mdx new file mode 100644 index 0000000000..0e299a4131 --- /dev/null +++ b/apps/docs/content/docs/zh/blocks/guardrails.mdx @@ -0,0 +1,317 @@ +--- +title: Guardrails +--- + +import { Callout } from 'fumadocs-ui/components/callout' +import { Step, Steps } from 'fumadocs-ui/components/steps' +import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Image } from '@/components/ui/image' +import { Video } from '@/components/ui/video' + +Guardrails 模块通过针对多种验证类型检查内容,验证并保护您的 AI 工作流。确保数据质量,防止幻觉,检测 PII,并在内容进入工作流之前强制执行格式要求。 + +
+ Guardrails 模块 +
+ +## 概述 + +Guardrails 模块使您能够: + + + + 验证 JSON 结构:确保 LLM 输出在解析之前是有效的 JSON + + + 匹配正则表达式模式:验证内容是否符合特定格式(如电子邮件、电话号码、URL 等) + + + 检测幻觉:使用 RAG + LLM 评分验证 AI 输出是否符合知识库内容 + + + 检测 PII:识别并可选择性地屏蔽 40 多种实体类型的个人身份信息 + + + +## 验证类型 + +### JSON 验证 + +验证内容是否为正确格式的 JSON。非常适合确保结构化的 LLM 输出可以安全解析。 + +**使用场景:** +- 在解析之前验证来自 Agent 模块的 JSON 响应 +- 确保 API 负载格式正确 +- 检查结构化数据的完整性 + +**输出:** +- `passed`:如果是有效的 JSON,则为 `true`,否则为 `false` +- `error`:如果验证失败,则为错误消息(例如,“无效的 JSON:意外的标记...”) + +### 正则表达式验证 + +检查内容是否符合指定的正则表达式模式。 + +**使用场景:** +- 验证电子邮件地址 +- 检查电话号码格式 +- 验证 URL 或自定义标识符 +- 强制执行特定文本模式 + +**配置:** +- **正则表达式模式**:要匹配的正则表达式(例如,`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}--- +title: Guardrails +--- + +import { Callout } from 'fumadocs-ui/components/callout' +import { Step, Steps } from 'fumadocs-ui/components/steps' +import { Tab, Tabs } from 'fumadocs-ui/components/tabs' +import { Image } from '@/components/ui/image' +import { Video } from '@/components/ui/video' + +Guardrails 模块通过针对多种验证类型检查内容,验证并保护您的 AI 工作流。确保数据质量,防止幻觉,检测 PII,并在内容进入工作流之前强制执行格式要求。 + +
+ Guardrails 模块 +
+ +## 概述 + +Guardrails 模块使您能够: + + + + 验证 JSON 结构:确保 LLM 输出在解析之前是有效的 JSON + + + 匹配正则表达式模式:验证内容是否符合特定格式(如电子邮件、电话号码、URL 等) + + + 检测幻觉:使用 RAG + LLM 评分验证 AI 输出是否符合知识库内容 + + + 检测 PII:识别并可选择性地屏蔽 40 多种实体类型的个人身份信息 + + + +## 验证类型 + +### JSON 验证 + +验证内容是否为正确格式的 JSON。非常适合确保结构化的 LLM 输出可以安全解析。 + +**使用场景:** +- 在解析之前验证来自 Agent 模块的 JSON 响应 +- 确保 API 负载格式正确 +- 检查结构化数据的完整性 + +**输出:** +- `passed`:如果是有效的 JSON,则为 `true`,否则为 `false` +- `error`:如果验证失败,则为错误消息(例如,“无效的 JSON:意外的标记...”) + +### 正则表达式验证 + +检查内容是否符合指定的正则表达式模式。 + +**使用场景:** +- 验证电子邮件地址 +- 检查电话号码格式 +- 验证 URL 或自定义标识符 +- 强制执行特定文本模式 + +**配置:** +- **正则表达式模式**:要匹配的正则表达式(例如, 用于电子邮件) + +**输出:** +- `passed`:如果内容符合模式,则为 `true`,否则为 `false` +- `error`:如果验证失败,显示错误信息 + +### 幻觉检测 + +使用基于检索增强生成 (RAG) 和 LLM 评分的方法,检测 AI 生成的内容是否与您的知识库相矛盾或不符合实际。 + +**工作原理:** +1. 查询您的知识库以获取相关上下文 +2. 将 AI 输出和检索到的上下文发送到 LLM +3. LLM 分配一个置信评分(0-10 分制) + - **0** = 完全幻觉(完全不符合实际) + - **10** = 完全符合实际(完全由知识库支持) +4. 如果评分 ≥ 阈值(默认值:3),验证通过 + +**配置:** +- **知识库**:从现有知识库中选择 +- **模型**:选择用于评分的 LLM(需要强大的推理能力,推荐 GPT-4o、Claude 3.7 Sonnet) +- **API 密钥**:所选 LLM 提供商的身份验证(托管/Ollama 模型自动隐藏) +- **置信阈值**:通过验证的最低评分(0-10,默认值:3) +- **Top K**(高级):检索的知识库块数量(默认值:10) + +**输出:** +- `passed`:如果置信评分 ≥ 阈值,则为 `true` +- `score`:置信评分(0-10) +- `reasoning`:LLM 对评分的解释 +- `error`:如果验证失败,显示错误信息 + +**使用场景:** +- 验证代理响应是否符合文档 +- 确保客户支持回答的事实准确性 +- 验证生成的内容是否与源材料一致 +- RAG 应用的质量控制 + +### PII 检测 + +使用 Microsoft Presidio 检测个人身份信息 (PII)。支持 40 多种实体类型,覆盖多个国家和语言。 + +
+
+ +**工作原理:** +1. 使用模式匹配和 NLP 扫描内容中的 PII 实体 +2. 返回检测到的实体及其位置和置信评分 +3. 可选择在输出中屏蔽检测到的 PII + +**配置:** +- **要检测的 PII 类型**:通过模态选择器从分组类别中选择 + - **常见**:姓名、电子邮件、电话、信用卡、IP 地址等 + - **美国**:社会安全号码 (SSN)、驾驶执照、护照等 + - **英国**:NHS 编号、国家保险号码 + - **西班牙**:NIF、NIE、CIF + - **意大利**:税号、驾驶执照、增值税号 + - **波兰**:PESEL、NIP、REGON + - **新加坡**:NRIC/FIN、UEN + - **澳大利亚**:ABN、ACN、TFN、Medicare + - **印度**:Aadhaar、PAN、护照、选民编号 +- **模式:** + - **检测**:仅识别 PII(默认) + - **掩码**:将检测到的 PII 替换为掩码值 +- **语言:**检测语言(默认:英语) + +**输出:** +- `passed`:如果检测到任何选定的 PII 类型,则为 `false` +- `detectedEntities`:包含类型、位置和置信度的检测到的 PII 数组 +- `maskedText`:带有 PII 掩码的内容(仅当模式为 "掩码" 时) +- `error`:如果验证失败的错误消息 + +**使用场景:** +- 阻止包含敏感个人信息的内容 +- 在记录或存储数据之前对 PII 进行掩码处理 +- 符合 GDPR、HIPAA 和其他隐私法规 +- 在处理之前清理用户输入 + +## 配置 + +### 要验证的内容 + +要验证的输入内容。通常来自: +- 代理块输出:`` +- 功能块结果:`` +- API 响应:`` +- 任何其他块输出 + +### 验证类型 + +从四种验证类型中选择: +- **有效 JSON**:检查内容是否为正确格式的 JSON +- **正则匹配**:验证内容是否匹配正则表达式模式 +- **幻觉检查**:通过 LLM 评分与知识库验证 +- **PII 检测**:检测并可选地掩码个人身份信息 + +## 输出 + +所有验证类型返回: + +- **``**:布尔值,指示验证是否通过 +- **``**:执行的验证类型 +- **``**:被验证的原始输入 +- **``**:如果验证失败的错误信息(可选) + +按类型的其他输出: + +**幻觉检查:** +- **``**:置信分数(0-10) +- **``**:LLM 的解释 + +**PII 检测:** +- **``**:检测到的 PII 实体数组 +- **``**:已屏蔽 PII 的内容(如果模式为 "Mask") + +## 示例用例 + +### 在解析前验证 JSON + +
+

场景:确保代理输出为有效的 JSON

+
    +
  1. 代理生成结构化的 JSON 响应
  2. +
  3. Guardrails 验证 JSON 格式
  4. +
  5. 条件块检查 ``
  6. +
  7. 如果通过 → 解析并使用数据,如果失败 → 重试或处理错误
  8. +
+
+ +### 防止幻觉 + +
+

场景:验证客户支持的回复

+
    +
  1. 代理生成对客户问题的回复
  2. +
  3. Guardrails 根据支持文档知识库进行检查
  4. +
  5. 如果置信分数 ≥ 3 → 发送回复
  6. +
  7. 如果置信分数 \< 3 → 标记为人工审核
  8. +
+
+ +### 阻止用户输入中的 PII + +
+

场景:清理用户提交的内容

+
    +
  1. 用户提交带有文本内容的表单
  2. +
  3. Guardrails 检测 PII(电子邮件、电话号码、社会安全号码等)
  4. +
  5. 如果检测到 PII → 拒绝提交或屏蔽敏感数据
  6. +
  7. 如果没有 PII → 正常处理
  8. +
+
+ +
+
+ +### 验证电子邮件格式 + +
+

场景:检查电子邮件地址格式

+
    +
  1. 代理从文本中提取电子邮件
  2. +
  3. Guardrails 使用正则表达式模式进行验证
  4. +
  5. 如果有效 → 使用电子邮件进行通知
  6. +
  7. 如果无效 → 请求更正
  8. +
+
+ +## 最佳实践 + +- **与条件块链式使用**:使用 `` 根据验证结果分支工作流逻辑 +- **在解析前进行 JSON 验证**:在尝试解析 LLM 输出之前,始终验证 JSON 结构 +- **选择合适的 PII 类型**:仅选择与您的用例相关的 PII 实体类型以获得更好的性能 +- **设置合理的置信度阈值**:对于幻觉检测,根据您的准确性要求调整阈值(更高 = 更严格) +- **使用强大的模型进行幻觉检测**:GPT-4o 或 Claude 3.7 Sonnet 提供更准确的置信度评分 +- **对日志中的 PII 进行掩码**:当需要记录或存储可能包含 PII 的内容时,使用“掩码”模式 +- **测试正则表达式模式**:在部署到生产环境之前,彻底验证您的正则表达式模式 +- **监控验证失败**:跟踪 `` 消息以识别常见的验证问题 + + + Guardrails 验证在您的工作流中同步进行。对于幻觉检测,如果延迟至关重要,请选择更快的模型(如 GPT-4o-mini)。 + diff --git a/apps/docs/content/docs/zh/execution/costs.mdx b/apps/docs/content/docs/zh/execution/costs.mdx index 4ada972604..69f05f8573 100644 --- a/apps/docs/content/docs/zh/execution/costs.mdx +++ b/apps/docs/content/docs/zh/execution/costs.mdx @@ -170,11 +170,43 @@ curl -X GET -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" htt | **团队** | $500(池化) | 50 同步, 100 异步 | | **企业** | 自定义 | 自定义 | +## 计费模型 + +Sim 使用 **基础订阅 + 超额** 的计费模型: + +### 工作原理 + +**专业计划($20/月):** +- 月订阅包含 $20 的使用额度 +- 使用低于 $20 → 无额外费用 +- 使用超过 $20 → 月底支付超额部分 +- 示例:$35 的使用 = $20(订阅)+ $15(超额) + +**团队计划($40/人/月):** +- 团队成员的使用额度合并计算 +- 超额费用根据团队总使用量计算 +- 组织所有者收到一张账单 + +**企业计划:** +- 固定月费,无超额费用 +- 根据协议定制使用限制 + +### 阈值计费 + +当未结算的超额费用达到 $50 时,Sim 会自动结算全部未结算金额。 + +**示例:** +- 第 10 天:$70 超额 → 立即结算 $70 +- 第 15 天:额外使用 $35(总计 $105)→ 已结算,无需操作 +- 第 20 天:再使用 $50(总计 $155,未结算 $85)→ 立即结算 $85 + +这可以将大额超额费用分散到整个月,而不是在周期末一次性结算。 + ## 成本管理最佳实践 -1. **定期监控**:经常检查您的使用仪表板,避免意外情况 -2. **设置预算**:使用计划限制作为支出控制的护栏 -3. **优化工作流程**:审查高成本的执行情况,优化提示或模型选择 +1. **定期监控**:经常检查您的使用仪表板,避免意外 +2. **设定预算**:使用计划限制作为支出控制的参考 +3. **优化工作流**:审查高成本的执行,优化提示或模型选择 4. **使用合适的模型**:根据任务需求匹配模型复杂度 5. **批量处理相似任务**:尽可能合并多个请求以减少开销 diff --git a/apps/docs/content/docs/zh/sdks/python.mdx b/apps/docs/content/docs/zh/sdks/python.mdx index 8ca6874295..5a59d69d70 100644 --- a/apps/docs/content/docs/zh/sdks/python.mdx +++ b/apps/docs/content/docs/zh/sdks/python.mdx @@ -433,7 +433,7 @@ with SimStudioClient(api_key=os.getenv("SIM_API_KEY")) as client: from simstudio import SimStudioClient import os -client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) +client = SimStudioClient(api_key=os.getenv("SIM_API_KEY")) def execute_workflows_batch(workflow_data_pairs): """Execute multiple workflows with different input data.""" @@ -660,7 +660,7 @@ def stream_workflow(): 'https://sim.ai/api/workflows/WORKFLOW_ID/execute', headers={ 'Content-Type': 'application/json', - 'X-API-Key': os.getenv('SIM_API_KEY') + 'X-API-Key': os.getenv('SIM_API_KEY') }, json={ 'message': 'Generate a story', diff --git a/apps/docs/content/docs/zh/sdks/typescript.mdx b/apps/docs/content/docs/zh/sdks/typescript.mdx index ba56120459..df768e26ab 100644 --- a/apps/docs/content/docs/zh/sdks/typescript.mdx +++ b/apps/docs/content/docs/zh/sdks/typescript.mdx @@ -604,28 +604,114 @@ async function executeClientSideWorkflow() { }); console.log('Workflow result:', result); - + // Update UI with result - document.getElementById('result')!.textContent = + document.getElementById('result')!.textContent = JSON.stringify(result.output, null, 2); } catch (error) { console.error('Error:', error); } } +``` + +### 文件上传 + +文件对象会被自动检测并转换为 base64 格式。请将它们包含在输入中,字段名称需与工作流的 API 触发输入格式匹配。 + +SDK 会将文件对象转换为以下格式: + +```typescript +{ + type: 'file', + data: 'data:mime/type;base64,base64data', + name: 'filename', + mime: 'mime/type' +} +``` + +或者,您可以使用 URL 格式手动提供文件: + +```typescript +{ + type: 'url', + data: 'https://example.com/file.pdf', + name: 'file.pdf', + mime: 'application/pdf' +} +``` + + + + + ```typescript + import { SimStudioClient } from 'simstudio-ts-sdk'; + + const client = new SimStudioClient({ + apiKey: process.env.NEXT_PUBLIC_SIM_API_KEY! + }); + + // From file input + async function handleFileUpload(event: Event) { + const input = event.target as HTMLInputElement; + const files = Array.from(input.files || []); + + // Include files under the field name from your API trigger's input format + const result = await client.executeWorkflow('workflow-id', { + input: { + documents: files, // Must match your workflow's "files" field name + instructions: 'Analyze these documents' + } + }); + + console.log('Result:', result); + } + ``` + + + + + ```typescript + import { SimStudioClient } from 'simstudio-ts-sdk'; + import fs from 'fs'; + + const client = new SimStudioClient({ + apiKey: process.env.SIM_API_KEY! + }); + + // Read file and create File object + const fileBuffer = fs.readFileSync('./document.pdf'); + const file = new File([fileBuffer], 'document.pdf', { + type: 'application/pdf' + }); + + // Include files under the field name from your API trigger's input format + const result = await client.executeWorkflow('workflow-id', { + input: { + documents: [file], // Must match your workflow's "files" field name + query: 'Summarize this document' + } + }); + ``` -// Attach to button click + + + +// 绑定到按钮点击事件 document.getElementById('executeBtn')?.addEventListener('click', executeClientSideWorkflow); + ``` - 在浏览器中使用 SDK 时,请注意不要暴露敏感的 API 密钥。建议使用后端代理或具有有限权限的公共 API 密钥。 + When using the SDK in the browser, be careful not to expose sensitive API keys. Consider using a backend proxy or public API keys with limited permissions. -### React Hook 示例 +### React Hook Example -为工作流执行创建自定义 React hook: +Create a custom React hook for workflow execution: -```typescript +``` + +typescript import { useState, useCallback } from 'react'; import { SimStudioClient, WorkflowExecutionResult } from 'simstudio-ts-sdk'; @@ -657,7 +743,7 @@ export function useWorkflow(): UseWorkflowResult { }); setResult(workflowResult); } catch (err) { - setError(err instanceof Error ? err : new Error('Unknown error')); + setError(err instanceof Error ? err : new Error('未知错误')); } finally { setLoading(false); } @@ -671,39 +757,42 @@ export function useWorkflow(): UseWorkflowResult { }; } -// Usage in component +// 在组件中使用 function WorkflowComponent() { const { result, loading, error, executeWorkflow } = useWorkflow(); const handleExecute = () => { executeWorkflow('my-workflow-id', { - message: 'Hello from React!' + message: '来自 React 的问候!' }); }; return (
- {error &&
Error: {error.message}
} + {error &&
错误: {error.message}
} {result && (
-

Result:

+

结果:

{JSON.stringify(result, null, 2)}
)}
); } + ``` -### 异步工作流执行 +### Async Workflow Execution -为长时间运行的任务异步执行工作流: +Execute workflows asynchronously for long-running tasks: -```typescript +``` + +typescript import { SimStudioClient, AsyncExecutionResult } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -712,47 +801,50 @@ const client = new SimStudioClient({ async function executeAsync() { try { - // Start async execution + // 开始异步执行 const result = await client.executeWorkflow('workflow-id', { input: { data: 'large dataset' }, - async: true // Execute asynchronously + async: true // 异步执行 }); - // Check if result is an async execution + // 检查结果是否为异步执行 if ('taskId' in result) { - console.log('Task ID:', result.taskId); - console.log('Status endpoint:', result.links.status); + console.log('任务 ID:', result.taskId); + console.log('状态端点:', result.links.status); - // Poll for completion + // 轮询完成状态 let status = await client.getJobStatus(result.taskId); while (status.status === 'queued' || status.status === 'processing') { - console.log('Current status:', status.status); - await new Promise(resolve => setTimeout(resolve, 2000)); // Wait 2 seconds + console.log('当前状态:', status.status); + await new Promise(resolve => setTimeout(resolve, 2000)); // 等待 2 秒 status = await client.getJobStatus(result.taskId); } if (status.status === 'completed') { - console.log('Workflow completed!'); - console.log('Output:', status.output); - console.log('Duration:', status.metadata.duration); + console.log('工作流已完成!'); + console.log('输出:', status.output); + console.log('持续时间:', status.metadata.duration); } else { - console.error('Workflow failed:', status.error); + console.error('工作流失败:', status.error); } } } catch (error) { - console.error('Error:', error); + console.error('错误:', error); } } executeAsync(); + ``` -### 速率限制和重试 +### Rate Limiting and Retry -通过指数退避自动处理速率限制: +Handle rate limits automatically with exponential backoff: -```typescript +``` + +typescript import { SimStudioClient, SimStudioError } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -761,7 +853,7 @@ const client = new SimStudioClient({ async function executeWithRetryHandling() { try { - // Automatically retries on rate limit + // 在速率限制时自动重试 const result = await client.executeWithRetry('workflow-id', { input: { message: 'Process this' } }, { @@ -771,26 +863,29 @@ async function executeWithRetryHandling() { backoffMultiplier: 2 }); - console.log('Success:', result); + console.log('成功:', result); } catch (error) { if (error instanceof SimStudioError && error.code === 'RATE_LIMIT_EXCEEDED') { - console.error('Rate limit exceeded after all retries'); + console.error('在所有重试后速率限制已超出'); - // Check rate limit info + // 检查速率限制信息 const rateLimitInfo = client.getRateLimitInfo(); if (rateLimitInfo) { - console.log('Rate limit resets at:', new Date(rateLimitInfo.reset * 1000)); + console.log('速率限制重置时间:', new Date(rateLimitInfo.reset * 1000)); } } } } + ``` -### 使用监控 +### Usage Monitoring -监控您的账户使用情况和限制: +Monitor your account usage and limits: -```typescript +``` + +typescript import { SimStudioClient } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -801,27 +896,46 @@ async function checkUsage() { try { const limits = await client.getUsageLimits(); - console.log('=== Rate Limits ==='); - console.log('Sync requests:'); - console.log(' Limit:', limits.rateLimit.sync.limit); - console.log(' Remaining:', limits.rateLimit.sync.remaining); - console.log(' Resets at:', limits.rateLimit.sync.resetAt); - console.log(' Is limited:', limits.rateLimit.sync.isLimited); + console.log('=== 速率限制 ==='); + console.log('同步请求:'); + console.log(' 限制:', limits.rateLimit.sync.limit); + console.log(' 剩余:', limits.rateLimit.sync.remaining); + console.log(' 重置时间:', limits.rateLimit.sync.resetAt); + console.log(' 是否受限:', limits.rateLimit.sync.isLimited); + + console.log('\n异步请求:'); + console.log(' 限制:', limits.rateLimit.async.limit); + console.log(' 剩余:', limits.rateLimit.async.remaining); + console.log(' 重置时间:', limits.rateLimit.async.resetAt); + console.log(' 是否受限:', limits.rateLimit.async.isLimited); + + console.log('\n=== 使用情况 ==='); + console.log('当前周期费用: ¥' + limits.usage.currentPeriodCost.toFixed(2)); + console.log('限制: ¥' + limits.usage.limit.toFixed(2)); + console.log('计划:', limits.usage.plan); + + const percentUsed = (limits.usage.currentPeriodCost / limits.usage.limit) * 100; + console.log('使用率: ' + percentUsed.toFixed(1) + '%'); + + if (percentUsed > 80) { + console.warn('⚠️ 警告: 您的使用量接近限制!'); + } + } catch (error) { + console.error('检查使用情况时出错:', error); + } +} - console.log('\nAsync requests:'); - console.log(' Limit:', limits.rateLimit.async.limit); - console.log(' Remaining:', limits.rateLimit.async.remaining); - console.log(' Resets at:', limits.rateLimit.async.resetAt); - console.log(' Is limited:', limits.rateLimit.async.isLimited); +checkUsage(); - console.log('\n=== Usage ==='); - console.log('Current period cost: +``` ### Streaming Workflow Execution Execute workflows with real-time streaming responses: -```typescript +``` + +typescript import { SimStudioClient } from 'simstudio-ts-sdk'; const client = new SimStudioClient({ @@ -842,11 +956,13 @@ async function executeWithStreaming() { console.error('错误:', error); } } + ``` The streaming response follows the Server-Sent Events (SSE) format: ``` + data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":"One"} data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":", two"} @@ -854,11 +970,14 @@ data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":", two"} data: {"event":"done","success":true,"output":{},"metadata":{"duration":610}} data: [DONE] + ``` **React Streaming Example:** -```typescript +``` + +typescript import { useState, useEffect } from 'react'; function StreamingWorkflow() { @@ -869,7 +988,7 @@ function StreamingWorkflow() { setLoading(true); setOutput(''); - // 重要提示:请从您的后端服务器发起此 API 调用,而不是从浏览器发起 + // 重要: 从您的后端服务器发起此 API 调用,而不是从浏览器 // 切勿在客户端代码中暴露您的 API 密钥 const response = await fetch('https://sim.ai/api/workflows/WORKFLOW_ID/execute', { method: 'POST', @@ -926,6 +1045,7 @@ function StreamingWorkflow() { ); } + ``` ## Getting Your API Key @@ -961,7 +1081,9 @@ function StreamingWorkflow() { The SDK is written in TypeScript and provides full type safety: -```typescript +``` + +typescript import { SimStudioClient, WorkflowExecutionResult, diff --git a/apps/docs/content/docs/zh/triggers/api.mdx b/apps/docs/content/docs/zh/triggers/api.mdx index e5f6ef72ef..7dd5b2a365 100644 --- a/apps/docs/content/docs/zh/triggers/api.mdx +++ b/apps/docs/content/docs/zh/triggers/api.mdx @@ -22,9 +22,17 @@ API 触发器将您的工作流公开为一个安全的 HTTP 端点。将 JSON /> -为每个参数添加一个 **输入格式** 字段。运行时输出键会镜像该模式,并且也可以在 `` 下使用。 +为每个参数添加一个 **输入格式** 字段。支持的类型: -在编辑器中手动运行使用 `value` 列,因此您可以在不发送请求的情况下进行测试。在执行过程中,解析器会填充 `` 和 ``。 +- **string** - 文本值 +- **number** - 数值 +- **boolean** - 真/假值 +- **json** - JSON 对象 +- **files** - 文件上传(通过 ``、`` 等访问) + +运行时输出键与架构相对应,并可通过 `` 获取。 + +编辑器中的手动运行使用 `value` 列,因此您可以在不发送请求的情况下进行测试。在执行期间,解析器会填充 `` 和 ``。 ## 请求示例 @@ -55,7 +63,7 @@ curl -X POST \ - 格式:`"blockName.attribute"`(例如,如果您想流式传输 Agent 1 块的内容,可以使用 `"agent1.content"`) - 块名称不区分大小写,空格会被忽略 -### 示例请求 +### 请求示例 ```bash curl -X POST \ @@ -92,7 +100,7 @@ data: [DONE] ### 多块流式传输 -当 `selectedOutputs` 包含多个块时,每个块会指示其来源: +当 `selectedOutputs` 包含多个块时,每个块会指示其来源块: ```bash curl -X POST \ @@ -118,11 +126,62 @@ data: {"blockId":"agent1-uuid","chunk":" complete"} ## 输出参考 -| 参考 | 描述 | +| 引用 | 描述 | |-----------|-------------| | `` | 输入格式中定义的字段 | | `` | 整个结构化请求体 | +### 文件上传格式 + +API 接受两种格式的文件: + +**1. Base64 编码文件**(推荐用于 SDK): + +```json +{ + "documents": [{ + "type": "file", + "data": "data:application/pdf;base64,JVBERi0xLjQK...", + "name": "document.pdf", + "mime": "application/pdf" + }] +} +``` + +- 最大文件大小:每个文件 20MB +- 文件上传到云存储并转换为具有所有属性的 UserFile 对象 + +**2. 直接 URL 引用**: + +```json +{ + "documents": [{ + "type": "url", + "data": "https://example.com/document.pdf", + "name": "document.pdf", + "mime": "application/pdf" + }] +} +``` + +- 文件未上传,URL 直接传递 +- 适用于引用现有文件 + +### 文件属性 + +对于文件,可以访问所有属性: + +| 属性 | 描述 | 类型 | +|----------|-------------|------| +| `` | 签名下载 URL | string | +| `` | 原始文件名 | string | +| `` | 文件大小(字节) | number | +| `` | MIME 类型 | string | +| `` | 上传时间戳(ISO 8601) | string | +| `` | URL 过期时间戳(ISO 8601) | string | + +对于 URL 引用的文件,除了 `uploadedAt` 和 `expiresAt` 外,其他属性均可用,因为文件未上传到我们的存储中。 + 如果未定义输入格式,执行器仅在 `` 处暴露原始 JSON。 diff --git a/apps/docs/content/docs/zh/triggers/chat.mdx b/apps/docs/content/docs/zh/triggers/chat.mdx index d48b75b97d..aba0a11665 100644 --- a/apps/docs/content/docs/zh/triggers/chat.mdx +++ b/apps/docs/content/docs/zh/triggers/chat.mdx @@ -24,20 +24,31 @@ import { Image } from '@/components/ui/image' 触发器会写入三个字段,供下游模块引用: -| 引用 | 描述 | -|-----------|-------------| -| `` | 最新的用户消息 | -| `` | 对话线程 ID | -| `` | 可选的上传文件 | +| 参考 | 描述 | 类型 | +|-----------|-------------|------| +| `` | 最新用户消息 | string | +| `` | 会话线程 ID | string | +| `` | 可选上传文件 | 文件数组 | -文件包括 `name`、`mimeType`,以及一个带签名的下载链接 `url`。 +### 文件属性 + +使用数组索引访问单个文件属性: + +| 属性 | 描述 | 类型 | +|----------|-------------|------| +| `` | 签名下载 URL | string | +| `` | 原始文件名 | string | +| `` | 文件大小(字节) | number | +| `` | MIME 类型 | string | +| `` | 上传时间戳(ISO 8601) | string | +| `` | URL 过期时间戳(ISO 8601) | string | ## 使用说明 -1. 每个工作流添加一个聊天触发器模块。 -2. 以聊天模式部署工作流。 -3. 分享部署链接——每次回复都会重用对话 ID,以便工作流保持上下文。 +1. 每个工作流添加一个聊天触发器块。 +2. 在聊天模式下部署工作流。 +3. 分享部署链接——每次回复都会重用会话 ID,以便工作流保持上下文。 -构建器会阻止在同一工作流中添加多个聊天触发器模块。 +构建器会阻止在同一工作流中使用多个聊天触发器块。 diff --git a/apps/docs/i18n.lock b/apps/docs/i18n.lock index 4ef71f624c..5e68358420 100644 --- a/apps/docs/i18n.lock +++ b/apps/docs/i18n.lock @@ -2331,73 +2331,84 @@ checksums: content/98: 6bd60468d8cc072c5fe4214481fa9f60 content/99: a81d7cd4a644a0061dad3a5973b4fe06 content/100: 981447969a71fd038049e9d9f40f4f8c - content/101: 531941216d31cb1947367c3c02127baa - content/102: bf1afa789fdfa5815faaf43574341e90 - content/103: 5f2fe55d098d4e4f438af595708b2280 - content/104: 41b8f7cf8899a0e92e255a3f845f9584 - content/105: 61ddd890032078ffd2da931b1d153b6d - content/106: 7873aa7487bc3e8a4826d65c1760a4a0 - content/107: 98182d9aabe14d5bad43a5ee76a75eab - content/108: 2bdb01e4bcb08b1d99f192acf8e2fba7 - content/109: 7079d9c00b1e1882c329b7e9b8f74552 - content/110: 0f9d65eaf6e8de43c3d5fa7e62bc838d - content/111: 58c8e9d2d0ac37efd958203b8fbc8193 - content/112: 7859d36a7a6d0122c0818b28ee29aa3e - content/113: ce185e7b041b8f95ebc11370d3e0aad9 - content/114: 701e9bf4fd4d0669da0584eac5bd96e0 - content/115: d1bab8ec5a51a9da5464eb47e2a16b50 - content/116: da658275cc81a20f9cf7e4c66c7af1e3 - content/117: 377d7c99a5df4b72166946573f7210b8 - content/118: 3afc03a5ab1dc9db2bfa092b0ac4826a - content/119: 18ddfcaf2be4a6f1d9819407dad9ce7c - content/120: 2f6263b2e95f09f7e4842453f4bf4a0a - content/121: 4603578d6b314b662f45564a34ca430d - content/122: cf4c97eb254d0bd6ea6633344621c2c2 - content/123: 7b4640989fab002039936156f857eb21 - content/124: 65ca9f08745b47b4cce8ea8247d043bf - content/125: 162b4180611ff0a53b782e4dc8109293 - content/126: 6b367a189eb53cb198e3666023def89c - content/127: dbb2125cefcf618849600c1eccae8a64 - content/128: 04eedda0da3767b06e6017c559e05414 - content/129: 661688450606eb09d8faee1468e88331 - content/130: 8ff8367c3246103b3e3e02499e34ae0b - content/131: 44678bda9166f746da1d61b694ced482 - content/132: a5e75db27c0a901f4cacf6598f450e6c - content/133: d1bab8ec5a51a9da5464eb47e2a16b50 - content/134: da658275cc81a20f9cf7e4c66c7af1e3 - content/135: 377d7c99a5df4b72166946573f7210b8 - content/136: 3afc03a5ab1dc9db2bfa092b0ac4826a - content/137: 18ddfcaf2be4a6f1d9819407dad9ce7c - content/138: 2f6263b2e95f09f7e4842453f4bf4a0a - content/139: 4603578d6b314b662f45564a34ca430d - content/140: cf4c97eb254d0bd6ea6633344621c2c2 - content/141: 7b4640989fab002039936156f857eb21 - content/142: 65ca9f08745b47b4cce8ea8247d043bf - content/143: 162b4180611ff0a53b782e4dc8109293 - content/144: 6b367a189eb53cb198e3666023def89c - content/145: dbb2125cefcf618849600c1eccae8a64 - content/146: 04eedda0da3767b06e6017c559e05414 - content/147: 661688450606eb09d8faee1468e88331 - content/148: 8ff8367c3246103b3e3e02499e34ae0b - content/149: 44678bda9166f746da1d61b694ced482 - content/150: 192a89879084dd7a74a6f44bcecae958 - content/151: 41c2bb95317d7c0421817a2b1a68cc09 - content/152: 4c95f9fa55f698f220577380dff95011 - content/153: 9ef273d776aada1b2cff3452f08ff985 - content/154: 100e12673551d4ceb5b906b1b9c65059 - content/155: ce253674cd7c49320203cda2bdd3685b - content/156: 8910afcea8c205a28256eb30de6a1f26 - content/157: 4d7ad757d2c70fdff7834146d38dddd8 - content/158: a88260a5b5e23da73e4534376adeb193 - content/159: e5e2329cdc226186fe9d44767528a4a0 - content/160: 1773624e9ac3d5132b505894ef51977e - content/161: d62c9575cc66feec7589fba95c9f7aee - content/162: 7af652c5407ae7e156ab27b21a4f26d3 - content/163: 4aa69b29cca745389dea8cd74eba4f83 - content/164: 46877074b69519165997fa0968169611 - content/165: 2e81908c18033109ac82a054b3fafd3d - content/166: ecd571818ddf3d31b08b80a25958a662 - content/167: 7dcdf2fbf3fce3f94987046506e12a9b + content/101: c4a515e993f75288ac915094c80cc1df + content/102: 23e5e8228c45d58c3b16af1dccdaf598 + content/103: cab7213a23e59504d834d347c944b685 + content/104: fcb1568f1adf19ac5a706001a84cad91 + content/105: 7b486d79adc6500458cf8d4fb0c3ada8 + content/106: 531ba61df0fffebc44fc6ebe9b9b08b0 + content/107: 4267ac9375ea48bd994758885c0e05c9 + content/108: ae7b4696ba7e9edf4b192fbab90d8e45 + content/109: 0a7f8dfd0edb971c731dad1ce322c6e6 + content/110: 652b35852355ef0a9e0d7b634639cfc9 + content/111: 7afd8cd395c8e63bb1ede3538307de54 + content/112: 3304a33dfb626c6e2267c062e8956a9d + content/113: eea7828d6d712dc31d150bd438284b8a + content/114: 72a2b6306511832781715e503f0442d8 + content/115: fe19a895e0b360386bfefc269ca596a5 + content/116: d1bab8ec5a51a9da5464eb47e2a16b50 + content/117: f4b91b5931dff5faaa26581272e51b61 + content/118: 8f2d6066da0f1958aa55c6191f0a5be1 + content/119: 2a1c4e0626d1a10a59ae80490435f1c6 + content/120: a74834b7a623c3f5cc323d3ceeb5415f + content/121: f9da331cf341b7abe9fa4f1f021bb2ce + content/122: 006b642e4072cd86730b41503906c267 + content/123: 4570f2c71f19c1a89aa15c62abea2a6b + content/124: bbb4874da742521d5e07d05e17056a3a + content/125: 35f33ebf126b4a967bccf057d990d8ea + content/126: 519f8d2ed7a62f11b58f924d05a1bdf4 + content/127: 711f65ba5fbbc9204591770be00c0b76 + content/128: d1bab8ec5a51a9da5464eb47e2a16b50 + content/129: 9a2604ebbc848ffc92920e7ca9a1f5d5 + content/130: 2d9792d07b8887ecb00b4bddaa77760d + content/131: 67c60dcbdcb96ec99abda80aed195a39 + content/132: cd7923b20a896061bd8b437607a456ab + content/133: 6497acadfafd123e6501104bc339cb0b + content/134: 8d345f55098ed7fe8a79bfcd52780f56 + content/135: 7f2808ae7cc39c74fa1ea2e023e16db8 + content/136: 88f2cd0696cc8d78dc4b04549b26c13b + content/137: d1bab8ec5a51a9da5464eb47e2a16b50 + content/138: 4760068730805bd746ad2b7abae14be7 + content/139: 363a11a70ad2991f43e5c645343d24b1 + content/140: 76193afa096b6017eb981461fbd0af36 + content/141: 0e297ada3c58c15adbac6ede74fec86b + content/142: 08c8a11473671bde84d82b265f8f70cc + content/143: d1bab8ec5a51a9da5464eb47e2a16b50 + content/144: ac1580a83d54361553916f1518ca3eff + content/145: a10c4dc3ab88bfa976836d5a2fd21168 + content/146: e7ac414081f94d0ea1f36ef434392bb2 + content/147: 5235c1c6fe2a3956c0b55c2d1827fb98 + content/148: 074894d66efb4d36737a0735278e41cb + content/149: e5aa4e76b5d89aa3c2cda5255443eccd + content/150: b41c367dfb1527280df6c09bd32e626c + content/151: a5b2b0cf64941e8e962724a5728a5071 + content/152: 08c8a11473671bde84d82b265f8f70cc + content/153: d1bab8ec5a51a9da5464eb47e2a16b50 + content/154: da658275cc81a20f9cf7e4c66c7af1e3 + content/155: d87f098de2239cceabdb02513ec754c0 + content/156: 642e60a6fc14e6cca105684b0bc778fa + content/157: 41775a7801766af4164c8d93674e6cb2 + content/158: 3afc03a5ab1dc9db2bfa092b0ac4826a + content/159: 18ddfcaf2be4a6f1d9819407dad9ce7c + content/160: 0d9a26fefe257a86593e24043e803357 + content/161: 7ec562abd07f7db290d6f2accea4cd2d + content/162: ee8b87f59db1c578b95ad0198df084b7 + content/163: 4603578d6b314b662f45564a34ca430d + content/164: cf4c97eb254d0bd6ea6633344621c2c2 + content/165: 7b4640989fab002039936156f857eb21 + content/166: 65ca9f08745b47b4cce8ea8247d043bf + content/167: 162b4180611ff0a53b782e4dc8109293 + content/168: 6b367a189eb53cb198e3666023def89c + content/169: dbb2125cefcf618849600c1eccae8a64 + content/170: 04eedda0da3767b06e6017c559e05414 + content/171: 7b909e3f9bcefa3b6fa603301dd8f898 + content/172: 905105177a561dc57b6e7d138d5de93d + content/173: 64eac7b6860c90aeb6467d5ea873d4ef + content/174: 8ff8367c3246103b3e3e02499e34ae0b + content/175: 44678bda9166f746da1d61b694ced482 + content/176: aaa4a0a394c487d60d82c6d77c0fcfef + content/177: ecd571818ddf3d31b08b80a25958a662 + content/178: 7dcdf2fbf3fce3f94987046506e12a9b 27578f1315b6f1b7418d5e0d6042722e: meta/title: 8c555594662512e95f28e20d3880f186 content/0: 9218a2e190598690d0fc5c27c30f01bb @@ -2479,16 +2490,16 @@ checksums: content/76: 33b9b1e9744318597da4b925b0995be2 content/77: 6afe3b62e6d53c3dcd07149abcab4c05 content/78: b6363faee219321c16d41a9c3f8d3bdd - content/79: 08410ce9f0ec358b3c7230a56bc66399 + content/79: 3c5b351d25fb0639559eacdad545a0ed content/80: b8b23ab79a7eb32c6f8d5f49f43c51f6 content/81: be358297e2bbb9ab4689d11d072611d1 - content/82: 09fea7c0d742a0eefa77e982e848de6c + content/82: 414b9bf7d35039c6a17f4fb03d6b7431 content/83: 7d098f0349c782f389431377ee512e92 content/84: 22b39537f6a104803389469d211154e4 content/85: d9ec74ab28b264d76f797fdae7c8f3d3 content/86: f29d6bfd74ba3fee0b90180f620b4f47 content/87: 2a59466500b62e57481fe27692a3ed0f - content/88: cbbb123fc3a12bf2ab72dc1bbe373a6e + content/88: 94965695a02aea6c753448c21fd66b18 content/89: 7873aa7487bc3e8a4826d65c1760a4a0 content/90: 98182d9aabe14d5bad43a5ee76a75eab content/91: 67bfa8ae3e22d9a949f08c79a40b8df5 @@ -2500,11 +2511,11 @@ checksums: content/97: dae96b41f0c029b464f02ac65d3c5796 content/98: 41c2bb95317d7c0421817a2b1a68cc09 content/99: 4c95f9fa55f698f220577380dff95011 - content/100: 6695bd47a05f9963134d8a71abb3d298 + content/100: e674c5e6ecaf4dae9fc93e328b8a57c4 content/101: 100e12673551d4ceb5b906b1b9c65059 content/102: ce253674cd7c49320203cda2bdd3685b content/103: 94d4346a735149c2a83f6d2a21b8ab4c - content/104: 3ee4b16b8204ef3b5b7c0322ff636fab + content/104: 869fd72c8911057ee0696f068fa22e35 content/105: 450265802cb0ba5b435b74b9cac1bf23 content/106: b735ede8764e4b2dfb25967e33ab5143 content/107: 0f881e586a03c4b916456c73fad48358 @@ -2834,10 +2845,20 @@ checksums: content/30: dbbf313837f13ddfa4a8843d71cb9cc4 content/31: cf10560ae6defb8ee5da344fc6509f6e content/32: c5dc6e5de6e45b17ee1f5eb567a18e2f - content/33: aa47ff01b631252f024eaaae0c773e42 - content/34: 1266d1c7582bb617cdef56857be34f30 - content/35: c2cef2688104adaf6641092f43d4969a - content/36: 089fc64b4589b2eaa371de7e04c4aed9 + content/33: 332dab0588fb35dabb64b674ba6120eb + content/34: 714b3f99b0a8686bbb3434deb1f682b3 + content/35: ba18ac99184b17d7e49bd1abdc814437 + content/36: bed2b629274d55c38bd637e6a28dbc4a + content/37: 71487ae6f6fb1034d1787456de442e6d + content/38: 137d9874cf5ec8d09bd447f224cc7a7c + content/39: 6b5b4c3b2f98b8fc7dd908fef2605ce8 + content/40: 3af6812662546ce647a55939241fd88e + content/41: 6a4d7f0ccb8c28303251d1ef7b3dcca7 + content/42: 5dce779f77cc2b0abf12802a833df499 + content/43: aa47ff01b631252f024eaaae0c773e42 + content/44: 1266d1c7582bb617cdef56857be34f30 + content/45: c2cef2688104adaf6641092f43d4969a + content/46: 089fc64b4589b2eaa371de7e04c4aed9 722959335ba76c9d0097860e2ad5a952: meta/title: 9842d3af9cf52b7f5ab4a6ed4f2b23d2 content/0: 112d20eb578be8c0f59a13c819bf7716 @@ -4068,11 +4089,13 @@ checksums: content/3: 78cfe3bc9c911dd9aa75f053f768707d content/4: d5c510cc37588bf8f3d9a91543544721 content/5: a09e8940e139c0b84886fa7f16f3e690 - content/6: 33f032ae58bee4c0e244491b110a22fe - content/7: ef92830705e75d566cb1c6bbc18a2c82 - content/8: 8f06e4f0147241cadfbae88fb2fc2057 - content/9: c2d4cc3ecf06ac3c07f57c83095e461b - content/10: 3d8114d48bbc82967b2e7c881f571dc0 + content/6: 4ec178f03b8b1dd035d0a2941d01b967 + content/7: c8a934e0c369887defde32b93786799b + content/8: 36205863ef80144682e36623ba455c7c + content/9: 1423b72abb907e40921f8f4ec40a22c2 + content/10: 8f06e4f0147241cadfbae88fb2fc2057 + content/11: c2d4cc3ecf06ac3c07f57c83095e461b + content/12: 3d8114d48bbc82967b2e7c881f571dc0 c1571f6a328a5083bc542ae1ffc98fac: meta/title: 41fc753f4232b5628873660d94faba90 meta/description: b108bba63132a8a2ddbff6b5264ef993 @@ -4081,30 +4104,99 @@ checksums: content/2: 3c7457d4671bdca75eb8847e77b3d09a content/3: b3c762557a1a308f3531ef1f19701807 content/4: bf29da79344f37eeadd4c176aa19b8ff - content/5: ae52879ebefa5664a6b7bf8ce5dd57ab - content/6: ce487c9bc7a730e7d9da4a87b8eaa0a6 - content/7: e73f4b831f5b77c71d7d86c83abcbf11 - content/8: 07e064793f3e0bbcb02c4dc6083b6daa - content/9: a702b191c3f94458bee880d33853e0cb - content/10: c497057cbb9dd53599071f8550f327cd - content/11: cc6e48f85d5c6bfc05f846341f2d5cc9 - content/12: 8a80a6a97da9bf375fac565f1caabb49 - content/13: 098cc8e062187eb877fe5e172a4aa467 - content/14: e452a7cb33d7cf2f7cf1804703edaa20 - content/15: 466cfd61b1d0fcd8fc93d867dfd0f3e3 - content/16: 377572316021236994f444e88949ef34 - content/17: 54852933b2cbe3deb3b1c3059dba6a15 - content/18: 9e66b045763abe053a3ba8d2c23e9aa1 - content/19: d34f0950591e3beb085e99db64d07d2f - content/20: 8677ef07618f7289b04fef3cce8bf745 - content/21: c0e6d2790e369569e7f272a5ec9ae21a - content/22: 93643a0d9d9745f131e4eabf7ead2018 - content/23: 89c7da6d2e8fbc25e303a7381e147237 - content/24: a8ec63597dc3a3564bc5f0c3a6e5f42c - content/25: 379618989b6cd427b319cfdab523297d - content/26: bc4c2e699a7514771276e90e9aee53ba - content/27: 38e14193b679ef774c3db93d399e700e - content/28: ce110ab5da3ff96f8cbf96ce3376fc51 - content/29: 83f9b3ab46b0501c8eb3989bec3f4f1b - content/30: e00be80effb71b0acb014f9aa53dfbe1 - content/31: 847a381137856ded9faa5994fbc489fb + content/5: d9ee91aa417a55e8cb1e0c5f4e4ca83b + content/6: b747c4e9aff28c3efba1c8888ba9b9f9 + content/7: d16a981c85afb9da140d46d4b8d51e06 + content/8: ff071011d7ed2f6c9b98e1bb18c0edf5 + content/9: e73f4b831f5b77c71d7d86c83abcbf11 + content/10: 07e064793f3e0bbcb02c4dc6083b6daa + content/11: a702b191c3f94458bee880d33853e0cb + content/12: c497057cbb9dd53599071f8550f327cd + content/13: cc6e48f85d5c6bfc05f846341f2d5cc9 + content/14: 8a80a6a97da9bf375fac565f1caabb49 + content/15: 098cc8e062187eb877fe5e172a4aa467 + content/16: e452a7cb33d7cf2f7cf1804703edaa20 + content/17: 466cfd61b1d0fcd8fc93d867dfd0f3e3 + content/18: 377572316021236994f444e88949ef34 + content/19: 54852933b2cbe3deb3b1c3059dba6a15 + content/20: 9e66b045763abe053a3ba8d2c23e9aa1 + content/21: d34f0950591e3beb085e99db64d07d2f + content/22: 8677ef07618f7289b04fef3cce8bf745 + content/23: c0e6d2790e369569e7f272a5ec9ae21a + content/24: 93643a0d9d9745f131e4eabf7ead2018 + content/25: 89c7da6d2e8fbc25e303a7381e147237 + content/26: a8ec63597dc3a3564bc5f0c3a6e5f42c + content/27: 379618989b6cd427b319cfdab523297d + content/28: bc4c2e699a7514771276e90e9aee53ba + content/29: 38e14193b679ef774c3db93d399e700e + content/30: ce110ab5da3ff96f8cbf96ce3376fc51 + content/31: 83f9b3ab46b0501c8eb3989bec3f4f1b + content/32: 8eafc1489817e2b31bb2dde5cf45bb17 + content/33: f7c188211a6c76460e159b65a8dae43f + content/34: 8a64c1f76a0bb16a40ba0eeaf6141dd1 + content/35: fb03882a39682b35fd8ef5574a110020 + content/36: cb234805a1738585c4725c6519b212bc + content/37: 3dee2b82795a6dab076cbcdc59a03965 + content/38: 950899e381ce7b7c73e98ad5b15562a0 + content/39: c8b1f8cd971687fc5d2b78c28c2b4050 + content/40: c8a934e0c369887defde32b93786799b + content/41: dc440445fa0173b8d47905205307b3a1 + content/42: 42cef4d960a45562b89682cc0a563fe5 + content/43: 0bbfb30bad650027ae86bb1a0baea081 + content/44: e00be80effb71b0acb014f9aa53dfbe1 + content/45: 847a381137856ded9faa5994fbc489fb + b214e6d00a19c26edb95e44446a6d760: + meta/title: 722934d11bc41f6e50b1cfc3dbadaf26 + content/0: 50d5c77e01abfc35c519f78cba84a473 + content/1: 5c9d3b7c555e2b6a1532d3112f841a70 + content/2: 23bd248a9a74fae4f7db5fde8d008138 + content/3: 5e26527ccf8fddebe14c951e6c950b48 + content/4: 49d51591195c906d11276a2dee57c0bb + content/5: 0461f100a5cf6ed6eb53cf836ef45c10 + content/6: dad5954a5a455e1c426441e4794b2a7c + content/7: a4efab9ed1bb9285bef34a82ba70c866 + content/8: c797150e0147747bbdacebac8a1421b7 + content/9: 770dc0be25d7b2c38351e32d9fa90e49 + content/10: 9ec734827a42d127af99e05d69fdf911 + content/11: 433e69f3cf2ae10821d1acf22a18a291 + content/12: be3b8ea55f32f09643422b15d37e3929 + content/13: ff1349545973b7600743bb8b95f90bb2 + content/14: 6bb355d4a953adbb0b5fe6501cd222f4 + content/15: ec3d41b4a649cfe33292f8be6c6c678c + content/16: 1f882cdaba7a9b78b05d26836e2411a5 + content/17: eacb0ee18275bf6801de5d2eef84e493 + content/18: 503ec68e64c9cbe4c283192659b5dbd2 + content/19: c09c061bd9bb350f345269de8532ac82 + content/20: c128c130dd3d3fd4148323cfcb675db2 + content/21: 83f4c595ce175cd6a414b46a88dfff57 + content/22: a746c949b86da5eca4fe9e1624b07836 + content/23: 842bd4cf67c9fdd48034d4b31d1a12db + content/24: 317d19b9c55fadf8fcd6b26e154f72e1 + content/25: 48af41b1da94b60b33f3402dd326f48b + content/26: d84ad590287648a6e6f08587fe6bf817 + content/27: 04e0d6242314dacfb8d8dd16505b2535 + content/28: b2f0eb9ec1d5c9cef46fa02b903a87e5 + content/29: 0441638444240cd20a6c69ea1d3afbb1 + content/30: 7384c7eedaf6fe9b7aa7d02f6e79bb5d + content/31: 69e9bbeac40eb0c9937f38647b06ba71 + content/32: 52afa38aae8cccc986d915c4ee894e89 + content/33: 29a51975b097968639b1b84009a809c0 + content/34: 987932038f4e9442bd89f0f8ed3c5319 + content/35: a351326511e997c1aa0f829733c4d8fa + content/36: f902bd33c2aa0d9eed80eb468255f0f3 + content/37: 320da12b94e7bb3d7b7524c15df7e035 + content/38: d4821d23bf0d88529a88aa7abe5330dc + content/39: 7a7902c8f8e0270e7949f37c5264f421 + content/40: 9c2f91f89a914bf4661512275e461104 + content/41: f76d8d662ed441da8d48254a63bb92a5 + content/42: f00ccf08ff9825a6dbed544caeb7e6ab + content/43: 3ab5d61f54f98ba50e611a48a2dc21bd + content/44: 0dc53c5490ace62a16ded85d264994de + content/45: 56570d30087803e02088eae20aecc762 + content/46: d99180a353e9102f7a3d0e366f140a28 + content/47: cb131821d20155010e12961c3aac309b + content/48: ec19338b3159fc866ee6cff196c54314 + content/49: b09931503d0e18462364b8e8d8c50e4b + content/50: b2a4a0c279f47d58a2456f25a1e1c6f9 + content/51: dd2fe5f38e6fadab2b5353cc6e8da57e + content/52: 604fec9d146658f2582bb53523378ac3