Aller au contenu principal
DocumentCréer un flux de travailVariables et expressions

Variables et expressions

Paramètres au niveau du workflow, sortie des étapes en amont, routage du classificateur, références d'informations d'identification - flux de données entre les étapes.

Toutes les valeurs dynamiques dans Braidrun utilisent des « références variables ». La syntaxe n’a qu’une seule forme : les doubles accolades.

yaml
{{var:name}}                     # workflow 级变量
{{steps.fetch.data.user.name}}   # 上游步骤的 JSON 输出
{{classifier.category}}          # 分类器路由结果
{{credentials.openai_api_key}}   # 凭据库里的密钥

Quatre sources de variables

1. var: — Paramètres de flux de travail

La section variables/paramètres en haut du workflow, ou l'entrée du préréglage planning/webhook.

yaml
variables:
  target_date:
    type: string
    default: "yesterday"
  top_n:
    type: number
    default: 10

steps:
  - id: fetch
    type: code
    code: |
      return { date: "{{var:target_date}}", top: {{var:top_n}} };

2. steps.id.* — Sortie de l'étape en amont

Il y a une sortie structurée après l’exécution de chaque étape. Les sous-champs les plus couramment utilisés :

  • steps.id.output — Texte brut ou valeur de retour brute.
  • steps.id.data — JSON structuré après extraction.
  • steps.id.artifacts[0].url — Lien vers la fiche produit.
  • steps.id.tokens / cost / duration_ms — Statistiques d'exécution.
yaml
steps:
  - id: fetch
    type: code
    extract:
      articles: $.items
      total: $.meta.total

  - id: summarize
    type: single
    agent: writer
    task: |
      我有 {{steps.fetch.data.total}} 条新闻,这是第一条:
      {{steps.fetch.data.articles[0].title}}

3. classifier.* — Résultats de routage du classificateur

Le résultat de l'étape de classificateur précédente est utilisé comme référence de premier niveau pour la condition/le branchement.

yaml
steps:
  - id: triage
    type: classifier
    agent: planner
    task: "{{var:user_message}}"
    categories: [billing, technical, other]

  - id: respond
    type: single
    condition: "{{classifier.category}} == 'billing'"
    agent: writer
    task: "客户关于账单的问题是:{{var:user_message}}"

Équivalent à steps.<classifier_step_id>.category - juste plus court et plus sémantique.

4. credentials.* — Référence des informations d'identification

Lien de résolution : Espace de noms utilisateur → Espace de noms d’équipe → Espace de noms système ; voir les détails Identifiants.

Expression jsonpath

La syntaxe de chemin simple peut être écrite entre accolades - fondamentalement compatible avec un sous-ensemble de JSONPath :

  • {{steps.fetch.data.articles[0].title}} — indice de tableau
  • {{steps.fetch.data.articles[*].title}} — Tous les éléments du tableau (tableau de retour)
  • {{steps.fetch.data.articles[?(@.score>5)]}} — Filtrage conditionnel
  • {{steps.fetch.data | length}} — filter:length / upper / lower / default / trim

Extraire : structurer la sortie de l'étape

Les données renvoyées par LLM ou le code doivent souvent « sélectionner quelques champs » pour une utilisation en aval. Utiliser l'extrait :

yaml
- id: fetch_user
  type: code
  code: |
    const res = await fetch('https://api.example.com/me');
    return await res.json();
  extract:
    name: $.profile.fullName
    company: $.profile.org.name
    is_admin: $.permissions[?(@=='admin')] | length > 0

Après cela, steps.fetch_user.data.name / .company sera disponible directement.

Condition : exécution conditionnelle

Toute étape peut avoir une condition - lorsque l'expression est fausse, cette étape est ignorée (l'état d'exécution est marqué SKIPPED).

yaml
- id: summarize
  type: single
  agent: writer
  condition: "{{classifier.category}} == 'ai' && length({{steps.fetch.data.articles}}) > 0"
  task: "..."

Opérateurs pris en charge :

  • Comparez :== != < > <= >=
  • Logique :&& || !
  • Chaîne :contains(x, y) startsWith(x, y) endsWith(x, y) matches(x, /re/)
  • Tableau :length(x) any(list, cond) all(list, cond)
  • Jugement court :isEmpty(x) isNotEmpty(x)
condition ignorée ou échouée

SKIPPED est "normal et ne fonctionne pas" et peut être utilisé en aval. {{steps.x.status}} == 'SKIPPED' détection. FAILED est une erreur d'exécution et sera transmise à exécuté.status. Ne mélangez pas les deux.

Réessayer : stratégie de nouvelle tentative

yaml
- id: fetch
  type: code
  code: "..."
  retry:
    max_attempts: 3
    backoff: exponential     # fixed | linear | exponential
    initial_delay_ms: 1000
    max_delay_ms: 30000
    retry_on: [network, rate_limit, http_5xx]

Réessayez uniquement en cas d'erreurs transitoires (réseau/limite de vitesse/5xx). Les exceptions métier (échec de condition, rejet LLM) ne seront pas retentées.

Agrégat : fusionner plusieurs entrées

Utilisez l'agrégat lorsqu'une étape collecte des données à partir de plusieurs sources en amont. Par exemple, résumez les commentaires après group_chat :

yaml
- id: combine
  type: code
  aggregate:
    comments: concat_lines({{steps.group_chat_1.messages}})
    total_tokens: sum({{steps.*.tokens}})
  code: "return { comments, total_tokens };"

Fonctions d'agrégation disponibles : concat/concat_lines/json_array/join(sep)/first/last/max/min/avg.

Mappage de noms DTO

Utilisez Snake_case (group_chat, agent_based) pour YAML et camelCase (groupChat, agentBased) pour JSON API/DTO. La plateforme convertit automatiquement dans les deux sens, vous n'avez pas à vous inquiéter.

Pièges courants

  • Référence à une étape qui n'a pas été exécutée — Si la condition ignore l'étape en amont, les références en aval à celle-ci deviendront nulles/non définies. Utiliser | default(...) pour le savoir.
  • Les grands champs sont directement connectés aux tâchestask: "{{steps.x.output}}" Si la sortie en amont est de 100 Ko, LLM éclatera le jeton. Extrayez et compressez d’abord avant de transmettre.
  • YAML guillemets à l'intérieur — Les expressions contenant des deux-points ou des caractères spéciaux doivent être placées entre guillemets : condition: "{{x}} == 1"