Архитектура распределенной системы памяти
В условиях ограниченных ресурсов (1 ГБ ОЗУ на Сервере 2 и отсутствие Docker) была разработана легковесная архитектура для распределенной системы памяти, где каждый сервер выполняет свою роль в обработке и хранении информации.
Сервер 1 (Kohana)
Хранит "твердые" факты в MySQL
Сервер 2 (Ubuntu)
Координатор памяти и хранилище векторов
Сервер 3 (LM Studio)
Генератор эмбеддингов
Архитектура потока данных
Сервер 1 (Kohana)
Отправляет текст на Сервер 2
Сервер 2 (Ubuntu)
Пересылает текст на Сервер 3 для получения вектора
Сервер 3 (LM Studio)
Возвращает вектор V
Сервер 2 (Ubuntu)
Сохраняет вектор в FAISS и возвращает результат на Сервер 1
Настройка Сервера 2 (Ubuntu)
Подготовка окружения
sudo apt update
sudo apt install python3-pip python3-venv -y
mkdir agent_memory && cd agent_memory
python3 -m venv venv
source venv/bin/activate
# Устанавливаем только необходимое
pip install fastapi uvicorn requests faiss-cpu numpy
Python-сервис "Коллективной Памяти"
import os
import requests
import numpy as np
import faiss
import json
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
# Конфигурация
LM_STUDIO_URL = "http://<SERVER_3_IP>:1234/v1/embeddings"
DIMENSION = 384 # Зависит от модели в LM Studio (например, all-MiniLM-L6-v2)
INDEX_FILE = "collective.index"
METADATA_FILE = "metadata.json"
# Инициализация FAISS индекса
if os.path.exists(INDEX_FILE):
index = faiss.read_index(INDEX_FILE)
with open(METADATA_FILE, 'r') as f:
metadata = json.load(f)
else:
index = faiss.IndexFlatL2(DIMENSION)
metadata = []
def get_embedding(text):
response = requests.post(LM_STUDIO_URL, json={
"input": text,
"model": "model-identifier"
})
return response.json()['data'][0]['embedding']
@app.post("/add")
async def add_memory(text: str, source_id: str):
vector = np.array([get_embedding(text)]).astype('float32')
index.add(vector)
metadata.append({"text": text, "source_id": source_id})
# Сохраняем состояние на диск
faiss.write_index(index, INDEX_FILE)
with open(METADATA_FILE, 'w') as f:
json.dump(metadata, f)
return {"status": "ok"}
@app.post("/search")
async def search_memory(text: str, top_k: int = 3):
vector = np.array([get_embedding(text)]).astype('float32')
distances, indices = index.search(vector, top_k)
results = []
for i, idx in enumerate(indices[0]):
if idx != -1:
results.append({
"content": metadata[idx],
"distance": float(distances[0][i])
})
return results
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
Математическое обоснование
Проекция
Трансформация текста в точку в многомерном пространстве f: Text → ℝn через LM Studio
Поиск близости
Расчет Евклидова расстояния на Сервере 2: d(q, v) = √∑(qi - vi)2
Оптимизация
Использование IndexFlatL2 в FAISS на Сервере 2 идеально подходит для 1 ГБ ОЗУ, так как оно работает чрезвычайно быстро и не требует фоновых процессов БД.
Интеграция с Сервером 1 (Kohana)
Пример контроллера синхронизации памяти
class Controller_Memory extends Controller {
public function action_sync()
{
$id = $this->request->query('id'); // ID записи из MySQL
$post = ORM::factory('Post', $id);
if ($post->loaded()) {
$client = Request::factory('http://<SERVER_2_IP>:8000/add')
->method(HTTP_Request::POST)
->headers('Content-Type', 'application/json')
->body(json_encode([
'text' => $post->content,
'source_id' => 'mysql_post_' . $post->id
]));
$response = $client->execute();
$this->response->body("Memory stored: " . $response->body());
}
}
public function action_ask()
{
$question = $this->request->query('q');
$client = Request::factory('http://<SERVER_2_IP>:8000/search')
->method(HTTP_Request::POST)
->body(json_encode(['text' => $question]));
$results = json_decode($client->execute()->body(), TRUE);
// Теперь у нас есть данные из "Коллективного Разума"
echo View::factory('memory/results', ['results' => $results]);
}
}
Оптимизация для 1 GB RAM
- Создайте swap-файл на 2ГБ
- Запускайте через gunicorn с 1 воркером
- Используйте модель с меньшей размерностью эмбеддинга (например, 384 вместо 1536)
Итог системы
MySQL (S1)
Хранит "твердые" факты
FAISS (S2)
Хранит "ассоциации" (вектора)
LM Studio (S3)
Выступает в роли "таламуса"
Агенты могут находиться где угодно, делая запросы к S2, получая в ответ опыт всей системы