goalflow について
goalflowは、LangGraphアプリを開発するチーム向けのスキルです。DifyフローのPythonコード化、エージェントループや配信層の設計、公開前のセキュリティ確認を扱います。
主な機能
- 01Dify DSLをLangGraphのPythonに変換
- 02ワークフローグラフと分岐の構築
- 03agent_kitによるエージェントループ
- 04ストリーミングとHITLの設定
- 05公開前のセキュリティ監査
活用シーン
- 01Difyフローを管理可能なコードへ移行
- 02ノード、分岐、ループの設計
- 03エージェントにツールとミドルウェアを追加
- 04公開前に認証情報と設定を確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ akillness/ jeo-skills --skill goalflowインストール後、Claude Code で/goalflowを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
SKILL.toonevals/evals.jsonreferences/serving-and-protocols.mdskills-engine.mddify-transpile.mdnodes-and-graph.mdagent-kit.mdsecurity-gate.mdscripts/check_goalflow_skill.pygoalflow.shpreflight_audit.py詳細
goalflow — グラフオーケストレーション型エージェントループ
goalflow は LangGraph 上で LLM アプリケーションを構築する 2 つの方法を提供し、両者を組み合わせることもできます。ビジュアルファースト(Dify で設計し、エクスポートした DSL を自分で管理する LangGraph の Python ファイルに変換する方法)と、コードファースト(同梱の agent_kit による ReAct/Deep エージェントループ)です。graph ノードに agent ループを組み込むことができ、エージェントはサブワークフローをツールとして呼び出せます。
このプロジェクトに関するほぼすべての回答に関わる重要な点が 2 つあります。
- 社内の本番システムから切り出されたものです。汎用化できるコア部分は実際に動作しますが、デフォルト設定には強い意見が反映されています(Qwen/DashScope、Alibaba OSS)。
- ドキュメントは冒頭で CAUTION を掲げています。実際に使える認証情報が git の履歴に残っています。これは公開する前に解決すべきブロッカーであり、単なる補足事項ではありません。
このスキルを使う場面
- Dify のランタイムを使い続けることなく、Dify フローをバージョン管理できる LangGraph コードに変換する
- ワークフローノード、エッジ、分岐ルーティング、反復/ループサブグラフを選択または作成する
agent_kitを使ってエージェントループを構築する — グラフビルダー、ミドルウェアチェーン、ハーネス/モデルルーター、実行可能なスキル- サービング層を接続する:データアダプター、SSE ストリーミング、HITL 割り込み、Redis/MySQL、ワークフロー登録
- LLM が照合してプロンプトに挿入する
SKILL.md機能を作成する - 公開または実環境にデプロイする前にリポジトリを監査する
このスキルを使わない場面
- LangGraph の一般的なグラフ/状態/チェックポインター API に関する質問 →
langgraph-fundamentals、langgraph-persistence - 一般的な LangChain チェーン、リトリーバー、RAG の設計 →
langchain-fundamentals、langchain-rag - このエンジンに紐づかない一般的な HITL パターン →
langgraph-human-in-the-loop agent_kitのラッパーを使わず、deepagentsを直接使用する場合 →deep-agents-core- goalflow のランタイムではなく、このリポジトリのエージェントカタログ向けにスキルを作成する場合 →
skill-standardization、write-a-skill - LLM トレース/評価プラットフォームの選定 →
langsmith、opik
手順
ステップ 1:最初に必要な情報を集める
モードを決めるのは、次の 4 つの情報です。
- 開始時の成果物 — Dify DSL のエクスポート、空のリポジトリ、既存の
BaseWorkflowサブクラス、または稼働中のデプロイ - 目標の形 — ワークフローグラフ、エージェントループ、またはループを組み込んだグラフノード
- クライアントプロトコル — Dify ネイティブ(デフォルト)、OpenAI 互換、またはカスタム
- 環境の実情 — Redis と MySQL は実際に利用可能かどうか。チェックポインターのバックエンドは MySQL であり、チェックポインターがあるからこそ停止/再開や HITL が機能します。
ステップ 2:モードを 1 つだけ選ぶ
| モード | 使用する場面 | 生成されるもの |
|---|---|---|
orient | goalflow が適切なツールか不明な場合 | 適合性の判定、または LangGraph を直接使うという率直な案内 |
transpile | Dify DSL のエクスポートがある場合 | 登録済みで実行可能な BaseWorkflow サブクラス |
build | グラフ自体を作成または修正する場合 | ノードの選択、エッジ/分岐ルーティング、エラー処理方針 |
agent | オープンエンドのツール使用ループが必要な場合 | ビルダー、ミドルウェア、ハーネスを備えた Agent/AgentBaseNode |
serve | ランタイムをクライアントに接続する場合 | アダプター、エンドポイント、ストリーミング、HITL、ストレージ、登録 |
harden | 公開またはデプロイの前 | 公開前ゲートで確認するブロッカーの一覧 |
ユーザーがどのモードを求めているかにかかわらず、公開または共有リモートにプッシュする前に harden を実行してください。
ステップ 3:環境を読み取り専用で確認する
bash .agent-skills/goalflow/scripts/goalflow.sh doctor
bash .agent-skills/goalflow/scripts/goalflow.sh doctor /path/to/goal-flow
doctor は Python のバージョン、コアパッケージ(langgraph、fastapi、redis、pymysql、sqlalchemy、langchain-openai)、goalflow と agent_kit をインポートできるかどうか、設定されている .env のキーを報告します — 名前のみで、値は決して表示しません。何もインストールせず、サーバーも起動しません。
ステップ 4:グラフを手書きする前にトランスパイルする
トランスフォーマーは 2 段階のパイプラインです。DSL を内部グラフモデルに解析し、次にダブルディスパッチビジターを使って Python を出力します。
python -m goalflow.tool.dify_transformer.wf_transformer_tool \
--dsl path/to/my_flow.yml \
--out my_flow_workflow.py \
--class MyFlowWorkflow
よくある間違いを防ぐために、次の 2 点を把握しておきましょう。
- 解析は読み取り専用です。ホストの移植性に関する書き換えはメモリ内のコピーに対して行われ、エクスポートファイルは変更されません。
- 置換テーブルは
DifyDslParser.DEFAULT_HOST_SUBSTITUTIONSです。これは元の作者が使用していた内部ホスト名を定義しています。独自のhost_substitutions=または無効化するための{}を渡してください。元の設定を引き継がないでください。
コードの生成は作業の半分にすぎません。生成されたクラスは登録するまで何もしません(ステップ 6)。詳細は references/dify-transpile.md を参照してください。
ステップ 5:実際の BaseNode の契約に沿ってノードを作成する
実装するメソッドは call(self, state) の 1 つだけです。戻り値の型によって、状態の更新とルーティングの両方が決まります。
| 戻り値 | 意味 |
|---|---|
dict | 状態にマージし、next_node_ids に進みます |
Command(update=, goto=) | 更新してジャンプします |
List[str] | 分岐ルーティング — 出力ハンドルを選択します |
Sequence[Send] | ファンアウトします。各 Send につき 1 つの並列分岐を実行します |
None | 更新なし |
__call__ ラッパーを使うと、計測、ログ記録、ファンインバリアを追加実装なしで利用できます。複数の pre_node_ids を持つノードは、トポロジカル深度に達するまで再キューイングされるため、すべての上流分岐が到着した後に 1 回だけ実行されます。これを独自に実装しないでください。
ノードカタログ、エラー戦略、反復回数やループ回数の上限については、 references/nodes-and-graph.md を参照してください。
ステップ 6:ワークフローを登録し、登録の実態を説明する
# src/goalflow/api/auth_validator.py
apikey_workflow_def_map = {
"2999a65aa67e37253623075d60796f9a": MyWorkflow, # md5(api_key)
}
これは、API キーの MD5 をキーとするコード内の静的なマップです。上流のドキュメントでは、現在の設計として説明されており、実際のデプロイに向けて最初に置き換えるべきものとされています。MD5 はシークレットのハッシュ化には適していません。ユーザーからワークフローの登録方法を尋ねられたら、質問に答えるとともに、この点も必ず伝えてください。本番環境での認証方法として提示しないでください。
ステップ 7:エージェントの処理には AgentBaseNode を優先する
AgentBaseNode は、ワークフローの BaseNode と agent_kit の Agent を多重継承します。これをサブクラス化し、output_schema、build_prompt、build_command を実装してください。これは DeepAgentBaseNode、CreateAgentBaseNode、StateGraphBaseNode に代わるものであり、従来の手動による AgentNode の ReAct ループより推奨される方法です。
ビルダーは自動的に選択されます。subagents がある場合は DeepGraphBuilder、ない場合は ReactGraphBuilder が使用されます。ミドルウェアはリストの順に実行されます。
フック、ミドルウェアカタログ、ハーネスとモデルルーターの契約については、references/agent-kit.md を参照してください。
ステップ 8:プロトコルの変更はアダプターレイヤーに限定する
エンジンはプロトコルに依存しないセマンティックイベントを出力し、それを最後に DataAdapter がシリアライズします。プロトコルを追加するには、generate()(ストリーミング)と execute()(ブロッキング)を実装します。エンジン、ノード、グラフには手を加える必要はありません。
内部形式がすでに Dify プロトコルそのものであるため、DifyDataAdapter は入力をそのまま渡します。OpenAIDataAdapter は /v1/chat/completions を処理します。
ストリーミングは分岐を認識します。選択されなかった if-else 分岐や分類器分岐のトークンは、クライアントに届く前に除外されます。詳細は
references/serving-and-protocols.md を参照してください。
ステップ 9:プッシュする前に公開前チェックを実行する
python3 .agent-skills/goalflow/scripts/preflight_audit.py /path/to/goal-flow
標準ライブラリのみを使用します。上流のチェックリストを決定論的に実行します。追跡対象の
.env*/キー/ログファイル、Git の履歴からまだ到達可能な .env* の blob、
ハードコードされた内部 IP とエンドポイント、.gitignore の網羅状況、LICENSE
の存在、認証情報付きのオープン CORS の組み合わせ、MD5 認証マップ、および
CodeNode の exec パスを確認します。```review で囲まれた JSON ブロックを 1 つ出力し、
ブロッカーがある場合は終了コード 1 で終了します。
ここで定めている、譲れないルールは次のとおりです。.env の追跡を解除しても、履歴から
削除されるわけではありません。すべての認証情報をローテーションし、git filter-repo
で履歴を消去してから、新しいリモートにプッシュしてください。すでに秘密情報を含む
リモートには、決してプッシュしないでください。
公開されている wanmol/goal-flow の履歴はすでに消去済みです(.env.example のみが
残っています)。そのため、通常はこのチェックを通過します。重要なのは、内部フォーク、
ミラー、消去前に作られたクローンです。元の認証情報はそこにまだ残っています。
チェックリストの全文はreferences/security-gate.mdを参照してください。
ステップ 10:インジェクションコストを考慮してランタイムスキルを作成する
goalflow には 2 つのスキルシステムがあります。メインプロジェクトのエンジン
(src/goalflow/skill/)は、LLM でクエリに対応する SKILL.md を照合します
(キーワードによる照合ではありません。デフォルトは qwen-turbo、しきい値は 0.3、
top_k は 1 です)。そして、Markdown の本文をそのままシステムプロンプトに注入します。
agent_kit のエンジンは、実行可能なスキル(LangChain ツールとしての module:func)と
ハイブリッドモードを追加します。
python3 .agent-skills/goalflow/scripts/check_goalflow_skill.py skills/weather_query
本文はそのまま注入されるため、本文の長さは、照合が行われるたびにプロンプトコストに
なります。チェッカーは、本文が大きすぎる場合や、照合エンジンが判断するには
description が曖昧すぎる場合に警告します。
references/skills-engine.mdでは、フロントマター、照合、 2 つのエンジンのどちらを選ぶかについて説明しています。
ベストプラクティス
- トランスパイルしたら、コードを自分で管理します。 目的は Dify のランタイムから 抜け出すことです。DSL を正本として、何度も変換し続けないでください。
- ホスト置換テーブルを置き換えます。 上流の作者の内部ホスト名を引き継ぐと、 URL が気付かないうちに書き換えられます。
- MD5 API キーマップを本番環境の認証として提示しないでください。 登録方法を 説明してから、デモ用の仕組みであることを明記してください。
CodeNodeの入力は信頼できるものだけとして扱います。 DSL/モデルから渡された Python をexecで実行します。また、AST のsafe_check()ガードは上流で無効に なっています。サンドボックスを再び有効にして強化するまでは、信頼できない DSL を 受け入れないでください。- MySQL なしで HITL や停止/再開が可能だと約束しないでください。 チェックポインターは その両方の基盤です。チェックポインターがなければ、永続的な一時停止はできません。
AgentNodeおよび非推奨の 3 つの基底クラスより、AgentBaseNodeを優先してください。- プロトコル関連の処理はエンジンではなく、アダプターに実装してください。 クライアントを サポートするためにノードの変更が必要なら、設計が本来の方針から逸れています。
- デフォルトが Alibaba 向けである場合は、その旨を伝えてください。 Qwen/DashScope、 OSS、Hologres のデフォルトは、プロジェクトの出自によるものであり、推奨によるものでは ありません。
- 共有リモートにプッシュする前に
preflight_audit.pyを実行し、履歴に残っている秘密情報は 単に追跡を解除するだけでなく、漏えいしたものとして扱ってください。
例
例 1:「Dify でフローを設計しました。次はどうすればよいですか?」
transpile モードを使用します。トランスフォーマーを実行し、host_substitutions を
上書きして、生成されたクラスを API キーマップに登録し、そのマップがデモ用の仕組みである
ことを明記します。
例 2:「自分のブランチのトークンがクライアントに漏れています」
そのようなことは起こらないはずです。チャンクプロセッサーは、実行されなかった
if-else/分類器の分岐を取り除きます。アダプターを修正するのではなく、すでに通過した
分岐を踏まえて、そのノードが answer/end ノードに確実に到達するかどうかを確認して
ください。
例 3:「MySQL なしで実行できますか?」
一部は可能ですが、どの機能が動かなくなるかを説明する必要があります。MySQL は LangGraph チェックポインターを支えているため、停止/再開や HITL は永続性を失います。
例 4:「フォークをオープンソースとして公開する予定です」
まず harden モードを使います。ご自身のチェックアウトに対して preflight_audit.py を実行してください。git status がクリーンでも、クローンから復元できるものがないとは限りません。また、上流でスクラブされる前のフォークには、元の認証情報が残っています。
例 5:「goalflow を使うべきでしょうか、それとも LangGraph だけでよいでしょうか?」
orient モードを使います。トランスパイルする Dify の設計がなく、差し替え可能なワイヤプロトコルも不要で、グラフ内でループをホストする必要もないのであれば、通常の LangGraph のほうが軽量です。その場合は別の選択肢を案内し、そう伝えてください。
参考資料
- references/dify-transpile.md — 2 段階のパイプライン、CLI フラグ、ホストの置換、生成される構造
- references/nodes-and-graph.md —
BaseNodeの契約、NodeOutputのユニオン、ファンイン、エラー処理戦略、ノードの全カタログ - references/agent-kit.md —
Agentのフック、グラフビルダー、ミドルウェアのカタログ、ハーネス/モデルルーター、実行可能なスキル - references/skills-engine.md —
SKILL.mdのフロントマター、LLM によるマッチング、プロンプトインジェクション、main とagent_kitのエンジン - references/serving-and-protocols.md — エンドポイント、データアダプター、3 層ストリーミング、HITL、ストレージと設定
- references/security-gate.md — 公開前チェックリストと各検出事項に伴う実際のコスト
- scripts/goalflow.sh — 読み取り専用の
doctor、およびauditとcheck-skillのパススルー - scripts/preflight_audit.py — 標準ライブラリのみを使用する公開前セキュリティゲート
- scripts/check_goalflow_skill.py — 標準ライブラリのみを使用する、実行時の
SKILL.mdフロントマターとインジェクションコストのチェック - goalflow GitHub リポジトリ
- プロジェクト標準:
.agent-skills/skill-standardization/SKILL.md