目的: 生成も埋め込みも OpenAI API のみを使い、その他はすべてローカル(無料)で完結する最小RAG。
ベクトルDBは使わず、JSONに埋め込みを保存し、Numpyのコサイン類似で検索します。
- API: FastAPI (
/ask
) - 埋め込み:
text-embedding-3-small
(OpenAI) - 生成:
gpt-4o-mini
(OpenAI) - ストレージ:
index.json
(ローカルに埋め込みキャッシュ) - 文書:
docs/
に.md/.txt/.pdf
を配置
python -m venv .venv
source .venv/bin/activate # Windowsは .venv\Scripts\activate
pip install -r requirements.txt
# OpenAIのAPIキーを設定
cp .env.example .env
# .env を開いて OPENAI_API_KEY=... を記入
uvicorn app:app --host 0.0.0.0 --port 8000
# または
python app.py # (uvicorn不要の簡易実行)
起動時に docs/
を走査 → 分割 → OpenAI埋め込み → index.json
に保存します。以降は毎起動時に再構築します(最小構成のため)。
curl -X POST http://localhost:8000/ask \
-H "Content-Type: application/json" \
-d '{"question":"このプロジェクトの目的は?"}'
<div>
<input id="q" placeholder="質問を入力" style="width:70%"><button onclick="ask()">Ask</button>
</div>
<pre id="ans"></pre>
<script>
async function ask(){
const q = document.getElementById('q').value;
const r = await fetch('/ask', {method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify({question:q})});
const j = await r.json();
document.getElementById('ans').textContent = j.answer + "\n\n(出典: " + (j.sources||[]).join(", ") + ")";
}
</script>
- 費用は? → OpenAI API(埋め込み&生成)のトークン課金のみ。他はローカル。
- 日本語PDFが抜ける →
pypdf
で空になる場合はpdfminer.six
に差し替えを検討。 - 精度を上げたい → チャンクサイズ/オーバーラップ調整、Top-k増加、systemプロンプト強化。
- 更新のたびに再構築は重い → 監視で差分のみ埋め込む実装に拡張可能。
MIT(サンプル)。