Phase 7A:新規作成ファイル(この構成に合わせた案)
既存の “routers / schemas / services” 分割に合わせます。
app/routers/sql.py
POST /sql/execute_paramsを定義
app/schemas/sql_execute_params.py
- Request/Response(SqlResult含む)を定義
app/services/sql_execute_params.py
- パイプライン本体(Chroma検索 → LLM → Guard → dry_runレスポンス生成)
app/services/sql_guard.py
- nlq-dev の sql_guard.py をコピー移植(Phase 7A時点では prepare() が使えればOK)
※補足:すでに services/analytics/sql_validator.py があるので、将来的に統合もできますが、Phase7Aは「移植して確実に動かす」が最短です。
Phase 7A:既存修正が必要なファイル
app/main.py
routers/sql.pyを include_router する
app/openapi/openapi.yaml
- /sql/execute_params を追記(ここが重要。contract test 回避)
app/routers/__init__.py(必要な場合のみ)
- ルータをまとめてexportしている運用なら追加
※ main.py が個別 import なら不要
app/schemas/__init__.py(必要な場合のみ)
- スキーマを集約exportしている運用なら追加
※ 直接importなら不要
app/config.py(Phase7Aでは “必要なら”)
- 既存の
services/analytics/llm_sql.pyが 設定値を config.Settings から読む作りなら、SQL生成用の model 名や top_k default を追加する可能性あり - ただし Phase7A は dry_run のため、最小は「既存設定の流用」で済むケースが多いです
Phase 7A: Endpoint追加+dry_run完了(最小で確実)
目的:nlq-dev から呼べて、SQL生成結果(安全化後のSQL)が返る
Dev-Portal:
POST /sql/execute_paramsChroma検索 → LLM SQL生成 → sql_guard.prepare()options.dry_run=trueのとき executed_sqlのみ返す(rows/columns空、row_count=0)
DoD:- curlで dry_run 200
executed_sqlが guard 後の final_sql
Phase 7B: non-dry-runでOdoo DB実行+返却(動く最短)
目的:実行して結果(columns/rows/row_count)を返す
Dev-Portal:
- Odoo DB接続(host=postgres, db=odoo, user=odoo…)
SET LOCAL statement_timeout等を必ず入れてから実行- rows/columns 返却(
columns + rows形式)
DoD: - 軽いクエリで rows が返る
- timeout を超えるクエリがちゃんと止まる
Phase 7C: 運用の地雷を踏まない仕上げ(ここで“安全にする”)
目的:nlq-dev 側で落ちない・暴走しない
Dev-Portal:
- 結果の JSONシリアライズ正規化(datetime/Decimal/UUID/JSONBなど)
max_rowsの上限制御(LIMIT矯正)- エラー形式の統一(Problem+JSON等)
- 任意で
sql_hash/guards_applied追加
DoD: - nlq-dev が例外なく受け取れる
- 危険SQL(DDL/DML等)が確実にブロックされる
既存で修正が必要なファイル(Phase 7A)
api/app/main.pyinclude_router(sql_router, prefix="")を追加- tags の整備(必要なら)
api/app/config.py- Settings 追加(Phase 7A で最低限必要なもの)
- LLM用(既に OpenAI は使っているはずなので不足分だけ)
SQL_BUILD_MODEL(例:gpt-4o-mini等)※既存の translate用モデルとは分けてもOK
- Chroma検索用
CHROMA_URL(既存)CHROMA_COLLECTION_FIELD_JA=portal_field_jaCHROMA_COLLECTION_VIEW_COMMON_JA=portal_view_common_jaCHROMA_TOP_K_DEFAULT(任意)
- LLM用(既に OpenAI は使っているはずなので不足分だけ)
- ※Odoo DB 接続設定は Phase 7B で必須。7Aでは不要。
- Settings 追加(Phase 7A で最低限必要なもの)
- 既存の
api/app/services/chroma_client.py/services/*(必要なら)- すでに Chroma 検索があるなら流用して 検索関数を1つ足すだけで済む可能性あり
- 例:
search_docs(query, collections=[...], top_k=...)
- 既存の OpenAI ラッパ(もしある場合)
services/translate.py等しかないなら、SQL生成用の 軽い呼び出し関数を追加- 例:
services/llm_client.pyを新規に切っても良い(ただし7Aは最小でOK)
コメントを残す