Spaces:
Sleeping
Sleeping
File size: 22,674 Bytes
2f25a40 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | # ResearchPath β Project Log
A chronological record of decisions, work sessions, issues, and outcomes for the ResearchPath portfolio project.
**Schema for each entry:**
```
## YYYY-MM-DD HH:MM β [type] Title
**Type:** setup | decision | implementation | issue | resolution | discussion
**Status:** in-progress | complete | blocked | reverted
**Duration:** approx time
### Context
### Decisions
### Actions taken
### Issues encountered
### Files touched
### Outcome
### Next
```
---
## 2026-05-06 15:00 β [discussion] Project framing & scope
**Type:** decision
**Status:** complete
**Duration:** ~30 min
### Context
Chetan (~2.5 YOE Data Scientist, Kyndryl + ex-Swiss Re, targeting top product companies) needed a portfolio project. Earlier "Agentic RAG Document Search" on his resume was copied from another GitHub β needed a genuine, defensible project.
### Decisions
- **Rejected** Underwriter Copilot (insurance) and Equity Research Analyst (SEC filings) β too generic / didn't match his preference for research-flavored work.
- **Rejected** generic-RAG-over-papers framing β already exists (Perplexity, Elicit, Consensus); not enough differentiation.
- **Committed**: **ResearchPath** β agentic research-onboarding companion. Killer feature: prerequisite-chain reading-path planning. Genuinely agentic (graph traversal + recursive retrieval + reasoning over user state), not RAG-with-extra-steps.
- Demo domain: **Reinforcement Learning**. Architecture domain-agnostic.
- Stack: Gemini 2.5 Flash Lite + Groq Llama 3.3 70B (free tiers), BAAI/bge-small-en embeddings, FAISS, LangGraph, Streamlit, RAGAS.
- Eval-first methodology: gold dataset + ablation table is the differentiator from generic portfolios.
### Outcome
Project scope locked. 5-week plan in README.
### Next
Day 1 setup: env, deps, API keys, smoke test.
---
## 2026-05-06 15:20 β [setup] Day 1: Environment bootstrap
**Type:** setup
**Status:** complete
**Duration:** ~45 min
### Context
Stand up local dev env so the agent work in Week 2+ has a working LLM substrate.
### Decisions
- Use `uv` for Python + dependency management (already installed on user's machine).
- Default Gemini model: `gemini-2.5-flash-lite` (chosen after `gemini-2.5-flash` returned transient 503s during smoke test).
### Actions taken
- Scaffolded repo files: `.gitignore`, `.env.example`, `README.md`, `pyproject.toml`, `researchpath/__init__.py`, `researchpath/llm.py`, `scripts/smoke_test.py`.
- `uv python install 3.12` β installed CPython 3.12.9.
- `uv sync` β resolved 38 packages including `google-genai`, `groq`, `python-dotenv`, `rich`, `pytest`, `ruff`.
- User created `.env` from template and pasted Gemini + Groq API keys.
- `uv run python scripts/smoke_test.py` β both providers returned valid completions.
### Issues encountered
- **Unicode arrow `β` broke on Windows cp1252 codepage** when `rich` tried to write to stdout. Fix: removed the arrow from `scripts/smoke_test.py`. Also set `PYTHONIOENCODING=utf-8` for the run.
- **Gemini 2.5 Flash returned 503 UNAVAILABLE (transient overload)** despite a valid key. Fix: switched default model in `researchpath/llm.py` from `gemini-2.5-flash` to `gemini-2.5-flash-lite`.
### Files touched
- Created: `.gitignore`, `.env.example`, `README.md`, `pyproject.toml`, `researchpath/__init__.py`, `researchpath/llm.py`, `scripts/smoke_test.py`, `.claude/settings.local.json`, `PROJECT_LOG.md`.
- User-created (gitignored): `.env`.
### Outcome
Both Gemini and Groq APIs verified end-to-end. `.claude/settings.local.json` grants Bash + PowerShell auto-approval for this project (gitignored β personal preference, not committed).
### Next
Day 2: git init β arxiv corpus fetch script β download ~17 canonical RL papers β first commit.
---
## 2026-05-06 16:00 β [implementation] Day 2: Corpus pipeline + first commit
**Type:** implementation
**Status:** complete (with one outstanding follow-up β see "Outcome")
**Duration:** ~75 min
### Context
Build the end-to-end corpus path: fetch canonical RL papers from arXiv β parse PDFs β chunk text into a single JSONL ready for embedding. Land everything as the first git commit.
### Decisions
- **17-paper canon** chosen across 5 eras (value-based, policy-gradient, actor-critic, model-based, RLHF). See `researchpath/corpus.py`.
- **Streaming downloads via `requests`** instead of `arxiv` library's built-in downloader β the latter was truncating large PDFs at exact 1MB / 2MB boundaries on Windows.
- **PDF validation step** (open with pymupdf, read page 1) gates every download; truncated files auto-deleted and retried.
- **Chunking**: 800-char windows, 100-char overlap, sentence-boundary aware, hyphenation-aware.
- **Accept partial corpus (10/17)** rather than grind on rate-limited retries β script is idempotent so missing papers can be picked up later.
### Actions taken
- Added deps: `arxiv`, `pymupdf`. `uv sync` resolved 5 new packages.
- `researchpath/corpus.py` β 17-paper canon with `era` tag.
- `scripts/fetch_corpus.py` β streaming downloader with per-paper validate-and-retry, 12s inter-request spacing, 30s backoff.
- `researchpath/parsing.py` β PDF text extraction + sentence-boundary chunking.
- `scripts/parse_corpus.py` β drives parsing across all valid PDFs into `data/chunks.jsonl`.
- Ran fetcher: 10 papers landed cleanly. Deleted 3 truncated stragglers (`1801.01290`, `1911.08265`, `2301.04104`).
- Ran parser: **1,093 chunks, 778,995 chars** across 10 papers.
- `git init -b main` β first commit `270993c` ("Bootstrap ResearchPath: scaffold + corpus pipeline"). 13 files, 1,611 insertions.
### Issues encountered
- **arXiv HTTP 429 rate-limiting** on PDF endpoint. Tried 3sβ8sβ12s inter-request delays; eventually too much accumulated state on this IP. Pivoted to "accept partial corpus, document the gap" per user's `feedback_dont_grind.md`.
- **`arxiv` library truncates large PDFs at 1MB/2MB** even on retry β buffer issue specific to its downloader. Switched to direct `requests` streaming. (Confirmed by post-hoc validation: 3 stragglers stuck at exactly 2,097,152 / 1,048,576 bytes.)
- **Unicode `β` in console output** broke on cp1252 (already known from Day 1; reused `PYTHONIOENCODING=utf-8`).
### Files touched
- Added: `researchpath/corpus.py`, `researchpath/parsing.py`, `scripts/fetch_corpus.py`, `scripts/parse_corpus.py`.
- Modified: `pyproject.toml` (+arxiv, +pymupdf).
- Generated (gitignored): `data/papers/*.pdf` (10 files), `data/chunks.jsonl`.
### Outcome
End-to-end corpus path works: arxiv ID β validated PDF β chunked JSONL. Repo under git, first commit landed.
**Outstanding:** 4 papers still missing β `1511.05952` (PER), `1707.06347` (PPO), `1802.01561` (IMPALA), `2106.01345` (Decision Transformer). PPO is the painful gap (canonical paper). Re-run `uv run python scripts/fetch_corpus.py` later (script is idempotent + only retries missing/invalid).
### Next
Day 3: embeddings + FAISS index over `data/chunks.jsonl`. Use `BAAI/bge-small-en-v1.5` (CPU-friendly, ~133MB, strong on academic text). Then a tiny CLI: ask question β top-k chunks β grounded Gemini answer. That's the baseline RAG to measure against.
---
## 2026-05-06 17:00 β [implementation] Day 3: Embeddings, FAISS index, baseline RAG
**Type:** implementation
**Status:** complete
**Duration:** ~50 min
### Context
Stand up the first measurable RAG system: chunks β embeddings β vector search β grounded LLM answer with citations. This becomes the baseline that all future improvements (hybrid retrieval, reranker, agent planning) get measured against.
### Decisions
- **Embedding model: `BAAI/bge-small-en-v1.5`** (384 dim, ~133MB, CPU-fast, strong on academic text). Documents embedded raw; queries prefixed with the BGE-recommended retrieval instruction for measurably better results.
- **FAISS `IndexFlatIP`** with L2-normalized embeddings β exact cosine search, fast enough for ~1k chunks. Will swap to HNSW if corpus grows past ~50k.
- **Citation format `[arxiv_id, p<page>]`** β parseable by future eval code, human-readable in output.
- **System prompt is strict**: only-from-sources, no speculation. Will tighten further once we have eval numbers.
### Actions taken
- Added deps: `sentence-transformers`, `faiss-cpu`, `numpy`. `uv sync` resolved 29 new packages (~330MB inc. torch CPU).
- `researchpath/embeddings.py` β `Embedder` wrapper with separate `embed_documents` / `embed_query` (BGE wants different prefixes).
- `researchpath/index.py` β `build_index`, `load_index`, `search`. `Hit` dataclass carries score + citation metadata.
- `researchpath/rag.py` β `build_prompt`, `answer`. Strict system prompt enforcing citations + grounding.
- `scripts/build_index.py` β drives end-to-end embed + persist.
- `scripts/ask.py` β CLI for question β answer with citations. `--show-sources` flag for debugging retrieval.
- Built index: 1,093 chunks embedded in **148s** on CPU. Persisted `data/index.faiss` + `data/index.chunks.json`.
- **Smoke test query**: *"How does Rainbow combine multiple deep Q-learning improvements like Double DQN, Dueling networks, and prioritized replay?"*
- Answer correctly cited [1710.02298, p1] for Rainbow components and [1511.06581, p4] for Dueling architecture details.
- Listed all 6 Rainbow components accurately. No hallucination observed.
- 1,106 input / 196 output tokens (β free under Gemini quota).
### Issues encountered
- **HF Hub symlink warning on Windows** β cache-system can't use symlinks without admin/Developer Mode. Cosmetic only; cache works in degraded mode (more disk, no functional impact).
- **`VIRTUAL_ENV` mismatch warning from uv** β leftover env var from a prior shell session pointing at a different Python. Harmless; `.venv` is used regardless.
### Files touched
- Added: `researchpath/embeddings.py`, `researchpath/index.py`, `researchpath/rag.py`, `scripts/build_index.py`, `scripts/ask.py`.
- Modified: `pyproject.toml` (+sentence-transformers, +faiss-cpu, +numpy), `uv.lock`.
- Generated (gitignored): `data/index.faiss`, `data/index.chunks.json`.
### Outcome
Baseline RAG is **end-to-end working** and producing high-quality, grounded, cited answers on a real RL question. This is the system we'll measure in Day 4.
### Next
Day 4: **eval harness + gold dataset.** Build ~30 (question, expected answer key, expected source citations) tuples sourced from OpenAI Spinning Up problem sets, Sutton & Barto exercises, and 3-5 hand-curated questions per major paper. Then implement metrics (citation faithfulness, retrieval recall@k, answer quality blind-rated 1-5). First numbers go into the README eval table.
---
## 2026-05-06 18:00 β [implementation] Day 4: Eval harness + gold dataset + baseline numbers
**Type:** implementation
**Status:** complete
**Duration:** ~90 min
### Context
Build a rigorous eval harness before optimizing anything. Eval-first is the portfolio differentiator β ablation table beats vibes.
### Decisions
- **30-question gold dataset** across 10 indexed papers (3 per single-paper + 4 cross-paper comparison). Difficulty-stratified: 7 easy / 15 medium / 8 hard. Each example: `{id, question, expected_arxiv_ids, expected_key_claim, difficulty}`.
- **Three metrics** (no citation faithfulness per-claim β too expensive on free tier):
- `retrieval_recall@k`: fraction of expected arxiv IDs found in top-k hits
- `citation_presence`: answer cites at least one expected paper (string check)
- `answer_correctness`: LLM-as-judge (Groq llama-3.3-70b), YES/NO prompt
- **Judge model: Groq** not Gemini β Gemini free tier has 20 req/day limit (hit during initial test run). Groq handles batch eval at no cost.
- **RAG model: Groq** for batch eval. Gemini stays as default for `scripts/ask.py` (the demo CLI). Added `--groq` flag to `run_eval.py` to toggle.
- **Retry logic** added to `gemini_generate()` β parses retry delay from 429 error body, sleeps and retries up to 5 times.
### Actions taken
- `data/gold_dataset.json` β 30 QA triples (hand-authored from Spinning Up + paper reading).
- `researchpath/eval.py` β `GoldExample`, `EvalResult`, `EvalSummary` dataclasses + `evaluate_example`, `summarize`, `results_to_json`.
- `scripts/run_eval.py` β full pipeline: load index β batch retrieve + generate β judge β print table + save JSON.
- Updated `researchpath/rag.py` β added `generate_fn` injection param + `answer_groq()` convenience wrapper.
- Updated `researchpath/llm.py` β retry-with-backoff on Gemini 429 (parses `retryDelay` from error body).
- Ran full 30-question eval (`--groq`). Duration: ~3.5 min. Results saved to `data/eval_results.json`.
### Issues encountered
- **Gemini 20 req/day free-tier limit** β hit on second run (smoke test + partial full run = 20 calls). Fix: route eval to Groq entirely.
- **Retry delay detection**: Gemini's 429 body contains `retryDelay: '10s'` in the Details array. Regex extracts it; if missing, defaults to 15s sleep.
### Files touched
- Added: `data/gold_dataset.json`, `researchpath/eval.py`, `scripts/run_eval.py`.
- Modified: `researchpath/rag.py` (generate_fn injection, answer_groq), `researchpath/llm.py` (retry logic), `README.md` (eval table row 1).
- Generated (gitignored): `data/eval_results.json`.
### Outcome
**Baseline RAG numbers (Groq llama-3.3-70b, k=5, n=30):**
| Metric | Value |
|---|---|
| Retrieval Recall@5 | **90.0%** |
| Citation Presence | **86.7%** |
| Answer Correctness | **36.7%** |
| Avg Latency | **5.07s** |
| RAG Tokens | 33,498 in / 7,000 out |
**Gap analysis:** Retrieval finds the right paper in 27/30 cases β the FAISS index is working well. But answer correctness is only 37%, revealing two failure modes:
1. **Wrong-chunk problem**: Right paper retrieved, but the specific mechanistic claim is in a chunk outside top-5 (e.g., Rainbow's 6 components, distributional RL definition). Fix: hybrid retrieval (BM25 + vector) to catch exact-term hits + smaller chunks.
2. **Precision failure**: Right chunk retrieved, but answer paraphrases around the key claim without naming the specific mechanism (e.g., "stability" instead of "identifiability" for Dueling DQN mean subtraction). Fix: reranker + more directive prompt.
Difficulty breakdown: easy=28.6%, medium=53.3%, hard=12.5% answer correctness β harder questions show compounding retrieval + precision failures.
### Next
Day 5: Optimization round 1 β implement hybrid BM25+vector retrieval and measure improvement on same 30 gold examples. Target: push Answer Correctness from 37% β 55%+.
---
## 2026-05-06 19:30 β [implementation] Day 5: Hybrid BM25+FAISS retrieval (RRF fusion)
**Type:** implementation
**Status:** complete
**Duration:** ~90 min
### Context
Day 4 baseline showed Retrieval Recall@5=90% but Answer Correctness=37%. Root-cause: right paper retrieved but wrong chunks β dense embeddings de-prioritize specific technical terms ("conjugate gradient", "Polyak averaging", "identifiability") relative to surrounding context. BM25 keyword search catches exact-term hits that dense misses.
### Decisions
- **BM25Okapi** (rank-bm25 library) for sparse retrieval over the same 1,093 chunks.
- **Reciprocal Rank Fusion** (RRF, k=60) to combine BM25 and FAISS rankings without normalizing incompatible score spaces.
- **Stop-word filter** in tokenizer: query "What does GAE stand for?" without stop words = `['gae', 'stand', 'fundamental', 'tradeoff']` β much better signal than including "what", "does", "for", "it".
- **fetch_k=20** from each retriever before fusion, then top-k=5 from combined candidate set.
### Actions taken
- `researchpath/retrieval.py` β `BM25Retriever`, `HybridRetriever` with RRF fusion. Stop-word list added to tokenizer.
- `researchpath/index.py` β added `global_idx` field to `Hit` dataclass (FAISS vector position, globally unique across papers). Fixed **critical bug**: original code used `chunk_idx` (within-paper index, 0..N) as RRF dict key, causing collisions across papers with same within-paper index.
- `scripts/ask.py` β added `--hybrid` flag.
- `scripts/run_eval.py` β added `--hybrid` flag, fixed `Path.relative_to()` crash on relative paths.
- Ran full hybrid eval (`--groq --hybrid`): 29/30 questions (cross_04 errored on Groq 100K daily TPD limit).
### Issues encountered
- **global_idx bug**: `chunk_idx` is per-paper, not globally unique. Two chunks from different papers with the same within-paper index collided in the RRF dict, silently corrupting results. Fixed by adding `global_idx` (FAISS position) to Hit and using it in HybridRetriever. Pre-fix: hybrid was WORSE than dense in all spot checks. Post-fix: BETTER or TIED.
- **BM25 stop-word pollution**: Without filtering, "What does GAE manage?" matched InstructGPT appendix QA sections (had literal "What is X? A: ...") scoring 19.9. After adding stop-word filter, query tokens = `['gae', 'stand', 'fundamental', 'tradeoff', 'manage']`, GAE paper correctly ranked first.
- **Groq 100K daily TPD**: Exhausted daily token limit on the 30th question (cross_04). n=29 eval still valid; cross_04 retry deferred.
### Files touched
- Added: `researchpath/retrieval.py`.
- Modified: `researchpath/index.py` (+global_idx field), `scripts/ask.py` (+--hybrid), `scripts/run_eval.py` (+--hybrid, path fix), `README.md` (eval table col 2), `PROJECT_LOG.md`.
- Generated (gitignored): results in memory only (save failed on path bug, now fixed).
### Outcome
**Hybrid BM25+FAISS results (Groq llama-3.3-70b, k=5, n=29):**
| Metric | Baseline | Hybrid | Delta |
|---|---|---|---|
| Retrieval Recall@5 | 90.0% | 89.7% | -0.3 pp |
| Citation Presence | 86.7% | 86.2% | -0.5 pp |
| **Answer Correctness** | **36.7%** | **72.4%** | **+35.7 pp** |
| Avg Latency | 5.07s | 4.58s | -0.5s |
By difficulty: easy 100%, medium 73.3%, hard 42.9%. Hard questions remain the weak spot.
**Why hybrid helped so much:** The global_idx bug fix + stop-word filter together fixed hybrid retrieval so it correctly fuses dense + sparse signals. Many questions where the right paper was retrieved but answer was wrong (dense recall=100%, correct=N in baseline) flipped to correct under hybrid because BM25 surfaced chunks with the specific technical term rather than contextual chunks about the same topic.
### Next
Retry cross_04 when Groq TPD resets (saves the 30/30 result). Then: cross-encoder reranker as column 3 in the ablation table. Target: 75%+ correctness on hard questions.
---
## 2026-05-07 β [implementation] Day 5 cont.: Agentic planning loop (offline prerequisite-chain planner)
**Type:** implementation
**Status:** complete
**Duration:** ~60 min
### Context
The killer differentiator of ResearchPath over generic RAG is the prerequisite-chain reading-path planner: given a target RL paper and what the user already knows, compute the topologically-sorted chain of papers they need to read first. This module runs fully offline β no LLM calls, no API quota burned. It's the deterministic core that an LLM annotation layer will augment later.
### Decisions
- **Static prerequisite graph** as the seed: hand-curate ~10 edges covering canonical chains (DQNβDouble DQNβDueling DQNβRainbow, TRPOβGAE, DQNβDDPG, DQNβA3C, InstructGPTβDPO). Enough to demo the killer feature; LLM-extracted edges added in a future iteration.
- **BFS backwards** from target, stopping at `known_ids` β avoids pulling in papers the user already understands.
- **Kahn's algorithm** for topological sort with `(year, arxiv_id)` tie-breaking β deterministic + chronologically sensible for RL literature.
- **ReadingStep annotation**: each step carries `bridges_to` (which later papers depend on it), `concepts` (the bridging ideas), and `why` (user-facing rationale) aggregated from the static edge metadata.
### Actions taken
- `researchpath/prerequisites.py` β `Prerequisite` dataclass + `STATIC_PREREQUISITES` tuple (10 hand-curated edges) + `edges_into` / `edges_from` accessors.
- `researchpath/planning.py` β `ReadingStep`, `ReadingPlan` dataclasses + `_bfs_backwards`, `_topo_sort` (Kahn's), `_build_step`, `plan_reading_path`. `ReadingPlan.render_text()` produces human-readable ordered list.
- `scripts/plan.py` β CLI: `--target` (arxiv ID or tag, case-insensitive), `--known` (comma-separated), `--list`. Rich Panel output.
- `tests/test_planning.py` β 7 pytest tests: no-prereq paper (1 step), Rainbow full chain (4 steps in order), known set truncates, known target β empty plan, topo order respects all edges, unknown target raises ValueError, render_text contains target title.
### Smoke tests (pre-pytest, verified manually):
- Rainbow (`1710.02298`, no prior knowledge): `1312.5602 β 1509.06461 β 1511.06581 β 1710.02298` β
- Rainbow knowing DQN: `1509.06461 β 1511.06581 β 1710.02298` (3 steps) β
- DPO (`2305.18290`) knowing InstructGPT: 1 step (DPO itself) β
- DDPG (`1509.02971`): `1312.5602 β 1509.02971` (2 steps) β
### Issues encountered
None. BFS + Kahn's on the static graph is deterministic and small enough that correctness is straightforward to verify.
### Files touched
- Added: `researchpath/prerequisites.py`, `researchpath/planning.py`, `scripts/plan.py`, `tests/test_planning.py`.
### Outcome
7/7 pytest tests pass in 0.09s. Planning loop runs offline without any API calls. Demonstrates genuine agentic behavior (graph traversal, state-aware planning) that differentiates ResearchPath from simple RAG demos.
**Sample CLI output** (`uv run python scripts/plan.py --target Rainbow`):
```
1. [1312.5602] DQN (2013) β Playing Atari with Deep Reinforcement Learning
bridges: -> 1509.06461, 1511.06581, 1710.02298
concepts: Q-learning, experience replay, target network
2. [1509.06461] DoubleDQN (2015) β Deep Reinforcement Learning with Double Q-learning
bridges: -> 1511.06581, 1710.02298
concepts: overestimation bias, decoupled action selection/evaluation, Double Q-learning
3. [1511.06581] DuelingDQN (2015) β Dueling Network Architectures for Deep Reinforcement Learning
bridges: -> 1710.02298
concepts: dueling networks
4. [1710.02298] Rainbow (2017) β Rainbow: Combining Improvements in Deep Reinforcement Learning
bridges: <- target
```
### Next
- Retry cross_04 when Groq TPD resets β update README hybrid result from n=29 to n=30
- Run reranker full eval (column 3 in ablation table): `--hybrid --rerank`
- LLM annotation layer: map free-text user background β `known_ids` set; per-step "what to focus on" rationale
- Fetch 4 missing papers: PER (1511.05952), PPO (1707.06347), IMPALA (1802.01561), Decision Transformer (2106.01345)
---
|