Ir al contenido
Nibiru docsv0.9.2

El módulo de IA

Primera clase de IA en Nibiru — chat, embeddings, RAG, agentes — conectados a tu propio Ollama en su Ollama. No se requieren APIs pagas.

Stable Reading time ~ 4 min Edit on GitHub

Nibiru incluye un módulo de IA (application/module/ai/) que da a cada aplicación Nibiru una interfaz de IA de primera clase. El código PHP puede chatear con un LLM local, incrustar texto, ejecutar RAG sobre sus propios datos o ejecutar un agente con herramientas — todo sin enviar un solo byte a una API pagada.

El módulo está conectado a su propio Ollama en su Ollama por defecto, por lo que la inferencia se realiza en su hardware, en su red y bajo sus términos.

Plugin¿Qué hace?Una línea
ChatCompletaciones de chat, una o múltiples vueltas$ai->chat()->ask('…')
EmbedTexto → vectores + ayudantes de coseno$ai->embed()->one('…')
RagIngesta + recuperación + chat basado en el contexto$ai->rag('docs')->ask('…')
AgentBucle ReAct con herramientas$ai->agent()->withTools([…])->run('…')
ToolBase para tus propias herramientas personalizadasclass MyTool extends Tool { … }
OllamaTransporte HTTP sin procesar a cualquier punto final compatible con Ollama(new Ollama($cfg))->chat(…)
use Nibiru\Module\Ai\Ai;
$ai = new Ai();
echo $ai->chat()->ask('How do I scaffold a new module?');
// → "Run `./nibiru -m <name>`. This creates application/module/<name>/ with…"

Esa es toda la superficie de la API para el caso simple. Sin contenedor de inyección de dependencias, sin claves de API, sin instalación del SDK.

Cada complemento lee sus configuraciones desde application/module/ai/settings/ai.ini:

[AI]
ollama.base_url = "https://your-ollama-host.example"
chat.model = "nibiru-coder:1.0"
chat.fallback_model = "qwen2.5-coder:14b"
chat.temperature = 0.4
chat.max_tokens = 1024
embed.model = "nomic-embed-text"
rag.top_k = 6
agent.max_iterations = 6

Sobrescritura por entorno: ai.production.ini, ai.staging.ini. El Registro de Nibiru los descubre automáticamente.

$ai = new \Nibiru\Module\Ai\Ai();
// One-shot
echo $ai->chat()->ask('Explain MMVC in two sentences.');
// Multi-turn
$chat = $ai->chat();
$chat->user('How do I scaffold a module?');
$chat->user('And add Graylog hooks?'); / referrs to previous turn
echo $chat->complete();
// Override per call
echo $ai->chat()
->system('Answer in German.')
->model('qwen2.5-coder:14b')
->temperature(0.1)
->ask('Was ist ein Modul?');

El complemento Chat se cae automáticamente en chat.fallback_model si el modelo principal no está disponible — útil mientras sigues construyendo nibiru-coder.

$embed = $ai->embed();
$va = $embed->one('controller');
$vb = $embed->one('module');
$score = \Nibiru\Module\Ai\Plugin\Embed::cosine($va, $vb);
// → 0.78 (close concepts)

Almacenamiento compacto:

$packed = \Nibiru\Module\Ai\Plugin\Embed::pack($vec); / base64 string, 4 bytes/dim
$vec = \Nibiru\Module\Ai\Plugin\Embed::unpack($packed);
$rag = $ai->rag('product-help');
// One-time ingestion
$rag->ingestDir(__DIR__ . '/help/'); / walks .md/.txt/.php
$rag->ingestText('FAQ entry…', ['source' => 'faq-12']);
$rag->ingestFile('/var/data/manual.pdf.txt');
// Then ask grounded questions
echo $rag->ask('How do I cancel my subscription?');
// → "Per the help docs, you can cancel in account → settings… [1]"

Almacenamiento: un archivo JSON por colección en application/module/ai/cache/rag/<nombre>.json. Reanudable, sin base de datos, se ajusta cómodamente a unos 10k fragmentos en memoria.

use Nibiru\Module\Ai\Plugin\Tools;
$ai = new \Nibiru\Module\Ai\Ai();
$agent = $ai->agent()->withTools([
new Tools\PdoQuery(), / read-only SQL
new Tools\HttpGet(), / fetch URLs
new Tools\FileRead(), / read project files
]);
echo $agent->run('How many active users registered last week?');
// → agent decides to call pdo_query with SELECT count(*) FROM users…
// reads observation, writes a final answer.

El agente utiliza un bucle estilo ReAct: leer tarea → elegir herramienta → ejecutar → observar → repetir → respuesta final. El protocolo usa un simple \“tool {…}```` sentinel JSON que funciona en todos los modelos de Ollama — no se requieren APIs específicas de llamada a herramientas por modelo.

application/module/ai/
├── ai.php # main class implementing IModule
├── interfaces/ai.php # contract
├── traits/ai.php # cfg() helper
├── plugins/
│ ├── ollama.php # raw transport
│ ├── chat.php # chat completions
│ ├── embed.php # embeddings + cosine + pack
│ ├── rag.php # ingest + retrieve + grounded chat
│ ├── agent.php # ReAct tool loop
│ ├── tool.php # abstract base for custom tools
│ └── tools/
│ ├── pdoQuery.php # read-only SQL
│ ├── httpGet.php # HTTP GET
│ └── fileRead.php # project-local file read
├── settings/ai.ini # config
├── cache/rag/ # RAG vector index files (gitignored)
└── training/
├── Modelfile # the nibiru-coder system prompt
├── build.sh # one-command Modelfile → registered model
├── smoke-test.php # verify the whole stack
└── README.md # training pipeline guide

PHP no tiene un “marco de IA” establecido como lo tienen Python con LangChain o JS con Vercel AI SDK. El módulo de IA de Nibiru llena ese vacío con la API más pequeña y afilada que pudimos escribir — tres capas (transporte → complemento → módulo), sin gráfica DI, sin instalación de SDK, sin facturación por token.

La filosofía de diseño:

  • Trae tu propio cerebro. Ollama por defecto, Anthropic y OpenAI como opciones de reemplazo. Cambia proveedores a través de INI, nunca a través de código.
  • Un archivo JSON por colección RAG. Sin base de datos vectorial. Seguro para reinicios. Grepable cuando estés depurando.
  • Las herramientas son clases PHP. Extiende Tool, obtén un nombre + esquema + método execute. El agente se encarga del resto.
  • No hay APIs específicas de llamada a herramientas por modelo. Una sola convención de JSON con marcas funciona en todas partes.