Skip to content

Commit 552dd97

Browse files
committed
Add agentic local knowledge and API service foundation
1 parent b877145 commit 552dd97

13 files changed

Lines changed: 1037 additions & 96 deletions

README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<p>
44
<a href="https://github.com/2002yy/study-agent/actions/workflows/ci.yml"><img src="https://github.com/2002yy/study-agent/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
55
<img src="https://img.shields.io/badge/python-3.12-blue" alt="Python 3.12">
6-
<img src="https://img.shields.io/badge/tests-277%20passed-green" alt="277 tests passed">
6+
<img src="https://img.shields.io/badge/tests-290%20passed-green" alt="290 tests passed">
77
</p>
88

99
A local AI learning assistant with long-term memory, role-based group chat,
@@ -17,7 +17,7 @@ Study Agent 是一个本地优先的 AI 学习助手,重点不是简单调用
1717
- **长期记忆**:Markdown memory + safe writer
1818
- **上下文分层**:fast / light / deep / archive
1919
- **联网搜索**:RSS / News fetch → article extraction → LLM digest → source tracing
20-
- **RAG MVP**:本地 Markdown / TXT / DOCX / PDF 索引、关键词 / 本地向量原型 / hybrid / backend-vector 检索、可配置 embedding provider、可选 Chroma 持久化、引用上下文、来源块、Streamlit 检索/调试面板、聊天注入和 FastAPI RAG 接口
20+
- **RAG MVP**:本地 Markdown / TXT / DOCX / PDF 索引、关键词 / 本地向量原型 / hybrid / backend-vector 检索、可配置 embedding provider、可选 Chroma 持久化、受控本地知识检索工具、引用上下文、来源块、Streamlit 检索/调试面板、聊天注入和 FastAPI RAG / chat / memory 基础接口
2121
- **工程安全**:SSRF protection、detect-secrets、配置模板
2222
- **工程质量**:pytest 测试套件、Ruff、GitHub Actions CI、打包检查
2323

@@ -27,11 +27,11 @@ Study Agent 是一个本地优先的 AI 学习助手,重点不是简单调用
2727
- **Model routing** with fast / light / deep / archive context tiers
2828
- **Long-term memory** based on Markdown files and safe-writer persistence
2929
- **Web search pipeline**: feed registry → URL safety checks → article extraction → LLM digest → auditable source trace
30-
- **RAG MVP**: local Markdown / TXT / DOCX / PDF indexing, lexical / local vector prototype / hybrid / backend-vector retrieval, configurable embedding providers, optional Chroma persistence, citation-first context formatting, source blocks, a Streamlit retrieval/debug panel, optional chat injection, and FastAPI RAG endpoints
30+
- **RAG MVP**: local Markdown / TXT / DOCX / PDF indexing, lexical / local vector prototype / hybrid / backend-vector retrieval, configurable embedding providers, optional Chroma persistence, a controlled local-knowledge retrieval tool, citation-first context formatting, source blocks, a Streamlit retrieval/debug panel, optional chat injection, and FastAPI RAG / chat / memory foundation endpoints
3131
- **SSRF protection** for article fetching, **detect-secrets** in CI
3232
- **Batched session logging** and multi-layer caching for performance
3333
- **Performance budget**: mode-based `max_tokens` bounds on the main chat, WeChat, and news LLM paths
34-
- **277 pytest tests**, Ruff clean, mypy clean, GitHub Actions CI workflow
34+
- **290 pytest tests**, Ruff clean, mypy clean, GitHub Actions CI workflow
3535

3636
For a detailed breakdown of the stack and engineering highlights, see [Technical Stack & Engineering Highlights](docs/TECH_STACK.md).
3737

