ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗A question-answering assistant for students of the MSc Artificial Intelligence at Vrije Universiteit Amsterdam. It answers questions about exam rules, resits, admission and courses using only the official study guides and Teaching and Examination Regulations, cites its sources, and says "I couldn't find this" instead of guessing.
Runs fully locally on a laptop (no API keys, no data leaves the machine).
Headline result: on a 48-question evaluation set, retrieval Recall@5 went from 0.81 → 0.95 and answers containing the correct key facts from 0.81 → 0.91, with zero hallucinated answers on unanswerable questions.
Website: munish702.github.io/vu-rag-assistant. A scroll-driven page that shows the idea (the whole rulebook collapses into one plain answer) and ends in the chat. Online it replays real recorded answers; run it on your own computer for live ones (see Run the website).
A real answer from the assistant (asked in the app, 6 October 2026):
Q: What IELTS score do I need?
You need an IELTS Academic overall score of at least 6.5, with a minimum score
of 6.0 for each subcomponent (Listening, Reading, Writing, and Speaking) [1].
[1] Artificial Intelligence TER 2026-2027 - Article 7.2 Admission requirements (part 1/2)
General rule. Searched 1,102 passages, reranked 35, used 5.
flowchart LR
Q[Question] --> D[Dense search<br/>bge-small, top 20]
Q --> B[BM25 keyword search<br/>top 20]
D --> M[Merge candidates]
B --> M
M --> R[Cross-encoder reranker<br/>bge-reranker-base]
R --> S[Top 5 + reserved<br/>general-rule slot]
S --> L[LLM: qwen2.5 7B<br/>via Ollama]
L --> A[Answer with citations<br/>or abstain]
| Stage | What it does | Why |
|---|---|---|
| Ingestion | Parses PDFs into one chunk per course section / regulation article, with metadata (course code, article, programme, year) | Chunk boundaries follow the documents' own structure, so a rule is never cut in half |
| Dense search | Embedding similarity (BAAI/bge-small-en-v1.5, ChromaDB) | Understands meaning: "resit" ≈ "second examination opportunity" |
| BM25 | Keyword search, implemented from scratch | Precise on exact course names and codes like XM_0189 |
| Reranker | Cross-encoder reads question and chunk together (BAAI/bge-reranker-base) | Far more accurate ordering than comparing embeddings |
| Reserved slot | If no general regulation is in the top 5, the best-ranked one replaces #5 | General rules apply to every student; the reranker tends to prefer course pages |
| Generation | Local LLM answers only from numbered, scope-labelled sources | Citations make every claim verifiable; abstains when sources don't cover the question |
I built the evaluation before optimising anything, so every change is measured rather than guessed.
Eval set: 48 hand-checked questions written in a student's voice
(17 course lookups, 17 regulation questions, 7 multi-hop, 7 unanswerable).
Each answerable question is labelled with the location of its answer (e.g. Article 3.5 or course XM_0083, Method of Assessment) rather than a chunk ID, so labels stay valid when chunking changes.
Retrieval metrics: Recall@1, Recall@5 (is the answer in what the LLM sees?), MRR. Generation metrics:
| System | R@1 | R@5 | MRR | Key facts | All facts | Gold source retrieved | Wrong abstain |
|---|---|---|---|---|---|---|---|
| Dense retrieval | 0.61 | 0.81 | 0.71 | 0.81 | 0.80 | 33 / 41 | 0.05 |
| + BM25 candidates + reranker | 0.73 | 0.90 | 0.79 | 0.88 | 0.85 | 37 / 41 | 0.00 |
| + reserved general-rule slot | 0.73 | 0.95 | 0.80 | 0.91 | 0.88 | 39 / 41 | 0.00 |
All runs: abstained on 7 / 7 unanswerable questions; gold-source citation accuracy 0.97–1.00. Average answer time ≈ 4–5 s on a MacBook Air (16 GB RAM).
Recall@5 by question type
| System | Course lookups | Regulations | Multi-hop |
|---|---|---|---|
| Dense | 0.71 | 0.94 | 0.71 |
| + Reranker | 1.00 | 0.88 ⬇ | 0.71 |
| + Reserved slot | 1.00 | 0.94 | 0.86 |
The breakdown shows something the averages hide: the reranker fixed every course lookup but pushed general regulations down. The reserved slot was designed specifically to counter that, and recovered regulation recall without costing anything on course lookups.
| Change | R@1 | R@5 | MRR |
|---|---|---|---|
| Baseline chunking | 0.54 | 0.77 | 0.63 |
| Chunking v2 (facts as sentences, split list-style articles, separate footnotes) | 0.69 | 0.92 | 0.79 |
Better data preparation alone gave the biggest single jump in the project.
Hybrid search with Reciprocal Rank Fusion. Fusing dense and BM25 rankings with RRF lowered key-fact coverage from 1.00 to 0.62 on the 15-question set. RRF rewards chunks that are mediocre in both rankings over chunks that are excellent in one; BM25 fails completely on paraphrased questions ("graded" vs "grade") but still got an equal vote. Using BM25 only to nominate candidates for the reranker fixed this.
A score threshold for "no answer". Reranker scores look well separated on average (0.70 answerable vs 0.10 unanswerable), but the distributions overlap: the lowest answerable question scored 0.002, the highest unanswerable 0.55 (a deliberately tricky near-miss question). No threshold separates them, so abstention stays with the LLM, which reads the sources.
Prompt tuning on a 3B model. With llama3.2:3b, three prompt versions gave three different answers to the same question. When small prompt changes flip answers, the model is the bottleneck. Switching to qwen2.5:7b fixed it.
Credits: 30 retrieved poorly; "Master Project AI is worth 30 EC (30 ECTS credits)" retrieved well.Remaining failures (41 answerable): 2 retrieval misses (the reserved slot picks the wrong regulation article) and 1 numeric reasoning error (the model treats 12 EC as meeting an 18 EC requirement).
src/
├── config.py # all settings: models, paths, retrieval mode
├── ingest.py # PDFs -> structured, metadata-rich chunks
├── index.py # embed chunks into ChromaDB
├── retrieve.py # dense / BM25 / hybrid / rerank retrieval
├── generate.py # prompt construction + local LLM (Ollama)
├── evaluate.py # retrieval metrics (Recall@k, MRR)
├── evaluate_generation.py # abstention, key facts, citations
├── server.py # serves web/ and answers its chat, locally
└── app.py # the earlier Streamlit interface
web/ # the website (static: HTML, CSS, JS, photo planes)
tools/make_plates.py # how the night photo was cut into depth planes
tools/make_map.py # bakes the dot-matrix map layers (Netherlands + Amsterdam)
data/
├── raw/manifest.csv # which documents to download (PDFs not included)
└── eval/questions.jsonl # 48-question evaluation set
experiments/ # every evaluation run, with its full configuration
data/raw/manifest.csv from the VU website into data/raw/
(the PDFs are VU's and are not redistributed here).ollama pull qwen2.5:7bpython -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
python src/ingest.py
python src/index.py
python src/generate.py "Can I resit an exam I already passed?"
Evaluate: python src/evaluate.py and python src/evaluate_generation.py.
python src/server.py
This opens http://127.0.0.1:8000: the scroll page with a live chat, answered on your own computer: your questions never leave it. On macOS you can also double-click start.command. Thumbs up/down are saved to data/feedback.jsonl, which is not committed.
The earlier Streamlit interface still works: streamlit run src/app.py.
.github/workflows/pages.yml publishes web/ to GitHub Pages on every push to main (one-time setup: Settings → Pages → Source: GitHub Actions). There is no language model online, so the published chat replays three answers the assistant really gave, and labels each one as recorded.
Python · pdfplumber · sentence-transformers · ChromaDB · BM25 (from scratch) · cross-encoder reranking · Ollama (qwen2.5 7B)
Built by Munishwar Pradhan, MSc AI student at VU Amsterdam. Website photo: the VU main building at night, taken by the author. Map: Natural Earth 1:10m (public domain); the A10 ring is drawn through station coordinates from Wikipedia. Streamlit app background: "Amsterdam VU" by Rokus Cornelis, CC BY 3.0, via Wikimedia Commons (modified: faded and blurred).