BioPhys-Neural-Agent / src /dynamic_knowledge_rag.rs
minseok
๐ŸŒŒ Release BioPhys 6.0 Grand Master: 16GB (14.89GB) Gemma-4 100% Devour, Ecosystem Evolution, Solar MoE, SNN Autoregressive SDK, Dynamic PhaseVM
be99550
Raw
History Blame Contribute Delete
9.47 kB
// ๐ŸŒŒ [๋ธ”๋ž™ํ™€ ์‚ฌ๊ฑด์˜ ์ง€ํ‰์„  ํ™€๋กœ๊ทธ๋ž˜ํ”ฝ RAG] (src/dynamic_knowledge_rag.rs)
// ์ด๋ก  ๊ธฐ๋ฐ˜: ๋ฒ ์ผ„์Šˆํƒ€์ธ-ํ˜ธํ‚น ์ •๋ณด ํ•œ๊ณ„(Bekenstein Bound) & 't Hooft-Susskind ํ™€๋กœ๊ทธ๋ž˜ํ”ฝ ์›๋ฆฌ
use std::fs::{self, File, OpenOptions};
use std::io::{BufRead, BufReader, Write};
use std::path::Path;
#[derive(Clone, Debug)]
pub struct DynamicDocument {
pub id: usize,
pub title: String,
pub category: String,
pub content: String,
pub horizon_x: u8, // 256x256 ์‚ฌ๊ฑด์˜ ์ง€ํ‰์„  2D X ์ขŒํ‘œ
pub horizon_y: u8, // 256x256 ์‚ฌ๊ฑด์˜ ์ง€ํ‰์„  2D Y ์ขŒํ‘œ
pub hawking_mass: f32, // ์ค‘๋ ฅ ํฌํ…์…œ ์งˆ๋Ÿ‰ (์ •๋ณด ๋ฐ€๋„)
pub keywords: Vec<String>,
}
pub struct DynamicKnowledgeRAG {
pub documents: Vec<DynamicDocument>,
pub corpus_dir: String,
pub horizon_grid: [[f32; 256]; 256], // 2D ์‚ฌ๊ฑด์˜ ์ง€ํ‰์„  ์ค‘๋ ฅ ๊ณก๋ฅ  ํ…์„œ
}
impl DynamicKnowledgeRAG {
pub fn new(corpus_dir: &str) -> Self {
let mut rag = DynamicKnowledgeRAG {
documents: Vec::new(),
corpus_dir: corpus_dir.to_string(),
horizon_grid: [[0.0; 256]; 256],
};
if !Path::new(corpus_dir).exists() {
let _ = fs::create_dir_all(corpus_dir);
}
rag.initialize_default_corpus();
rag.reload_all_documents();
rag
}
fn initialize_default_corpus(&self) {
let sample_file = format!("{}/world_knowledge_2026.jsonl", self.corpus_dir);
if !Path::new(&sample_file).exists() {
if let Ok(mut f) = File::create(&sample_file) {
let initial_data = r#"{"id":1,"category":"์ตœ์‹ IT","title":"2026 ์ฐจ์„ธ๋Œ€ ์–‘์ž-๊ด‘ํ•™ AI ๊ฐ€์†๊ธฐ QuantumX-9000","content":"QuantumX-9000์€ 2026๋…„ ์ถœ์‹œ๋œ ์„ธ๊ณ„ ์ตœ์ดˆ์˜ ์ƒ์˜จ ์‹ค๋ฆฌ์ฝ˜ ํฌํ† ๋‹‰์Šค ๊ธฐ๋ฐ˜ ์–‘์ž ๊ฐ„์„ญ ๊ฐ€์†๊ธฐ๋กœ, ํ…Œ๋ผํ”Œ๋กญ์Šค๋‹น 0.05W์˜ ๊ทน์ €์ „๋ ฅ์„ ์†Œ๋ชจํ•˜๋ฉฐ 1.58๋น„ํŠธ ์—ฐ์‚ฐ ์ „์šฉ ๊ด‘ํ•™ ํ…์„œ ์ฝ”์–ด๋ฅผ ๋‚ด์žฅํ•จ."}
{"id":2,"category":"์šฐ์ฃผํƒ์‚ฌ","title":"2026 ์•„๋ฅดํ…Œ๋ฏธ์Šค 3ํ˜ธ ์œ ์ธ ๋‹ฌ ์ฐฉ๋ฅ™ ๋ฐ ์˜๊ตฌ ๊ธฐ์ง€ ๊ฑด์„ค","content":"2026๋…„ ์ธ๋ฅ˜๋Š” 50์—ฌ ๋…„ ๋งŒ์— ๋‹ฌ ๋‚จ๊ทน ์—์ด์ปจ ๋ถ„์ง€์— ์œ ์ธ ์ฐฉ๋ฅ™ํ•˜์—ฌ ์–ผ์Œ ์ˆ˜์ž์›์„ ์ฑ„๊ตดํ•˜๊ณ  ์˜๊ตฌ์ ์ธ ์œ ์ธ ์—ฐ๊ตฌ ๊ธฐ์ง€ ์•„๋ฅดํ…Œ๋ฏธ์Šค ๋ฒ ์ด์Šค์บ ํ”„๋ฅผ ๊ณต์‹ ๊ฐ€๋™ํ•จ."}
{"id":3,"category":"์ƒ๋ช…๊ณตํ•™","title":"2026 ๋‚˜๋…ธ๋กœ๋ด‡ ๊ธฐ๋ฐ˜ ํ‘œ์  ์•”์„ธํฌ ์ง์ ‘ ์ œ๊ฑฐ ์ž„์ƒ ์„ฑ๊ณต","content":"2026๋…„ ํ˜ˆ๊ด€์„ ํƒ€๊ณ  ์ด๋™ํ•˜๋ฉฐ ํŠน์ • ์•”์„ธํฌ ํ‘œ๋ฉด ํ•ญ์›๋งŒ์„ ๊ฐ์ง€ํ•ด ์ •ํ™•ํžˆ ํŒŒ๊ดดํ•˜๋Š” ์ž์œจ ์œ ๋„ DNA ์˜ค๋ฆฌ๊ฐ€๋ฏธ ๋‚˜๋…ธ๋กœ๋ด‡์˜ 3์ƒ ์ž„์ƒ ์‹œํ—˜์ด ์„ธ๊ณ„ ์ตœ์ดˆ๋กœ ์Šน์ธ๋จ."}
"#;
let _ = f.write_all(initial_data.as_bytes());
}
}
}
pub fn reload_all_documents(&mut self) {
self.documents.clear();
self.horizon_grid = [[0.0; 256]; 256];
if let Ok(entries) = fs::read_dir(&self.corpus_dir) {
for entry in entries.flatten() {
let path = entry.path();
if path.extension().and_then(|s| s.to_str()) == Some("jsonl") {
if let Ok(file) = File::open(&path) {
let reader = BufReader::new(file);
for line in reader.lines().flatten() {
if line.trim().is_empty() { continue; }
if let Some(mut doc) = self.parse_jsonl_line(&line) {
// ํ™€๋กœ๊ทธ๋ž˜ํ”ฝ ์‚ฌ๊ฑด์˜ ์ง€ํ‰์„  2D ์ขŒํ‘œ ํˆฌ์˜
let (hx, hy, mass) = Self::compute_holographic_projection(&doc.title, &doc.content);
doc.horizon_x = hx;
doc.horizon_y = hy;
doc.hawking_mass = mass;
self.horizon_grid[hy as usize][hx as usize] += mass;
self.documents.push(doc);
}
}
}
}
}
}
}
/// [ํ™€๋กœ๊ทธ๋ž˜ํ”ฝ ํˆฌ์˜]: ๊ณ ์ฐจ์› ํ…์ŠคํŠธ๋ฅผ 2D ์ง€ํ‰์„  256x256 ์ขŒํ‘œ์™€ ํ˜ธํ‚น ์ค‘๋ ฅ ๊ณก๋ฅ ๋กœ ํˆฌ์˜
fn compute_holographic_projection(title: &str, content: &str) -> (u8, u8, f32) {
let mut hx: u32 = 0;
let mut hy: u32 = 0;
for (i, b) in title.bytes().enumerate() {
hx = (hx * 31 + b as u32 + i as u32) % 256;
}
for (i, b) in content.bytes().enumerate() {
hy = (hy * 37 + b as u32 + (i * 7) as u32) % 256;
}
let mass = (content.len() as f32).ln().max(1.0);
(hx as u8, hy as u8, mass)
}
fn parse_jsonl_line(&self, line: &str) -> Option<DynamicDocument> {
let get_val = |key: &str| -> String {
if let Some(pos) = line.find(&format!("\"{}\":", key)) {
let rest = &line[pos + key.len() + 3..];
if rest.starts_with('"') {
if let Some(end) = rest[1..].find('"') {
return rest[1..1 + end].to_string();
}
} else if let Some(end) = rest.find(|c: char| c == ',' || c == '}') {
return rest[..end].trim().to_string();
}
}
String::new()
};
let title = get_val("title");
let category = get_val("category");
let content = get_val("content");
let id_str = get_val("id");
let id = id_str.parse::<usize>().unwrap_or(self.documents.len() + 1);
if !title.is_empty() && !content.is_empty() {
let mut keywords = Vec::new();
for word in content.split_whitespace().chain(title.split_whitespace()) {
let clean: String = word.chars().filter(|c| c.is_alphanumeric()).collect();
if clean.len() >= 2 {
keywords.push(clean.to_lowercase());
}
}
Some(DynamicDocument { id, title, category, content, horizon_x: 0, horizon_y: 0, hawking_mass: 1.0, keywords })
} else {
None
}
}
/// [์‹ค์‹œ๊ฐ„ ์ง€์‹ ์ฃผ์ž…]: ์‚ฌ๊ฑด์˜ ์ง€ํ‰์„ ์— ์ฆ‰์‹œ ๋ธ”๋ž™ํ™€ ์ค‘๋ ฅ ์šฐ๋ฌผ ํ˜•์„ฑ
pub fn ingest_new_knowledge(&mut self, category: &str, title: &str, content: &str) {
let doc_id = self.documents.len() + 1;
let (hx, hy, mass) = Self::compute_holographic_projection(title, content);
let mut keywords = Vec::new();
for word in content.split_whitespace().chain(title.split_whitespace()) {
let clean: String = word.chars().filter(|c| c.is_alphanumeric()).collect();
if clean.len() >= 2 {
keywords.push(clean.to_lowercase());
}
}
let doc = DynamicDocument {
id: doc_id,
title: title.to_string(),
category: category.to_string(),
content: content.to_string(),
horizon_x: hx,
horizon_y: hy,
hawking_mass: mass,
keywords,
};
self.horizon_grid[hy as usize][hx as usize] += mass;
self.documents.push(doc.clone());
let sample_file = format!("{}/world_knowledge_2026.jsonl", self.corpus_dir);
if let Ok(mut f) = OpenOptions::new().create(true).append(true).open(&sample_file) {
let line = format!("{{\"id\":{},\"category\":\"{}\",\"title\":\"{}\",\"content\":\"{}\"}}\n", doc_id, category, title, content);
let _ = f.write_all(line.as_bytes());
}
}
/// [๋ธ”๋ž™ํ™€ ์ค‘๋ ฅ ํฌํ…์…œ ์ธก์ง€์„  ๊ฒ€์ƒ‰ (Holographic Geodesic RAG)]:
/// ์งˆ์˜๊ฐ€ ์‹œ๊ณต๊ฐ„ ์ง€ํ‰์„ ์— ๋˜์ ธ์กŒ์„ ๋•Œ, ๊ฐ€์žฅ ๊ฐ•ํ•œ ์ค‘๋ ฅ ์šฐ๋ฌผ(Singularity Well)๋กœ ๋นจ๋ ค ๋“ค์–ด๊ฐ€๋Š” ๋ฌธ์„œ๋ฅผ ์ฆ‰์‹œ ์ธ์ถœ!
pub fn search_documents(&self, query: &str, top_k: usize) -> Vec<(&DynamicDocument, f32)> {
let (qx, qy, _qmass) = Self::compute_holographic_projection(query, query);
let query_lower = query.to_lowercase();
let query_words: Vec<String> = query_lower
.split_whitespace()
.map(|w| w.chars().filter(|c| c.is_alphanumeric()).collect())
.filter(|w: &String| w.len() >= 2)
.collect();
let mut scored: Vec<(&DynamicDocument, f32)> = self.documents.iter().map(|doc| {
// 1. ์‚ฌ๊ฑด์˜ ์ง€ํ‰์„  2D ๊ณต๊ฐ„ ๊ฑฐ๋ฆฌ (์ธก์ง€์„  ์ธ๋ ฅ)
let dx = (doc.horizon_x as f32 - qx as f32).abs();
let dy = (doc.horizon_y as f32 - qy as f32).abs();
let dist_sq = dx * dx + dy * dy + 1.0;
let gravitational_pull = (doc.hawking_mass * 100.0) / dist_sq;
// 2. ์˜๋ฏธ๋ก ์  ํ‚ค์›Œ๋“œ ๊ณต๋ช…
let mut semantic_score: f32 = 0.0;
if doc.title.to_lowercase().contains(&query_lower) {
semantic_score += 20.0;
}
for qw in &query_words {
if doc.title.to_lowercase().contains(qw) {
semantic_score += 10.0;
}
if doc.content.to_lowercase().contains(qw) {
semantic_score += 5.0;
}
}
let total_score = gravitational_pull * 0.3 + semantic_score * 0.7;
(doc, total_score)
}).filter(|(_, score)| *score > 0.0).collect();
scored.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
scored.truncate(top_k);
scored
}
}