オフショアに渡す前に、あなた側でここまでできていれば十分、というラインをこう置きます:
- nlq-dev バックエンドのエンドポイント構成とDBスキーマがほぼ固定されている
- k8s/base(nlq-api, Chroma, Neo4jスケルトン)が用意されていて、
ローカルでkubectl applyすれば最低限動く - nlq-dev ⇔ dev-portal(Postgres / Chroma)のインタフェース仕様が文書化されている
- Neo4j は k8sとenvだけ用意した「席だけある」状態
これを、無理のない粒度でタスクに分けます。
タスク1:現状整理&リポジトリの基本ルール固め
目的: あとからオフショアに「この形を守ってね」と言えるようにする。
nlq-devリポジトリのトップにREADME.mdを置く(簡易でOK)- プロジェクト概要(NLQ → SQL → 分析)
- ディレクトリ構成(
api/,k8s/,sql/など) - ローカル起動方法(今できる範囲だけ)
.env.exampleを整備DATABASE_URLCHROMA_URLNEO4J_URI(空でいいがキーだけ書いておく)OPENAI_API_KEYなど
- バックエンドのエントリポイントを一箇所に固定
- 例:
api/app/main.py(portal-dev と似た構造に寄せる)
- 例:
👉 ここは「1日あれば終わる」レベルの軽作業です。
タスク2:nlq-dev バックエンドのエンドポイント骨格を確定
目的: フロントとオフショアに「この API 前提で作って」と渡せる状態にする。
- NLQ関連の主要エンドポイントだけは固定しておく
- 例:
POST /nlq/planPOST /nlq/executeGET /nlq/historyPOST /nlq/analysisPOST /nlq/analysis/{analysis_id}/upsert
- 例:
- Pydanticスキーマを軽く整理
PlanRequest,ExecuteRequest,AnalysisResponse,DiffUpsertResponseなど
- 中身のロジックはダミーでもOKだが「I/Fだけは変えない」方針にする
- 例:
/nlq/analysisは今はスタブで"This is dummy analysis"を返すだけでもよい
- 例:
👉 ここができると、フロント実装はかなり任せやすくなります。
タスク3:Chroma 設計&環境変数の固定
目的: Dev-Portal と nlq-dev が 同じ前提で Chroma を使えるようにする。
- Chromaのコレクション命名ルールを決めておく
- 例:
- Dev-Portal フィールドJA:
portal_field_ja - Dev-Portal ビューJA:
portal_view_common_ja - NLQセッション用:
nlq_sessions_ja/nlq_sessions_en
- Dev-Portal フィールドJA:
- 例:
config.py的な場所で環境変数→設定のマッピングを書くCHROMA_URLCHROMA_COLLECTION_FIELD_JACHROMA_COLLECTION_VIEW_JACHROMA_DEFAULT_COLLECTION(あれば)
/nlq/analysis/{analysis_id}/upsertで使うコレクションのルールを一言コメントに残す- 例:「NLQの分析コメントは
nlq_sessions_{lang}に入れる」
- 例:「NLQの分析コメントは
👉 これは「後から変更したくない設計」の部分なので、今のうちに軽くでも決めておくのが吉です。
タスク4:k8s/base(ローカル用)の骨格を作る
目的: 後でオフショアが overlays/dev/prod を増築しやすい「基礎」を作る。
最小構成はこれくらいでOKです:
k8s/base/nlq-api/deployment.yamlapp: nlq-apicontainerPort: 8000readinessProbe: /health/ready
k8s/base/nlq-api/service.yaml- ClusterIP でOK。
k8s/base/chroma/deployment.yaml+service.yaml- 既に portal-dev で使っている構成をほぼコピペでOK(namespace だけ注意)
k8s/base/neo4j/deployment(or statefulset).yaml+service.yaml- 今は 中身はほぼデフォルト & 1ノード でOK
k8s/base/postgresは- 既存の Odoo/Dev-Portalと同じ Postgres を使うなら、ここでは触らず「外部リソース」と見なしてもよい
👉 この段階では overlays/dev/prod は空でもよくて、base が揃えばOK。
(後で「ここをオフショアに触らせる」前提)
タスク5:nlq-dev ⇔ Dev-Portal のインタフェース仕様を書面化
目的: コードをいじる前に、どの情報を dev-portal 側からもらうかを明文化。
- Markdown 1ファイル(例:
docs/nlq-dev-portal-integration.md)を書く- nlq-dev が必要とするメタ情報:
- モデル名/テーブル名
- 各フィールドのラベル・説明
- Viewの説明/用途(あれば)
- それをどこから取るか:
- 直接 Postgres(
portal_model,portal_field,portal_view_*)を読むのか - それとも Dev-Portal API を叩くのか
- 直接 Postgres(
- 参照方向:
- きほん「nlq-dev → Dev-PortalのDB/Chromaを読むだけ」(書き込みはしない)と決める、など
- nlq-dev が必要とするメタ情報:
- ここに「後で絶対に変えたくないルール」も一言書いておく
- 例:
model + field_nameは自然キーとして扱う、など
- 例:
👉 これがあると、**Dev-PortalのUIやオフショアの実装を変えるときの“軸”**になります。
タスク6:Neo4j スケルトンだけ先に用意(中身ナシでOK)
目的: 3ヶ月後にいつでも Odoo→Neo4j を始められる“席”を用意する。
k8s/base/neo4jを作成(上のタスク4と一体でやってOK).env.exampleにNEO4J_URI,NEO4J_USER,NEO4J_PASSWORDを追記api/app/services/graph_client.pyみたいなファイルを1つだけ作る- 中身は「接続クライアントの雛形」だけでOK:
- 接続を作る関数
ping()的なヘルスチェックだけ実装
- 中身は「接続クライアントの雛形」だけでOK:
- README に「Neo4j は今は“空の席”。将来 Odoo データ連携を入れる予定」と一文書いておく
👉 これで、「今は使ってないけど、ちゃんと設計に組み込まれている」状態になります。
タスク7:オフショアへ渡すための “まとめファイル” を作る
目的: ここまでできたら一旦「私のターン終了」、と区切れるようにする。
docs/offshore-hand-off.mdみたいなファイルを作る- プロジェクト全体像(nlq-dev + dev-portal + Chroma + Neo4j + Odoo)
- 今回、オフショアにお願いしたい領域:
- フロント実装(nlq-dev, Dev-Portal)
- k8s/overlays/dev, overlays/prod
- AWS(EKS/ALB/ACM) 移行
- 「ここは触らないでほしい」という領域:
- DBスキーマ
- Chromaコレクション設計
- Neo4jのCypher(当面)
- ざっくり PR 粒度の例(
NLQ-PR-01など)
👉 この1ファイルがあれば、「そろそろハンドオフしよう」と思ったときにすぐ動けます。
進め方のおすすめ
- まずは タスク1 → 2 → 3(設計とAPI周り)を先にやる
- そのあと タスク4(k8s/base) でローカルの“箱”を作る
- 時間と気力があれば タスク5/6/7 を少しずつ埋めていく
どれも「丸一日〜数日で終わるサイズ」にしてあるので、
仕事の合間にちょこちょこ進めつつ、頃合いを見てオフショアに投げる、というスタイルが取りやすいと思います。
「タスク2の API 骨格だけもう少し具体的に見たい」みたいな感じなら、
次は nlq-dev 用の openapi スケッチか routers/nlq.py のテンプレを書き起こすところから一緒にやりましょうか。
あなた:
この後のオフショアのタスクを同じように分割して提示してください。その際、理解しておくべきことも書いて欲しいです。
ChatGPT:
思考時間: 1m 12s
いいですね、「まずこちらで土台を作ってから、まとまった塊をオフショアに渡す」やり方は絶対やりやすいです 👍
では、その**“土台ができた後” にオフショアにお願いするタスク**を、こちら側のタスクと同じノリで分割してみます。
前提(あなた側でやるところ)
ここまでが終わっている前提で書きます:
- nlq-dev の バックエンドAPIの骨格とスキーマがほぼ固定
k8s/base/*が一通りある(nlq-api,chroma,neo4jの Deployment/Service など)- Chroma のコレクション名・メタデータの方針が決まっている
docs/offshore-hand-off.mdやdocs/nlq-dev-portal-integration.mdで
**「触っていいところ/触ってほしくないところ」**が文章化されている
この状態からスタート、という想定です。
Offshore-Task 1:キックオフ&環境再現
目的:
オフショア側が「全体像」と「守備範囲」を理解し、ローカル or dev クラスタで nlq-dev を動かせる状態にする。
やってもらうこと
nlq-devリポジトリを cloneREADME.md/docs/offshore-hand-off.md/docs/nlq-dev-portal-integration.mdを一通り読む- あなたが用意した
.env.exampleをもとにローカル用.envを作成 - あなたの手順書どおりに
- ローカル or dev クラスタに nlq-api, Chroma, Neo4j(骨格)を起動
curlやhttpie, VSCode REST などで/health/readyや NLQ API を軽く叩いてみる
★理解しておくべきこと
- プロジェクト全体構成:
- Odoo(業務DB)
- Dev-Portal(メタ情報+Chroma)
- nlq-dev(NLQ→SQL→分析+差分 upsert)
- 「DBスキーマとChroma/Neo4j設計は Raqqa側がオーナー」であり、
- オフショアは「それを safely 利用する側」であること
k8s/baseとk8s/overlays/*の役割の違い- base = あなたが決めた“標準形”
- overlays = 環境ごとの調整(ここはオフショアの主戦場)
Offshore-Task 2:nlq-dev フロント実装(NLQフロー基本画面)
目的:
NLQ の「計画 → 実行 → 履歴」を、あなたが用意した API 骨格に沿ってフロントで操作できるようにする。
やってもらうこと
- Figma / 画面仕様にあわせて、NLQ の基本画面を実装
- NLQ入力画面(テキストボックス+送信ボタン)
- プラン表示画面(どんな SQL が出るか)
- 実行結果画面(テーブル表示、件数)
- 履歴一覧(過去の NLQ セッション一覧 or タイムライン)
- あなたが確定した API を利用して接続
POST /nlq/planPOST /nlq/executeGET /nlq/history
- 最低限のエラーハンドリングを実装
- HTTPエラー / タイムアウト時のメッセージ表示
- ローディングのスピナーなど
★理解しておくべきこと
- NLQ の基本フロー
- 自然言語 → plan(候補SQL) → execute(Postgres)→ 結果 → history
- APIはあなたが決めた契約が絶対であり、
「フロントに合わせてAPIを変える」のではなく「わからない点は質問する」方針であること - Odoo のテーブル構造までは深く理解していなくてもよいが、
- SELECTのみ実行
- LIMITが必ずかかる
など、安全系の思想は頭に入れておくこと
Offshore-Task 3:nlq-dev 分析+差分アップサート UI & 配線
目的:
NLQ結果に対してAI分析を行い、その分析結果を Chroma に diff-doc として upsert する一連の流れをフロントから操作できるようにする。
やってもらうこと
- Figma で定義済みの「分析画面」「タイムライン」を実装
- 対象ステップに対する「AI分析結果」の表示
-「次のアクション」「要約」などのセクション
- 対象ステップに対する「AI分析結果」の表示
- 分析APIとの連携
POST /nlq/analysisで分析を生成(もしくは取得)- 分析ステータスの表示(処理中/完了/失敗)
- Diff upsert 操作の実装
POST /nlq/analysis/{analysis_id}/upsertを呼び出すボタン- 成功時/失敗時のトースト表示
- ログ確認手順をREADME等にまとめる
- どのログを見れば doc_id や collection がわかるか
※ コアなプロンプト設計や、メタデータの意味付けはあなた側が主導する前提で、
オフショアは「サービス層を呼ぶ」「レスポンスを表示する」部分がメイン。
★理解しておくべきこと
- Chroma の役割:
- 「分析コメント」や「メタ情報」を後から検索するためのストレージとして使っていること
- あなたが決めた Chroma の設計ルール:
collection名doc_idの生成ルールmetadataに必ず含めるキー(session_id, used_tables など)
- 「upsert は冪等(idempotent)」であること
→ 同じdoc_idに対する再アップサートは「上書き」であり、重複を増やすものではないこと
Offshore-Task 4:Dev-Portal の入力UI実装(フロント)
目的:
あなたが設計した Dev-Portal のモデル/フィールド/ビュー入力画面を、Figma と OpenAPI に忠実に実装する。
やってもらうこと
- Figma.make の画面定義を見ながら、各画面のコンポーネントを実装
- モデル一覧
- モデル詳細(フィールドタブ/ビュータブ)
- View Common / View 詳細編集画面
- あなたが用意した Screen↔API マッピングに従い、Dev-Portal API に接続
GET /portal/modelsGET /portal/models/{id}POST/PATCH /portal/models/{id}
など実際のパスに合わせて
- フォームのバリデーション・エラー表示を実装
- 必須項目
- 型のチェック(数値/選択肢など)
★理解しておくべきこと
- Dev-Portal の目的:
- Odoo の「構造(モデル/フィールド/ビュー)」を
人間とAIの両方がわかりやすい形で管理するポータルであること
- Odoo の「構造(モデル/フィールド/ビュー)」を
portal_model,portal_field,portal_view_*などのテーブルは、**業務DBではなく“メタDB”**であること- i18nの扱い:
- ラベル・ヘルプ等が
*_i18nの JSONB で管理されていること - 翻訳は専用のパイプラインがあるので、フロント側で勝手に翻訳しないこと
- ラベル・ヘルプ等が
Offshore-Task 5:Dev-Portal UI → 翻訳/Chroma/nlq-dev への配線
目的:
Dev-Portal 上で入力されたメタ情報が、翻訳 → Chroma → nlq-dev まで流れるように、UIからパイプラインを「発火」できる状態にする。
やってもらうこと
- Dev-Portal UI から翻訳ジョブをキックする操作を実装
- 例:対象モデル/フィールドを選択して「翻訳キューに送る」ボタン
POST /translate/run等、既存のOpenAPIに従う
- Chroma package / upsert 操作をフロントから起動できるようにする
- 例:管理画面から
POST /chroma/package→POST /chroma/upsertを叩く
- 例:管理画面から
- nlq-dev から見たときに、
- 必要なメタ情報(モデル説明/フィールド説明)が Chroma に入っている状態が作れることを確認
★理解しておくべきこと
- 翻訳パイプラインの概念:
- Dev-Portal →
portal_translate→portal_chroma_doc→ Chroma の流れ
- Dev-Portal →
- 「UIからは“トリガーを押すだけ”」であり、
- パイプラインの中身(SQLやバッチ処理)は Raqqa 側が責任を持つ領域であること
- nlq-dev は、このメタ情報を RAG の文脈として参照するだけで、
メタ情報の生成や品質は Dev-Portal 側の責任範囲であること
Offshore-Task 6:k8s/overlays/dev・prod および AWS 移行
目的:
あなたが作った k8s/base をベースに、実際の dev/prod 環境で nlq-dev + Dev-Portal を動かす。
やってもらうこと
k8s/overlays/devの整備- レプリカ数、リソースリクエスト/リミット
- dev 用 Ingress(
dev.example.com的な) - 簡易な Basic 認証 or IP制限(必要なら)
k8s/overlays/prodの整備(AWS EKS 前提)- Ingress に ALB コントローラ用の annotation 付与
- ACM 証明書 ARN の設定
secret-api-db,secret-api-authなどシークレット連携
- AWS 上での動作確認
kubectl apply -k k8s/overlays/prodがエラーなく通る/health/readyが 200 を返す- 簡単な NLQ クエリ〜分析まで通る
★理解しておくべきこと
baseは Raqqa 側がコントロールし、
overlays でだけ環境依存の要素を変えるという方針- AWS EKS / ALB / ACM の基本構造
- EKSクラスター
- ALB Ingress Controller
- ACM 証明書
- シークレットや認証情報は Gitにコミットしない こと
→ マニフェストはsecretRefまで、値は別管理であること
Offshore-Task 7:CI/CD スケルトン構築(最後の仕上げ)
目的:
「新規顧客プロジェクトが始まったときに、このテンプレをコピーすれば環境が立ち上がる」状態を CI/CD でサポートする。
やってもらうこと
- GitHub Actions(または他CI)で、
nlq-devとdev-portalのビルド&テストジョブを用意- Docker image をコンテナレジストリ(GHCR / ECR)に push
- 手動トリガー(workflow_dispatch)で、
- 特定のバージョンを dev / prod にデプロイするジョブを用意
(ここは skeleton でOK。kubectl apply or ArgoCD sync のラッパ程度)
- 特定のバージョンを dev / prod にデプロイするジョブを用意
- CI でやりすぎないこと:
- この段階では「最低限ビルド+テスト+デプロイ」が出来ればよく、
- 複雑なマトリクスやマルチテナント自動構築まではやらない
★理解しておくべきこと
- 「CI/CD の設計権限は Raqqa 側にあり、
今回は “スケルトンを作る” ところまでがスコープ」であること - GitHub Actions の基本:
- workflowのトリガー
- job / step / runnerの概念
- シークレットの扱い
- 将来、「顧客ごとの overlay」「Helm values」などを CI で扱う可能性はあるが、
今回のスプリントではそこまで踏み込まないこと
こんな感じで分けておくと、
- あなた側:設計・スキーマ・バックエンド骨格・base k8s
- オフショア:フロント実装・overlays・AWS・CI/CD
という役割がかなりクッキリします。
このうち、「まずは Offshore-Task 1〜3 だけやってもらう」といった形で
段階的に依頼していくのもアリですし、各タスクを PR 番号(NLQ-PR-01 みたいな)に紐づけても運用しやすいと思います。
コメントを残す