@@ -109,7 +109,7 @@ Study Agent 的定位很明确:**一个运行在你本地的、有长期记忆
109109
| **角色群聊** | 四位角色(三月七、刻晴、纳西妲、流萤)群聊讨论,各有独立人设 |
110110
| **联网搜索** | Google News + Bing News + RSSHub 多源聚合,页面正文三层提取 |
111111
| **来源追溯** | 搜索结果写入群聊记录,可回溯依据 |
112-
| **RAG MVP** | 本地 Markdown / TXT / DOCX / PDF 文档索引,前端面板返回带文件路径、行号、分数、命中词和 score breakdown 的引用片段,并可注入单人聊天和微信群互动回复;FastAPI 提供 `/health``/rag``/rag/index``/rag/query` |
112+
| **RAG MVP** | 本地 Markdown / TXT / DOCX / PDF 文档索引,前端面板返回带文件路径、行号、分数、命中词和 score breakdown 的引用片段,并可注入单人聊天和微信群互动回复;FastAPI 提供 `/health``/rag``/rag/index``/rag/query``/rag/status``/rag/upload``/rag/local-knowledge` |
113113
| **课后总结** | 学习完成后自动总结进展,用户确认后写入记忆 |
114114
| **长期记忆** | 学习者画像、进度追踪、项目上下文、当前焦点,多级记忆档案 |
115115
| **多 Provider** | 支持 OpenAI / DeepSeek / OpenRouter / SiliconFlow / 本地模型 |
@@ -233,7 +233,7 @@ RAG_EMBEDDING_PROVIDER=local_hash
233233
│ ├── llm_router.py # 模型路由分发
234234
│ ├── context_builder.py # 上下文构建
235235
│ ├── mode_manager.py # 模式管理(版本/性能/氛围)
236-
│ ├── api.py # FastAPI health / RAG endpoints
236+
│ ├── api.py # FastAPI health / chat / memory / sessions / RAG endpoints
237237
│ ├── role_manager.py # 角色加载与管理
238238
│ ├── performance_budget.py # 性能预算(max_tokens 分级)
239239
│ ├── memory.py # 记忆系统
@@ -250,6 +250,7 @@ RAG_EMBEDDING_PROVIDER=local_hash
250250
│ ├── router.py # 路由配置
251251
│ ├── news/ # 新闻聚合链路
252252
│ ├── rag/ # 本地 RAG MVP:加载、分块、索引、关键词/向量原型/embedding/可选后端检索
253+
│ ├── tools/ # 受控工具边界:本地知识检索等
253254
│ └── ui/ # Streamlit UI 组件
254255
├── tests/ # pytest 测试套件
255256
├── docs/ # 设计文档与工程说明
@@ -270,7 +271,7 @@ RAG_EMBEDDING_PROVIDER=local_hash
270271
## 测试
271272

272273
```bash
273-
pytest tests/ -v # current local baseline: 277 passed
274+
pytest tests/ -v # current local baseline: 290 passed
274275
pytest tests/ --cov=src # 覆盖率
275276
ruff check src/ tests/ # linting
276277
mypy --explicit-package-bases src/ # type check
@@ -312,8 +313,8 @@ CI 通过 GitHub Actions 在 push / pull request 上运行,集成 `pytest`、`
312313

313314
求职导向的技术演进路线:
314315

315-
- [ ] FastAPI service layer (partial): `/health`, `/rag`, `/rag/index`, `/rag/query` implemented; `/chat` and `/memory` remain planned
316-
- [x] RAG MVP: Markdown / TXT / DOCX / PDF loading, chunking, local keyword retrieval, local vector prototype, hybrid retrieval, backend-vector retrieval, configurable embedding provider, optional Chroma adapter, citation context, source blocks, Streamlit retrieval panel, optional single-chat and WeChat interactive injection
316+
- [x] FastAPI service layer foundation: `/health`, `/chat`, `/memory/preview`, `/memory/commit`, `/sessions`, `/rag`, `/rag/index`, `/rag/query`, `/rag/status`, `/rag/upload` and `/rag/local-knowledge` implemented; streaming, auth and frontend-specific contracts remain planned
317+
- [x] RAG MVP: Markdown / TXT / DOCX / PDF loading, chunking, local keyword retrieval, local vector prototype, hybrid retrieval, backend-vector retrieval, configurable embedding provider, optional Chroma adapter, controlled local-knowledge retrieval, citation context, source blocks, Streamlit retrieval panel, optional single-chat and WeChat interactive injection
317318
- [ ] RAG document QA (partial): PDF parsing has file-size, page-count, extracted-text and encrypted-file guards; production embedding requires explicit API/env configuration and Chroma remains optional
318319
- [ ] Vector store: Chroma optional adapter implemented; FAISS local prototype and pgvector engineering version remain planned
319320
- [ ] Web UI: TypeScript + Vue3 / React, streaming chat, source panel

docs/INTERVIEW_NOTES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Study Agent 是一个本地优先的 AI 学习助手,重点在多 Provider 模
1010
2. **长期记忆写入安全** — safe writer + preview/confirm 机制,防止不可逆的记忆污染
1111
3. **联网搜索来源追溯** — Feed registry / RSS 多源聚合 → URL safety matrix → 文章正文三层提取 → LLM digest → pipeline trace 全过程来源可回溯
1212
4. **Streamlit 重渲染性能优化** — 多层缓存策略、按模式批量落盘、主链路 token 预算控制
13-
5. **CI / Ruff / detect-secrets 工程检查**277 pytest tests、Ruff clean、mypy local clean、GitHub Actions workflow、detect-secrets 对未豁免发现硬阻断
13+
5. **CI / Ruff / detect-secrets 工程检查**290 pytest tests、Ruff clean、mypy local clean、GitHub Actions workflow、detect-secrets 对未豁免发现硬阻断
1414

1515
## 可讲亮点
1616

docs/RAG.md

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,11 @@ Implemented:
1919
- Streamlit retrieval panel for uploads, local paths, indexing, querying and citation preview
2020
- Optional single-chat and WeChat interactive reply injection through the `用于聊天回答` toggle
2121
- UI source blocks for retrieved file paths, line ranges, scores and matched terms
22-
- FastAPI endpoints: `GET /health`, `POST /rag`, `POST /rag/index`, `POST /rag/query`
22+
- FastAPI endpoints: `GET /health`, `POST /rag`, `POST /rag/index`, `POST /rag/query`, `GET /rag/status`, `POST /rag/upload`, `POST /rag/local-knowledge`
2323
- Streamlit knowledge/debug panel with index summary, document rows, chunk preview and score breakdowns
2424
- Optional vector backend interface with local fallback and Chroma adapter
2525
- Configurable embedding providers: deterministic `local_hash` by default, OpenAI-compatible embeddings when explicitly configured
26+
- Controlled local-knowledge retrieval tool with intent gating, deterministic query rewrite and explicit not-found behavior
2627

2728
Not implemented yet:
2829

@@ -44,7 +45,8 @@ Not implemented yet:
4445
| `src/rag/eval.py` | LLM-free retrieval quality evaluation over gold query fixtures |
4546
| `src/rag/service.py` | Application-facing helpers for indexing, querying and context formatting |
4647
| `src/rag/schema.py` | Dataclasses for documents, chunks, indexes and search results |
47-
| `src/api.py` | FastAPI health and RAG endpoints |
48+
| `src/tools/local_knowledge.py` | Controlled retrieval boundary for agentic local knowledge use |
49+
| `src/api.py` | FastAPI health, chat, memory, session, RAG and local-knowledge endpoints |
4850

4951
## Data Flow
5052

