Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

research_assist

研究者向けのサーベイ論文ファインダー+新規性チェッカー。 キーワードが論文中で「目的(objective)」か「制約(constraint)」かを本文まで読んで判定する。 ("Undermind の素朴版" / 自前 ResearchRabbit)

アーキテクチャ

research_assist/
├── paper_novelty_checker.py   # リファレンス実装(単体で動くCLI。scaffoldの移植元)
├── backend/                   # Python + FastAPI + LangGraph
│   ├── app/
│   │   ├── main.py            # FastAPI エントリ(OpenAPI を吐く)
│   │   ├── config.py          # pydantic-settings + TOML ローダ(設定の単一ソース)
│   │   ├── schemas.py         # Paper / Judgment / RunRequest …(フロントとの契約)
│   │   ├── deps.py            # 認証など共通依存(スケルトン)
│   │   ├── llm/               # provider非依存LLM層
│   │   │   ├── registry.py    #   providers.toml からプロバイダ解決(旧 _LLM_REGISTRY)
│   │   │   └── client.py      #   complete() → 使用トークンも返す(課金用)
│   │   ├── pipeline/          # LangGraph
│   │   │   ├── state.py       #   GraphState(state→state の純ステップ)
│   │   │   ├── nodes.py       #   search/snowball/embed_rank/judge/deepen
│   │   │   └── graph.py       #   配線 + 「弱い判定は深掘り」条件サイクル
│   │   ├── services/          # 実ロジック(cache/semantic_scholar/pdf/judge)✅移植済
│   │   ├── routers/           # runs.py(SSEストリーム) / config.py(UI用メタ)
│   │   └── static/index.html  # 組み込みの軽量UI(バニラJS, ビルド不要)← 当面はこれで操縦
│   ├── config/
│   │   ├── providers.toml     # LLMレジストリ+料金 ← ハードコード排除
│   │   └── settings.toml      # 既定値・許容範囲・パイプライン設定
│   └── prompts/
│       └── objective_vs_constraint.ja.jinja2  # 判定プロンプト(仮置き。UIから編集可)
└── frontend/                  # (将来用)Next.js。当面は backend 組み込みUIで十分
    └── package.json           # `npm run gen:api` で OpenAPI → TS型生成

設計の3本柱

  1. 最大限カスタマイズ可能 / ハードコード排除 LLMレジストリ・料金・既定パラメータ・許容範囲・プロンプトはすべて config/*.tomlprompts/*.jinja2 に外出し。コードには「賢いデフォルト」だけ残し、上書きを設定で受ける。 UI は GET /config でカスタマイズ可能項目を取得して描画する。

  2. インタラクティブ=非同期+ストリーミング クロール+判定は数分かかるので、POST /runs で即 run_id を返し、 GET /runs/{id}/stream(SSE)で LangGraph の astream_events を流す。 論文が1件判定されるたびにUIへ届く。LangGraph の条件サイクル(弱い判定→深掘り→再判定)が このアプリでLangGraphを使う正当な理由。

  3. 自分+友人用 / 課金なし APIキーは環境変数でサーバ側が持つ(こちらが発行したキーを使う)。決済・台帳・認証は無し。 まずは関連研究を探すツールとして動くことを優先。 (将来 公開するなら、providers.toml に料金欄を残してあるので、後からメータリング層を 足せる設計にはしてある。)

プロバイダの線引き(重要)

  • Anthropic は純正 anthropic SDK(prompt caching / adaptive thinking / 正確な usage のため)。
  • OpenAI / Gemini / xAI / DeepSeek は openai SDK + base_url(いずれも OpenAI互換エンドポイント)。
  • Anthropic にも OpenAI互換シムは存在するが機能不足(キャッシュ・思考制御・usage精度を失う)なので 本番では使わない。client.py の分岐は意図的。

起動

cd backend
cp .env.example .env        # → .env に DEEPSEEK_API_KEY=... を1行書く(git管理外)
uv run uvicorn app.main:app --reload
# ブラウザで http://localhost:8000 を開く(/docs に Swagger, / が操縦UI)

.env(git管理外)に LLMキー(いずれか1つ)、任意で SEMANTIC_SCHOLAR_API_KEY。 UIから クエリ / キーワード / research question / 各件数 / プロバイダ / 判定プロンプト を すべて変更して実行でき、結果は判定されるたびにストリーム表示される。

実装ステータス

  • ✅ 設定の外出し(providers/settings TOML, jinja2 プロンプト), pydantic スキーマ
  • ✅ provider非依存LLM層, LangGraph 配線(条件付き深掘りサイクル含む)
  • services/ 実ロジック移植(検索/snowball/埋め込み/PDF/判定)
  • ✅ FastAPI + SSE + 組み込みUI(クエリ・件数・プロンプトをUIから変更可能)
  • ✅ DeepSeek で end-to-end 動作確認済み
  • ⬜ run_id の永続化(今はプロセス内メモリ), LangGraph checkpointer
  • ⬜ 深掘りノードの中身(grobid全文 / 近傍snowball / 再プロンプト)
  • ⬜ (必要になれば)Next.js フロント, 公開時の課金・認証

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages