appcore-ai
appcore-ai 0.1.0-beta.4 está publicado no crates.io. A API pode mudar durante
a beta, e o docs.rs pode levar algum tempo para concluir o build de uma nova
release. Ela não adiciona campos aos manifests V1 estáveis.
appcore-ai é o core de execução de IA limitado e independente de backend. Ele
escolhe uma rota a partir de modelos, backends, devices, recursos e policy de
privacidade explícitos. A aplicação continua dona dos prompts, validação de
domínio e decisão de aplicar qualquer resultado gerado.
O que está implementado
| Área | Comportamento atual |
|---|---|
| API central | requests/responses tipados, texto/chat/imagem/documento, qualidade e privacidade |
| Caminho rápido | transformações e regras lightweight determinísticas, sem ML |
| Routing | custo local/remoto, escalation limitada e load single-flight por modelo/backend |
| Recursos | snapshots nativos CPU/RAM, topologia unificada/dedicada, admission por device exato, sampling single-flight, batching e residency |
| Artifacts | tamanho + SHA-256, cache atômico no-follow/revalidado, provenance e ranges verificados |
| Generativo | chat com papéis, sampling, tool calls recuperáveis, JSON Schema, contratos de streaming e data URLs de imagem opt-in |
| ML local | Candle CPU e training para o classificador data-only NativeLinearV1 |
| Operação | cancelamento, deadlines, health e telemetria sem payload |
| Distribuído | contratos Swarm experimentais; sem claim de adapter Peer RPC de produção |
O build default não inclui framework de ML nem adapter HTTP.
A normalização lightweight de whitespace Unicode escreve direto em sua
String de saída limitada, sem reter uma lista intermediária de palavras.
A ativação do cache local também é limitada em memória quando o artefato já existe. Stores idempotentes e corridas entre writers abrem o arquivo regular sem seguir links, verificam o tamanho exato, comparam e calculam SHA-256 incrementalmente com um buffer fixo de 16 KiB. O artefato completo owned pelo caller não é duplicado.
O classificador Candle opcional move labels, pesos e biases decodificados ao
estado carregado sem clonar os buffers completos. CandleBackend reserva
atomicamente um slot e os bytes declarados antes de acessar o store.
new_with_loaded_byte_limit seleciona um teto agregado menor e
memory_pressure() informa uso atual/de pico e loads rejeitados. Uma inferência
ativa mantém a reserva depois de unload até liberar seu lease dos tensors.
Candle não possui KV cache generativo; a engine generativa externa escolhida
deve limitar seu próprio cache.
Backends e modelos aceitos
| Feature | Engine/formato | Escopo real |
|---|---|---|
| nenhuma | resolver lightweight | normalização, matching, extração e regras |
accelerator-nvidia | NVIDIA NVML | descoberta read-only opcional de VRAM/utilização no Linux/Windows; sem instalar/controlar driver |
backend-candle | NativeLinearV1 | classificação CPU in-process |
training-candle | NativeLinearV1 | SGD reprodutível, checkpoint e resume |
backend-openai-compatible | llama.cpp, MLX-LM, vLLM, SGLang, TensorRT-LLM, OpenVINO, TabbyAPI, generic | chat-completions limitado; SSE nativo exige implementação de transporte streaming |
swarm | bridge fornecida pelo host | contrato autenticado experimental |
O adapter OpenAI-compatible reconhece GGUF para llama.cpp, ONNX para OpenVINO e SafeTensors para os demais profiles. Quem interpreta e executa esses formatos é o servidor externo. Registrar um formato nunca instala engine nem baixa modelo silenciosamente.
Rodar um LLM local
Inicie o servidor compatível separadamente. Exemplo de listener loopback do llama.cpp:
llama-server -m /caminho/absoluto/modelo.gguf --host 127.0.0.1 --port 8080
Depois execute o exemplo real com a identidade exata do artifact:
APPCORE_AI_ENGINE=llama.cpp \
APPCORE_AI_FORMAT=gguf \
APPCORE_AI_BASE_URL=http://127.0.0.1:8080 \
APPCORE_AI_MODEL=nome-exato-no-servidor \
APPCORE_AI_MODEL_SHA256=<digest-hex-de-64-caracteres> \
APPCORE_AI_MODEL_BYTES=<tamanho-exato-do-arquivo> \
cargo run -p appcore-ai --example openai_compatible \
--features backend-openai-compatible
Valores aceitos para engine: llama.cpp, mlx-lm, vllm, sglang,
tensorrt-llm, openvino, tabbyapi e generic. Cada config liga um
ModelId AppCore ao nome exato entendido pelo servidor. Tools, visão, seed e
stop ficam desabilitados até o deployment exato declarar suporte.
OpenAiCompatibleConfig::local rejeita endpoints fora de loopback. Um
deployment remoto usa OpenAiCompatibleConfig::remote e transporte customizado
apoiado por referências de segredo e policy AppCore. O transporte default
rejeita credenciais.
Mudanças OpenAI-compatible na beta.2
- respostas não-2xx preservam o status HTTP exato e o delta limitado de
Retry-After; o routing só repete falhas transitórias; - argumentos malformados de tool call permanecem disponíveis como JSON bruto, junto com finish reason, uso e contagem de argumentos inválidos;
- a SPI de transporte retorna futures, enquanto o HTTP bloqueante incluído usa um gate de workers limitado em vez de bloquear o executor assíncrono;
- profiles explícitos podem omitir sampling, escolher o campo de limite de tokens e acrescentar parâmetros de provider limitados e não reservados;
- output estruturado por JSON Schema usa
response_formatnativo ou fallback textual JSON explícito e limitado; resolve_streamoferece cancelamento cooperativo e backpressure pelo sink. SSE nativo só é habilitado quando deployment e transporte customizado declaram e implementam streaming. Depois de emitir um evento, uma falha transitória é retornada sem misturar output de uma rota fallback.
O decoder limitado analisa frames SSE completos e coalescidos diretamente dos
chunks emprestados pelo transporte. Ele retém somente uma cauda incompleta entre
chamadas e compacta o buffer pendente uma vez por chunk, sem Vec temporário ou
deslocamento repetido do body para cada frame.
O trabalho é acompanhado publicamente na issue #1.
Modelo de execução adaptativo
A forma conceitual voltada à aplicação é:
let output = app.ai().resolve(request).await?;
Por baixo dessa facade, appcore-ai mantém seleção de modelo explícita. Um
model registry liga identidade do modelo, proveniência de artifact, suporte de
backend, modalidade, qualidade, privacidade e requisitos de recurso. Backends
decidem como executar a request, mas o runtime continua dono de admission,
cancelamento, health, observabilidade e policy.
ModelRegistryLimits torna explícita a retenção de metadata: modelos,
localizações por modelo, localizações agregadas e bytes contabilizados possuem
tetos configuráveis abaixo dos máximos fixos de segurança. Iteradores iniciais
e adições posteriores excessivos falham antes da retenção ou copy-on-write,
enquanto duplicatas continuam idempotentes. ModelRegistry::pressure expõe
contagens e bytes atuais/de pico e rejeições sem labels de alta cardinalidade.
A execução pode ser local, remota ou delegada a swarm experimental:
enum AiExecutionMode {
Local,
Swarm,
Auto,
}
Auto pode rotear ou escalar entre opções permitidas, mas apenas dentro da
policy declarada. Ele nunca deve mover silenciosamente uma request local-only
para compute remoto.
Perfis de recurso descrevem headroom voluntário do AppCore:
Eco: preferir menor energia e menor uso de memória;Balanced: trade-off padrão de throughput e latência;Performance: admitir execução local ou remota mais agressiva;Unrestricted: remove limites voluntários do AppCore, mas ainda respeita proteções de hardware, firmware, driver e sistema operacional.
Compute e storage são preocupações separadas:
COMPUTE: CPU / GPU / NPU / remote
STORAGE: VRAM / RAM / NVMe / peer
Um node pode doar compute, storage, ambos ou nenhum. O design de swarm precisa de contribution policy, checks de integridade, health, failover e accounting claro antes de virar comportamento de produção.
Recursos reais de hardware
cargo run -p appcore-ai --example hardware_report
cargo run -p appcore-ai --example hardware_report \
--features accelerator-nvidia
SystemHardwareProbe::default() usa cache on-demand de um segundo com
single-flight: não há thread de polling enquanto AppCore AI está ocioso. Ele lê
topologia/carga da CPU, CPU do processo e RAM disponível por APIs nativas no
macOS, Linux e Windows. Apple Silicon é GPU integrada que compartilha o pool de
RAM. Linux tem descoberta DRM sysfs best-effort de AMD/NVIDIA; a feature
opcional accelerator-nvidia carrega a NVML do sistema dinamicamente para VRAM
total/livre/usada e utilização da GPU NVIDIA exata.
Métrica desconhecida fica None, nunca zero ou ilimitada. Duas GPUs não são
somadas para caber um modelo: admission, carga e VRAM livre usam o DeviceId
exato. Memória unificada é cobrada uma vez, sem pools fictícios de RAM + VRAM.
Eco, Balanced, Performance, Unrestricted e Custom calculam headroom
voluntário da disponibilidade atual e aplicam hysteresis sob pressão. O mesmo
budget limita batching, residency, treino e contribuição Swarm explícita.
A execução de referência cobre macOS arm64 no Apple M1. Probes Linux/Windows, incluindo NVML opcional, compilam e têm testes determinísticos, mas não foram certificados fisicamente neste passe. Sysfs AMD é parcial; térmica/utilização fora das fontes documentadas e NPU continuam indisponíveis, não simuladas.
Chat e chamadas de tools
let request = AiRequest::chat(
[
AiMessage::new(AiMessageRole::System, "Responda brevemente.")?,
AiMessage::new(AiMessageRole::User, "Explique IA local-first.")?,
],
AiLimits::default(),
)?;
let response = runtime.resolve(request).await?;
Uma tool possui nome, descrição e JSON Schema limitados. AiOutput::ToolCalls
é apenas proposta: a aplicação valida os argumentos e roteia trabalho
autorizado por appcore-capabilities. Texto gerado nunca é autoridade de
escrita.
Imagens e documentos
Imagem só é transportada quando backend e modelo declaram suporte. PDF é uma modalidade de documento para routing, mas a beta não embute parser, rasterizer nem OCR universal. A aplicação escolhe um processor limitado por páginas, pixels, bytes expandidos, tempo e output.
Configurar ou treinar
LLMs generativos são configurados, não treinados, por este crate: execute o
engine, registre metadata e identidade exatas, declare capabilities e deixe o
AiRuntime rotear. Fine-tuning e conversão pertencem ao engine.
O trainer implementado é propositalmente menor: classificação local
NativeLinearV1. Execute:
cargo run -p appcore-ai --example candle_training \
--features training-candle
O job limita labels, dimensões de features, dataset, epochs, steps, batch,
learning rate, seed, CPU/RAM e checkpoints. O resultado contém bytes, SHA-256 e
um ModelDescriptor pronto para o registry. Isso não é fine-tuning de LLM.
Integração com uma aplicação
A feature appcore-sdk/ai expõe os contratos neutros de backend para a
aplicação. O deployment configura AiRuntime e possui startup
required/optional, health, bloqueio de admission, cancelamento e shutdown:
use appcore_sdk::ai::{AiRequest, AiTask};
let request = AiRequest::new(AiTask::Chat, "Resuma esta entrada limitada")?;
let response = ai_runtime.execute(request)?;
A policy de deployment falha o startup sem modelo/backend obrigatório. Expor
appcore.ai.resolve por appcore-capabilities exige AiCapabilityCodec
limitado e explícito. A seleção declarativa aguarda contrato versionado pós-1.0.
Qual engine escolher
- llama.cpp: GGUF portátil e execução híbrida CPU/GPU;
- MLX-LM: Apple Silicon;
- TabbyAPI/ExLlama: NVIDIA consumer com baixa concorrência;
- vLLM ou SGLang: serving de alta concorrência;
- TensorRT-LLM: deployments NVIDIA ajustados;
- OpenVINO: Intel CPU/GPU/NPU;
- Candle: apenas o pequeno classificador incluído, não LLM generativo.
Meça engine, revisão, quantização, contexto, batch e device juntos. Registre cold start, TTFT, tokens/s, requests/s, RAM, VRAM, fila e falhas. Não existe engine universalmente mais rápido.
Performance e prontidão beta
O benchmark repetível perf_lab gera saída humana ou JSONL e cobre lightweight,
routing, scaling de registry/scheduler, batching, artifacts, Candle/training e
1–1.000 candidatos Swarm. No Apple M1 documentado, resolve quente com 32 rotas
passou de 96,417 us para 21,958 us p50 e batch Candle 32 de 68,959 us para
31,041 us. O relatório também mantém visíveis regressões de batch pequeno e o custo
intencional da proteção no-follow.
Um workload separado com 65.536 localizações de peers antes retinha todas as entradas e alcançava 7,83 MiB de RSS pico/retido. Com admissão limitada, ele retém o máximo default de 128 por modelo, rejeita o restante explicitamente e mediu 1,91 MiB de RSS pico (-75,61%) e 1,89 MiB retido (-75,86%) em cinco processos Apple M1.
Para um classificador Candle representativo de 4 MiB, mover os buffers decodificados e reservar memória antes da leitura reduziu a mediana de cinco processos de 1,701 para 1,368 ms (-19,56%) e o RSS pico mediano de 20,16 para 16,11 MiB (-20,08%).
Para um input lightweight de 1 MiB com 524.288 palavras de um byte, remover o
Vec<&str> intermediário reduziu a mediana de cinco processos de 4,823 para
3,337 ms (-30,80%) e o RSS pico mediano de 12,98 para 3,88 MiB (-70,16%).
O veredito local é READY FOR BETA dentro do escopo documentado. Execução física Windows/Linux, soak real em aceleradores e adapter Swarm Peer RPC de produção continuam evidências do programa beta. Isolamento do processo pertence ao deployment e composição declarativa permanece trabalho pós-1.0; nenhum dos dois é anunciado por esta beta.
Segurança, limites e status
- prompts, outputs, endpoints e credenciais são redigidos dos diagnósticos;
- requests LocalOnly rejeitam permissões remotas de compute e storage;
- rotas remotas exigem grants explícitos do tenant;
- filas, attempts, peers, payloads, metadata, tools e artifacts são limitados;
- cancelamento é cooperativo; o worker bloqueante limitado o encaminha para a exchange HTTP e transportes streaming o verificam entre chunks;
- modelo exige tamanho exato e SHA-256 antes da ativação;
Unrestrictednão desliga proteções do SO ou hardware.
O release beta.2 define streaming, mas o HTTP incluído continua sendo de resposta completa; o transporte do deployment deve implementar SSE nativo explicitamente. PDF/OCR, instalação/sandbox automático do engine, Swarm de produção e manifests declarativos continuam fora do escopo desta beta. Consulte guide.pt.md, basic.pt.md e intermediate.pt.md para APIs e exemplos. O guia exato de recursos documenta matriz de plataforma, custo da dependência, fit de modelo e métricas operacionais. O relatório de performance e a matriz beta ficam versionados com o crate.