@@ -56,7 +58,9 @@ local files
5658
-> save_rag_index
5759
-> query_documents
5860
-> build_rag_context
61+
-> optional controlled local-knowledge tool
5962
-> optional single-chat / WeChat interactive prompt injection or FastAPI response
63+
-> optional frontend-facing chat / memory / session API flow
6064
```
6165

6266
## Retrieval Behavior
@@ -111,8 +115,10 @@ Regression coverage lives in `tests/test_rag.py` and verifies:
111115
- Local hash-vector and hybrid retrieval behavior
112116
- Citation formatting and context budget behavior
113117
- Streamlit RAG panel helpers for uploaded filenames and local path parsing
114-
- FastAPI `/health`, `/rag`, `/rag/index` and `/rag/query`
118+
- FastAPI `/health`, `/rag`, `/rag/index`, `/rag/query`, `/rag/status`, `/rag/upload` and `/rag/local-knowledge`
119+
- FastAPI `/chat`, `/memory/preview`, `/memory/commit`, `/sessions` and `/sessions/{session_id}/flush`
115120
- Prompt injection behavior for cited RAG context
121+
- Controlled local-knowledge tool behavior for skip / found / not-found / rewrite
116122

117123
`tests/test_rag_eval.py` adds a small gold fixture suite under `tests/fixtures/rag_eval/` and verifies:
118124

@@ -182,7 +188,19 @@ Goal: turn the Streamlit expander into a usable knowledge panel.
182188

183189
Goal: let the model retrieve when it needs evidence instead of always pre-retrieving.
184190

185-
- Add a `retrieve_local_knowledge(query)` tool boundary.
186-
- Route retrieval only for knowledge-grounded questions.
187-
- Allow query rewrite and second-pass retrieval when first-pass evidence is weak.
188-
- Require explicit "not found in local knowledge" behavior when no source is retrieved.
191+
- [x] Add a `retrieve_local_knowledge(query)` tool boundary.
192+
- [x] Route retrieval only for knowledge-grounded questions through deterministic intent gating.
193+
- [x] Allow deterministic query rewrite and second-pass retrieval when first-pass evidence is weak.
194+
- [x] Require explicit "not found in local knowledge" behavior when no source is retrieved.
195+
- [x] Expose the same boundary through `POST /rag/local-knowledge` for future frontends.
196+
- [ ] Add LLM tool-calling / function-calling integration; current implementation is controlled pre-generation retrieval, not free-form tool use.
197+
198+
### P8: Service API Foundation
199+
200+
Goal: expose the current local-first capabilities through stable API boundaries before building a separate web frontend.
201+
202+
- [x] Add RAG status and upload endpoints for index inspection and rebuilds.
203+
- [x] Add a non-streaming `/chat` endpoint that reuses model routing, role prompts, memory bundles, local-knowledge retrieval and session logging.
204+
- [x] Add memory preview / commit endpoints with the same runtime write-mode guard as the Streamlit UI.
205+
- [x] Add session listing and force-flush endpoints for local session inspection.
206+
- [ ] Add streaming chat, auth, CORS policy and frontend-oriented error envelopes before public or LAN deployment.

docs/STUDY_AGENT_OPTIMIZATION_ROADMAP.md

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ Study Agent 后续的核心竞争力应该来自 RAG,而不是普通聊天。
286286

287287
不要让模型无限制自由调用工具,而是先用可控路由实现稳定 Agent 工作流。
288288

289-
## 9. P1:FastAPI 服务化
289+
## 9. P8:FastAPI 服务化
290290

291291
不建议立刻推翻 Streamlit。推荐三步走:
292292

@@ -298,7 +298,7 @@ Streamlit UI → core/chat_engine.py
298298

299299
### 阶段 2:增加 FastAPI
300300

301-
最小接口
301+
当前基础接口已经落地
302302

303303
```text
304304
GET /health
@@ -307,12 +307,21 @@ POST /memory/preview
307307
POST /memory/commit
308308
POST /rag/upload
309309
POST /rag/query
310+
GET /rag/status
311+
POST /rag/local-knowledge
310312
GET /sessions
313+
POST /sessions/{session_id}/flush
311314
```
312315

316+
仍需补齐:streaming chat、auth、CORS、统一错误响应、OpenAPI 示例和 Docker 部署配置。
317+
313318
### 阶段 3:补前端
314319

315-
前端可用 Vue3 或 React。推荐先 Vue3,开发成本较低。
320+
前端建议进入 P9 后使用 React + Vite + TypeScript。理由是:
321+
322+
- React 生态更适合后续做聊天流、引用面板、调试抽屉和状态组件拆分。
323+
- Vite 开发服务器启动快,生产构建输出静态 `dist`,可以独立部署,也可以由 FastAPI 挂载静态目录。
324+
- TypeScript 能把 API response、RAG source、memory preview、session row 等数据结构固定下来,减少前后端联调时的隐性字段漂移。
316325

317326
最低页面:
318327

@@ -368,7 +377,7 @@ GET /sessions
368377
| RAG 测试 | chunk、入库、检索、引用来源 |
369378
| Tool 测试 | 新闻检索、文件读取、摘要 |
370379
| ContextBuilder 测试 | 不同模式下上下文是否正确 |
371-
| API 测试 | /chat、/health、/rag/query |
380+
| API 测试 | /chat、/health、/rag/query、/rag/upload、/rag/status、/memory/preview、/memory/commit、/sessions |
372381
| UI smoke 测试 | 页面能打开、基本交互不崩 |
373382

374383
最关键的是 Mock Provider。真实模型用于演示和实际使用,Mock Provider 用于自动测试和 CI,避免测试依赖外部 API。
@@ -438,23 +447,23 @@ docs/
438447

439448
任务:
440449

441-
1. 增加 FastAPI
442-
2. 实现 /health
443-
3. 实现 /chat
444-
4. 实现 /rag/upload
445-
5. 实现 /rag/query
446-
6. 实现 /memory/preview
447-
7. 实现 /memory/commit
448-
8. 补 API 测试
449-
9. Docker Compose
450+
1. [x] 增加 FastAPI
451+
2. [x] 实现 /health
452+
3. [x] 实现 /chat(当前为非流式)
453+
4. [x] 实现 /rag/upload
454+
5. [x] 实现 /rag/query
455+
6. [x] 实现 /memory/preview
456+
7. [x] 实现 /memory/commit
457+
8. [x] 补 API 测试
458+
9. [ ] 补 streaming chat / auth / CORS / Docker Compose
450459

451460
### v1.0:前端产品化版本
452461

453462
目标:能演示、能截图、能部署、能写简历。
454463

455464
任务:
456465

457-
1. Vue3 / React 前端
466+
1. React + Vite + TypeScript 前端
458467
2. 聊天页
459468
3. 文件上传页
460469
4. 知识库列表页
@@ -479,28 +488,27 @@ docs/
479488

480489
## 15. 当前最建议执行的下一步
481490

482-
第一步先画清主流程并拆模块
491+
当前主流程已经可以按 FastAPI 边界继续收口
483492

484493
```text
485494
用户输入
486-
→ UI 接收
495+
→ Streamlit 或 Web UI 接收
496+
→ FastAPI /chat
487497
→ memory 读取
488498
→ context 构建
489-
→ tool 判断
499+
local knowledge tool 判断
490500
→ provider 调用
491-
stream 输出
501+
response 输出
492502
→ session 记录
493503
→ memory 写回确认
494504
```
495505

496-
推荐重构顺序:
497-
498-
1. Provider 抽象稳定
499-
2. MemoryManager 稳定
500-
3. ContextBuilder 稳定
501-
4. SessionLogger 批量写入
502-
5. ToolRouter 初步成型
503-
6. Streamlit 只保留 UI
504-
7. 再加 FastAPI
505-
8. 再加 RAG
506-
9. 最后做前端
506+
推荐推进顺序:
507+
508+
1. [x] Provider 抽象稳定
509+
2. [x] Memory / ContextBuilder 基础稳定
510+
3. [x] SessionLogger 批量写入
511+
4. [x] RAG MVP 与 local knowledge tool
512+
5. [x] FastAPI 基础服务层
513+
6. [ ] streaming chat / auth / CORS / Docker
514+
7. [ ] React + Vite + TypeScript 前端

0 commit comments

Comments
 (0)