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.
{{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.
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.
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.
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 :
- 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 > 0Aprè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).
- 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)
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
- 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 :
- 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âches —
task: "{{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"