Spaces:
Sleeping
Sleeping
| """ | |
| 5 LangChain tools ánh xạ trực tiếp với các lệnh trong test_db.py. | |
| section_prereqs(section_id) ← test_db.py prereq <section_id> | |
| concepts_needed_for_section(id) ← test_db.py concepts <section_id> | |
| concept_prereqs(concept_name) ← test_db.py cprerq <concept_name> | |
| concept_children(concept_name) ← test_db.py children <concept_name> | |
| search_knowledge_graph(keyword) ← test_db.py find <keyword> | |
| Tất cả trả về JSON string. Definitions vẫn còn trong payload; | |
| masker_node sẽ strip/replace trước khi response_node dùng. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| from langchain_core.tools import tool | |
| from src.graph_db.client import GraphClient | |
| def _db() -> GraphClient: | |
| return GraphClient.get() | |
| def _json(obj) -> str: | |
| return json.dumps(obj, ensure_ascii=False, default=str) | |
| # ───────────────────────────────────────────────────────────────────────────── | |
| def chapter_info(chapter_id: str) -> str: | |
| """ | |
| Trả về thông tin của một chapter: tiêu đề, trang bắt đầu, part, | |
| và danh sách tất cả các section (tiêu đề + số trang) trong chapter đó. | |
| Dùng khi người dùng hỏi: | |
| - "Chương 2 bắt đầu từ trang nào?" | |
| - "Chương 3 gồm những phần nào?" | |
| - "Tiêu đề chương 2 là gì?" | |
| - "Chương 2 có mấy section?" | |
| Input: chapter ID (chỉ số), ví dụ "2", "3", "4" | |
| """ | |
| data = _db().chapter_info(chapter_id) | |
| if data is None: | |
| return _json({"error": f"Chapter '{chapter_id}' not found in knowledge graph."}) | |
| return _json({"chapter": data}) | |
| def section_info(section_id: str) -> str: | |
| """ | |
| Trả về thông tin cơ bản của một section: tiêu đề, số trang, chapter, part. | |
| Dùng khi người dùng hỏi: | |
| - "Section 3.3 ở trang nào?" | |
| - "Phần 3.3 nằm ở đâu trong sách?" | |
| - "Tên của section 2.4 là gì?" | |
| - "Chương nào chứa section 4.1?" | |
| Input: section ID, ví dụ "3.3", "2.4", "4.1" | |
| """ | |
| data = _db().section_info(section_id) | |
| if data is None: | |
| return _json({"error": f"Section '{section_id}' not found in knowledge graph."}) | |
| return _json({"section": data}) | |
| def section_prereqs(section_id: str) -> str: | |
| """ | |
| Trả về danh sách các section cần đọc TRƯỚC khi đọc section_id. | |
| Duyệt theo quan hệ REQUIRES (có transitivity tối đa 10 hop). | |
| Dùng khi người dùng hỏi: | |
| - "Đọc section 3.2 cần đọc gì trước?" | |
| - "Trước khi học chương 3.5 cần học những section nào?" | |
| - "Prerequisites của section 1.4 là gì?" | |
| Input: section ID, ví dụ "3.2", "1.4", "3.5" | |
| """ | |
| rows = _db().section_prereqs(section_id) | |
| return _json({"section_id": section_id, "prereq_sections": rows}) | |
| def concepts_needed_for_section(section_id: str) -> str: | |
| """ | |
| Trả về danh sách các concept cần biết TRƯỚC khi đọc section_id. | |
| Lấy từ CONCEPT_REQUIRES của các concept định nghĩa trong section đó, | |
| loại bỏ duplicate và loại bỏ concept thuộc chính section đó. | |
| Dùng khi người dùng hỏi: | |
| - "Cần biết khái niệm gì trước khi học section 3.3?" | |
| - "Để hiểu section 2.5 cần nắm những concept nào?" | |
| - "Vocabulary cần ôn trước khi đọc chương 3?" | |
| Input: section ID, ví dụ "3.3", "2.5" | |
| """ | |
| rows = _db().concepts_needed_for(section_id) | |
| return _json({"section_id": section_id, "concepts_needed": rows}) | |
| def concept_prereqs(concept_name: str) -> str: | |
| """ | |
| Trả về danh sách các concept cần hiểu TRƯỚC khi học concept_name. | |
| Duyệt theo quan hệ CONCEPT_REQUIRES (transitivity tối đa 10 hop), | |
| kèm depth (số bước) và section định nghĩa. | |
| Dùng khi người dùng hỏi: | |
| - "Để hiểu tu quoque cần biết gì trước?" | |
| - "Cần nắm những khái niệm nào trước khi học hasty generalization?" | |
| - "Prerequisites của concept ad hominem là gì?" | |
| Input: tên concept bằng tiếng Anh (chữ thường), ví dụ "tu quoque", | |
| "hasty generalization", "cogent argument" | |
| """ | |
| rows = _db().concept_prereqs(concept_name) | |
| return _json({"concept": concept_name, "prereq_concepts": rows}) | |
| def concept_children(concept_name: str) -> str: | |
| """ | |
| Trả về các khái niệm con (subtypes) của concept_name theo quan hệ IS_TYPE_OF. | |
| Dùng để khám phá taxonomy của một khái niệm lớn. | |
| Dùng khi người dùng hỏi: | |
| - "Fallacy gồm những loại nào?" | |
| - "Fallacy of relevance bao gồm những fallacy nào?" | |
| - "Inductive argument có những dạng nào?" | |
| - "Liệt kê các loại definition" | |
| Input: tên concept cha, ví dụ "fallacy", "informal fallacy", | |
| "fallacy of relevance", "deductive argument" | |
| """ | |
| rows = _db().concept_subtypes(concept_name) | |
| return _json({"concept": concept_name, "subtypes": rows}) | |
| def search_knowledge_graph(keyword: str) -> str: | |
| """ | |
| Tìm kiếm full-text trong knowledge graph theo từ khóa. | |
| Trả về tối đa 8 concept khớp với keyword (tên hoặc định nghĩa), | |
| kèm số trang và section định nghĩa. | |
| Dùng khi người dùng hỏi: | |
| - "Tìm kiếm 'sufficient condition' trong sách" | |
| - "Có concept nào liên quan đến 'circular' không?" | |
| - "Tìm tất cả khái niệm liên quan đến 'analogy'" | |
| - Hoặc khi không chắc tên chính xác của một concept | |
| Input: từ khóa tiếng Anh, ví dụ "sufficient", "circular", "analogy" | |
| """ | |
| rows = _db().search_concepts(keyword) | |
| return _json({"keyword": keyword, "results": rows}) | |
| # Danh sách để import vào nodes.py | |
| ALL_GRAPH_TOOLS = [ | |
| chapter_info, | |
| section_info, | |
| section_prereqs, | |
| concepts_needed_for_section, | |
| concept_prereqs, | |
| concept_children, | |
| search_knowledge_graph, | |
| ] | |