flow問い合わせ v1examples/inquiry/temporal/inquiry.ja.flow · dandori doc
お客さまの問い合わせの種類を Jev が選び、その確信度も返す。エージェントは問い合わせを読んで注文番号と要点を取り出し、種類も読む。Jev が種類に十分な確信を持てないときは、エージェントが読んだ種類を使う。受け持つ窓口と最初の返事までの時間は規則が決め、返事の下書きは別のエージェントが書き、窓口のシステムに起票する。選ぶことは Jev が、読むことと書くことはエージェント(読むのは会社が自分で動かしているモデル、書くのは Claude)が、決めることは規則が受け持つ。Temporal 向けの版:Jev とエージェントは生成したアクティビティで、Jev は TypeSafe の API キー(TYPESAFE_API_KEY)で呼び、読み取りは Open Responses を話す会社の Ollama に(`url`)、下書きはワーカーが持つ鍵で Claude に送る。規則はワークフローと同じワーカーでローカルアクティビティとして動き、その結果はマーカーとして履歴に残る。起票は自分で書くアクティビティ
flow| 行 | 呼び出し | 呼ぶもの | リトライ | タイムアウト | 失敗したとき |
|---|---|---|---|---|---|
| 62 | 読み = 読み取る(…) | agent · gpt-oss:20b · http://ollama.internal:11434/v1 | 10 秒おきに 2 回(failure・timeout) | 1 分 | timeout・failure → 63 行目 |
| 64 | 手作業 = 起票する(…) | 自分で書くタスク・key | 5 秒おきに 2 回(failure・timeout) | — | timeout・failure → ワークフローが失敗する |
| 67 | 種類 = 種類を選ぶ(…) | jev · jev-1.13.0 · confidence 0.8 else 迷い | 1 秒おきに 2 回(failure・timeout) | 10 秒 | 迷い・timeout・failure → 68 行目 |
| 69 | 判定 = 振り分け(…) | 規則 問い合わせの振り分け.rule(Temporal ではローカルアクティビティ) | 1 秒後と 2 秒後の 2 回(failure) | — | timeout・failure → ワークフローが失敗する |
| 74 | 下書き = 下書きする(…) | agent claude · claude-sonnet-5 | — | 1 分 | timeout・failure → 75 行目 |
| 76 | 票 = 起票する(…) | 自分で書くタスク・key | 5 秒おきに 2 回(failure・timeout) | — | timeout・failure → ワークフローが失敗する |
| 行 | 終わり方 |
|---|---|
| 65 | succeed チケットID = 手作業.チケットID, 窓口 = 総合 |
| 77 | succeed チケットID = 票.チケットID, 窓口 = 判定.窓口 |
ステップを選ぶと、そこについて検査で分かったことが出ます。左のシナリオを選ぶと、その実行が通るところが光ります。ステップの横の数は、その実行が通った回数です。
問い合わせ v1お客さまの問い合わせの種類を Jev が選び、その確信度も返す。エージェントは問い合わせを読んで注文番号と要点を取り出し、種類も読む。Jev が種類に十分な確信を持てないときは、エージェントが読んだ種類を使う。受け持つ窓口と最初の返事までの時間は規則が決め、返事の下書きは別のエージェントが書き、窓口のシステムに起票する。選ぶことは Jev が、読むことと書くことはエージェント(読むのは会社が自分で動かしているモデル、書くのは Claude)が、決めることは規則が受け持つ。Temporal 向けの版:Jev とエージェントは生成したアクティビティで、Jev は TypeSafe の API キー(TYPESAFE_API_KEY)で呼び、読み取りは Open Responses を話す会社の Ollama に(`url`)、下書きはワーカーが持つ鍵で Claude に送る。規則はワークフローと同じワーカーでローカルアクティビティとして動き、その結果はマーカーとして履歴に残る。起票は自分で書くアクティビティ
問い合わせ: 問い合わせチケットID: string・窓口: 振り分け.窓口examples/inquiry/temporal/inquiry.ja.flow読み = 読み取る(…) 62 行目62 let 読み = 読み取る(本文: 問い合わせ.本文) 63 on failure =>
agent · gpt-oss:20b · http://ollama.internal:11434/v1timeout・failure → 63 行目39 # 会社が自分で動かしている Ollama のモデルが、Open Responses を通して本文を読む。読み取りの 40 # Schema が、答えを規則の種類のどれかに縛る。 41 task 読み取る(本文: string) -> 読み取り 42 agent "お客さまからの問い合わせの本文を読み、種類を一つ選び、注文番号が書かれていれば取り出し、要点を一文にまとめてください。注文番号が書かれていなければ null にします。" 43 model "gpt-oss:20b" 44 effort low 45 url "http://ollama.internal:11434/v1" 46 plaintext "モデルのサーバーにはクラスターのネットワークの中だけで届き、そこはサービスメッシュが暗号化する" 47 timeout 60 seconds 48 retry 2 times every 10 seconds
手作業 = 起票する(…) 64 行目 64 let 手作業 = 起票する(問い合わせID: 問い合わせ.id, 窓口: 総合, 期限: 24, 件名: "読み取れなかった問い合わせ", 本文: 問い合わせ.本文, 下書き: none)
keytimeout・failure → ワークフローが失敗する56 # 起票は、窓口のシステムのクライアントライブラリを使って、自分で書くコードで行う。 57 task 起票する(問い合わせID: string, 窓口: 振り分け.窓口, 期限: duration[h], 件名: string, 本文: string, 下書き: string?) -> 起票 58 key 59 retry 2 times every 5 seconds
succeed チケットID = 手作業.チケットID, 窓口 = 総合 65 行目 65 succeed チケットID = 手作業.チケットID, 窓口 = 総合
種類 = 種類を選ぶ(…) 67 行目67 let 種類 = 種類を選ぶ(本文: 問い合わせ.本文) 68 on 迷い, failure => let 種類 = 読み.種類
jev · jev-1.13.0 · confidence 0.8 else 迷い迷い・timeout・failure → 68 行目27 # Jev は規則の種類のどれかを、それぞれの意味を見て選び、その確信度も返す。 28 task 種類を選ぶ(本文: string) -> 振り分け.種類 29 jev "この問い合わせの種類はどれか" 30 返品 "商品を返したい、交換したい" 31 配送 "荷物が遅れている、届かない、壊れていた、どこにあるか知りたい" 32 請求 "請求、支払い、返金のこと" 33 その他 "上のどれでもない" 34 model "jev-1.13.0" 35 confidence 0.8 else 迷い 36 timeout 10 seconds 37 retry 2 times every 1 second
let 種類 = 読み.種類 68 行目 68 on 迷い, failure => let 種類 = 読み.種類
判定 = 振り分け(…) 69 行目 69 let 判定 = 振り分け(種類: 種類, 会員: 問い合わせ.会員)
問い合わせの振り分け.rule(Temporal ではローカルアクティビティ)timeout・failure → ワークフローが失敗する4 use rule 振り分け from "../rules/問い合わせの振り分け.rule" 5 local
let 件名 = "{種類}の問い合わせ" 70 行目 70 let 件名 = "{種類}の問い合わせ"
match 読み.注文ID 71 行目71 match 読み.注文ID 72 some 注文ID => let 件名 = "{種類}の問い合わせ(注文 {注文ID})" 73 none => pass
let 件名 = "{種類}の問い合わせ(注文 {注文ID})" 72 行目 72 some 注文ID => let 件名 = "{種類}の問い合わせ(注文 {注文ID})"
下書き = 下書きする(…) 74 行目74 let 下書き = 下書きする(種類: 種類, 要点: 読み.要点, 注文ID: 読み.注文ID, 期限: 判定.期限) 75 on failure => let 下書き: string? = none
agent claude · claude-sonnet-5timeout・failure → 75 行目50 task 下書きする(種類: 振り分け.種類, 要点: string, 注文ID: string?, 期限: duration[h]) -> string 51 agent claude "問い合わせへの最初の返事を、丁寧な日本語で三文以内に下書きしてください。`期限` は返事をするまでの時間の数です。約束できないことは書きません。" 52 model "claude-sonnet-5" 53 effort medium 54 timeout 60 seconds
let 下書き = none 75 行目 75 on failure => let 下書き: string? = none
票 = 起票する(…) 76 行目 76 let 票 = 起票する(問い合わせID: 問い合わせ.id, 窓口: 判定.窓口, 期限: 判定.期限, 件名: 件名, 本文: 問い合わせ.本文, 下書き: 下書き)
keytimeout・failure → ワークフローが失敗する56 # 起票は、窓口のシステムのクライアントライブラリを使って、自分で書くコードで行う。 57 task 起票する(問い合わせID: string, 窓口: 振り分け.窓口, 期限: duration[h], 件名: string, 本文: string, 下書き: string?) -> 起票 58 key 59 retry 2 times every 5 seconds
succeed チケットID = 票.チケットID, 窓口 = 判定.窓口 77 行目 77 succeed チケットID = 票.チケットID, 窓口 = 判定.窓口
終わり(成功)flow が最後まで走り、ワークフローは成功します。
読み = 読み取る(…) ok種類 = 種類を選ぶ(…) ok判定 = 振り分け(…) oklet 件名 = "{種類}の問い合わせ"match 読み.注文ID → none下書き = 下書きする(…) ok票 = 起票する(…) oksucceed チケットID = 票.チケットID, 窓口 = 判定.窓口読み = 読み取る(…) failure failure failure → on failure手作業 = 起票する(…) oksucceed チケットID = 手作業.チケットID, 窓口 = 総合読み = 読み取る(…) failure failure failure → on failure手作業 = 起票する(…) failure failure failure → ここでは処理しない読み = 読み取る(…) failure ok種類 = 種類を選ぶ(…) ok → on 迷い, failurelet 種類 = 読み.種類判定 = 振り分け(…) failure failure failure → ここでは処理しない読み = 読み取る(…) ok読み = 読み取る(…) ok種類 = 種類を選ぶ(…) ok → on 迷い, failurelet 種類 = 読み.種類判定 = 振り分け(…) ok読み = 読み取る(…) ok種類 = 種類を選ぶ(…) failure ok判定 = 振り分け(…) ok読み = 読み取る(…) ok種類 = 種類を選ぶ(…) ok読み = 読み取る(…) ok種類 = 種類を選ぶ(…) ok判定 = 振り分け(…) oklet 件名 = "{種類}の問い合わせ"match 読み.注文ID → some 注文IDlet 件名 = "{種類}の問い合わせ(注文 {注文ID})"下書き = 下書きする(…) failure → on failurelet 下書き = none票 = 起票する(…) failure failure failure → ここでは処理しない読み = 読み取る(…) ok種類 = 種類を選ぶ(…) ok判定 = 振り分け(…) oklet 件名 = "{種類}の問い合わせ"match 読み.注文ID → none下書き = 下書きする(…) failure → on failurelet 下書き = none票 = 起票する(…) failure oksucceed チケットID = 票.チケットID, 窓口 = 判定.窓口読み = 読み取る(…) ok種類 = 種類を選ぶ(…) ok判定 = 振り分け(…) oklet 件名 = "{種類}の問い合わせ"match 読み.注文ID → none下書き = 下書きする(…) ok読み = 読み取る(…) ok種類 = 種類を選ぶ(…) ok判定 = 振り分け(…) oklet 件名 = "{種類}の問い合わせ"match 読み.注文ID → none下書き = 下書きする(…) ok票 = 起票する(…) ok読み = 読み取る(…) failure failure failure → on failure手作業 = 起票する(…) failure oksucceed チケットID = 手作業.チケットID, 窓口 = 総合読み = 読み取る(…) failure failure failure → on failure手作業 = 起票する(…) ok