- SymbolicAI é um framework neuro-simbólico que combina programação clássica em Python com a natureza diferenciável e programável dos LLMs, com o objetivo de ser usado de forma natural dentro do Python
- Os conceitos centrais são os primitivos baseados no objeto
Symbol e os contratos (contracts) que validam e corrigem resultados de LLM; o comportamento padrão começa no modo sintático por segurança e velocidade
Symbol se comporta como um valor normal de Python no modo sintático e lida com contexto e significado no modo semântico, podendo alternar com chamadas de função semântica como semantic=True, .sem e .map()
- O sistema de contratos aplica os princípios de Design by Contract a fluxos de trabalho com LLM, cobrindo validação de entrada, alteração de estado, geração pelo LLM, validação de saída e até resposta alternativa em caso de falha em um único fluxo baseado em decoradores
- A instalação começa com
pip install symbolicai, e o uso real exige configuração de symconfig e symai.config.json; o motor neuro-simbólico é obrigatório para usar o pacote symai
O modelo que a SymbolicAI busca
- SymbolicAI é um framework neuro-simbólico (neuro-symbolic) que trata código Python comum e processamento semântico baseado em LLM em conjunto
- Com design modular, pode ser expandido e customizado conforme a necessidade
- Suporta integração com ferramentas como criação de motores próprios, hospedagem de motores locais, busca na web e geração de imagens
- O nome do projeto pretende dar crédito ao trabalho fundamental de Allen Newell e Herbert Simon
O primitivo Symbol
- No centro da SymbolicAI está o objeto
Symbol, e pequenas operações combináveis podem ser usadas como sintaxe nativa do Python
Symbol tem dois modos de funcionamento
- Syntactic: funciona como valores comuns de Python, como strings, listas e inteiros passados diretamente
- Semantic: conecta-se ao motor neuro-simbólico para lidar com significado e contexto
- O padrão é o modo sintático
- Operadores Python como
==, ~ e & são sobrecarregados em symai
- Se o motor fosse chamado imediatamente em toda comparação ou bitshift, o sistema ficaria lento e poderia gerar efeitos colaterais inesperados
- A ideia é manter segurança e velocidade ativando o comportamento semântico apenas quando necessário
Como mudar para o modo semântico
- Ao definir
semantic=True no momento da criação, ele já passa a funcionar como um Symbol semântico desde o início
- No exemplo,
Symbol("Cats are adorable", semantic=True) trata "feline" in S como True
- Quando necessário, dá para usar a projeção
.sem para mudar para comportamento semântico e .syn para voltar ao comportamento sintático
- O mesmo valor
"Cats are adorable" resulta em "feline" in S.sem como True, enquanto no S padrão é False
- Operações em notação de ponto como
.map() ou outras chamadas de função semântica convertem automaticamente o Symbol para o modo semântico
- No exemplo, ao aplicar
convert all fruits to vegetables a uma lista de frutas, apenas as frutas viram vegetais, enquanto cat e dog são mantidos
- As projeções
.sem e .syn funcionam aplicando camadas de comportamento diferentes sobre o mesmo objeto base, permitindo encadear operações sintáticas e semânticas em um único Symbol
Exemplos de operações disponíveis
- SymbolicAI oferece vários primitivos, documentados em primitives
== verifica igualdade literal no modo sintático e trata equivalência difusa ou conceitual, como "Hi" e "Hello", no modo semântico
+ faz soma de números, strings e listas no modo sintático e realiza combinação significativa, mistura ou fusão conceitual no modo semântico
& atua como AND bit a bit ou lógico no modo sintático e como combinação lógica, inferência ou fusão de contexto no modo semântico
- Recursos exclusivos do modo semântico incluem
.choice(cases, default), .foreach(condition, apply), .cluster(**clustering_kwargs?) e .similarity(other, metric?, normalize?)
.cluster() agrupa dados semanticamente usando DBSCAN do sklearn
.similarity() calcula similaridade entre embeddings
Como os contratos tratam a saída de LLMs
- Partindo da ideia de que LLMs podem alucinar, mas código não pode, a SymbolicAI aplica os princípios de Design by Contract ao universo dos LLMs
- Em vez de depender só de testes posteriores, os contratos unem modelo de dados e restrições de validação em decoradores para tratar corretude já na fase de design
- No código de exemplo, o decorador de contrato usa as seguintes opções
pre_remedy=True: tenta corrigir automaticamente entradas inválidas
post_remedy=True: tenta corrigir automaticamente saídas inválidas do LLM
accumulate_errors=True: envia o histórico de erros a cada nova tentativa
verbose=True: exibe o progresso no terminal
remedy_retry_params: usa tries=3, delay=0.4, max_delay=4.0, jitter=0.15, backoff=1.8, graceful=False
- O fluxo de alto nível da classe
Expression com contratos aplicados é o seguinte
prompt: descrição estática do que o LLM deve fazer; é obrigatório
pre: valida a entrada; é opcional
act: altera o estado; é opcional
- LLM: o motor da SymbolicAI gera a resposta esperada
post: verifica se a resposta atende às regras semânticas; é opcional
forward: é obrigatório e, em caso de sucesso do contrato, retorna um objeto de LLM com tipo validado; em caso de falha, retorna uma resposta de fallback graceful
- A documentação dos contratos está em sistema de validação de contratos do DeepWiki e features/contracts
Instalação e recursos opcionais
- A instalação básica é feita via pip
pip install symbolicai
- Também é possível clonar o repositório e configurar um ambiente virtual Python com uv
>= 0.9.17
git clone git@github.com:ExtensityAI/symbolicai.git
cd symbolicai
uv sync --python x.xx
source ./.venv/bin/activate
- A SymbolicAI usa vários motores para processar texto, voz e imagem, além de incluir acesso a um motor de busca para recuperar informações da web
- Dependências opcionais podem ser instaladas como extras por recurso
bitsandbytes, hf, lean, llama_cpp, ocr, qdrant, scrape, search, serpapi, services, solver, whisper, wolframalpha
- Todas as dependências opcionais podem ser instaladas de uma vez
pip install "symbolicai[all]"
uv sync --frozen instala dependências fixadas no arquivo de lock fornecido
- Algumas dependências opcionais podem exigir etapas adicionais de instalação, e algumas atualmente têm apenas suporte experimental, podendo não funcionar como esperado
Gerenciamento de configuração e motor obrigatório
- A SymbolicAI usa um sistema de gerenciamento de configuração baseado em prioridade
- As configurações são carregadas de três locais, nesta ordem de prioridade
- Modo de depuração no diretório de trabalho atual: prioridade mais alta e aplicável apenas a
symai.config.json
- Configuração específica do ambiente Python: localizada em
{python_env}/.symai/, adequada para configurações por projeto
- Configuração global no diretório home: localizada em
~/.symai/, servindo como fallback padrão
- Há três arquivos de configuração gerenciados
symai.config.json: configuração principal da SymbolicAI
symsh.config.json: configuração do shell
symserver.config.json: configuração do servidor
symconfig mostra os locais de configuração, o caminho da configuração ativa e a configuração atual com informações sensíveis ocultadas, além de iniciar o cache inicial de pacotes e a inicialização dos arquivos de configuração
- Para usar o pacote
symai, o motor neuro-simbólico é obrigatório
- Definir propriedades do motor em
symai.config.json no caminho do projeto substitui variáveis de ambiente
- A configuração de exemplo inclui
claude-sonnet-4-6 como valor de NEUROSYMBOLIC_ENGINE_MODEL, text-embedding-3-small como modelo de embedding, tts-1 como modelo de TTS, mistral-ocr-latest como modelo de OCR e qdrant como motor de indexação, entre outros
- Por padrão, os avisos ao usuário ficam ativados e podem ser desativados com a variável de ambiente
SYMAI_WARNINGS=0
Testes, documentação e licença
- Exemplos para executar testes são os seguintes
pytest tests
pytest -m mandatory
pytest --cov=symbolicai tests
- Antes dos testes, a configuração precisa estar correta
- Como próximos passos, consulte a página da SymbolicAI no DeepWiki, o artigo e os tutoriais em vídeo
- As informações de citação apontam para o preprint no arXiv de 2024 intitulado
Symbolicai: A framework for logic-based approaches combining generative models and solvers
- A licença do projeto é a BSD-3-Clause License
1 comentários
Comentários do Hacker News
Essas funcionalidades que parecem vodu são as mais interessantes
Por exemplo, ao aplicar “troque todas as frutas por vegetais” a
['apple', 'banana', 'cherry', 'cat', 'dog']com ummapbaseado em significado, o resultado sai como['carrot', 'broccoli', 'spinach', 'cat', 'dog']; jáequals()muda o resultado da comparação conforme o contexto, comocontext='greeting context'oucontext='politeness level'Operadores bit a bit também são usados como combinações lógicas semânticas, de modo que
horn_rule & observationleva a inferência; por issointerpret()parece poderosoFico curioso sobre a motivação para criar isso, as aplicações reais e o caso de uso favorito até agora
A ideia é pegar operadores relacionais centrais e transformá-los em versões baseadas em significado como extensão de bibliotecas de dataframes em Python, e cada chamada vira depois um ponto de “modelo” para trabalhos mais complexos, como abordagens baseadas em aprendizado
O lado de SQL em nuvem, como Snowflake, também parece estar indo nessa direção; na louie.ai usamos uma abordagem parecida em notebooks/dashboards/APIs de IA (MCP etc.), em que você conversa com dados do Splunk, Databricks, bancos de grafos e afins, e o sistema descobre operadores simbólicos + semânticos adequados ao contexto — na prática, foi bem útil
O principal caso de uso, em 80% das vezes, é criar um dataframe enriquecido por um map baseado em significado, como “pegue todos os alertas do índice xyz do Splunk e adicione uma coluna marcando itens suspeitos e outra explicando o motivo”, seguido de um reduce baseado em significado, como “resuma o que encontrou”, para obter uma explicação em linguagem natural
Não mudou muita coisa desde quando comecei o projeto no fim de 2022; os modelos apenas ficaram melhores, mas muitos dos operadores primitivos já existiam desde a época do GPT-3
O mais importante recentemente é a contribuição do DbC: é possível encadear contratos, e os guardrails se propagam bem, o que é único porque resolveu quase todos os problemas relacionados a agentes que joguei nele
O Perplexity ficou menos útil por causa da busca web da OpenAI, e a própria busca web da OpenAI ainda não é suficiente em comparação com algo customizado diretamente, então criei meu próprio agente de pesquisa profunda: https://x.com/futurisold/status/1931751644233945216
Na empresa, também encadeamos 3 contratos para criar geração de documentos de ponta a ponta, e há um exemplo de saída aqui: https://drive.google.com/file/d/1Va7ALq_N-fTYeumKhH4jSxsTrWD...
A entrada era um pedido para comparar e analisar os system prompts dos principais provedores de IA, identificar formatos como XML/Markdown/JSON, instruções de bajulação/manipulabilidade, restrições de uso de ferramentas, guardrails éticos e diferenças de design de alinhamento, e sintetizar tudo em um relatório técnico; as instruções geradas foram expandidas em perguntas específicas comparando a estrutura dos system prompts, os frameworks linguísticos e as restrições operacionais de OpenAI, Google, Anthropic, xAI etc.
Os contratos foram apresentados no post de março e evoluíram bastante desde então, mas a base e a motivação continuam as mesmas: https://futurisold.github.io/2025-03-01-dbc/
Acho que linkar o artigo e o notebook de exemplos junto ajudaria na compreensão
https://github.com/ExtensityAI/symbolicai/blob/main/examples...
https://arxiv.org/pdf/2402.00854
Muito legal
Poder usar operadores como
==e+não como sintaxe, mas como operadores baseados em significado, parece que pode virar adubo para novas ideias, parecido com a sensação de quando word embeddings apareceram pela primeira vez e surgiu uma álgebra conceitual meio frouxa do tipo “King - Man + Woman = Queen”Dito isso, a integração neural + simbólica aqui parece, como na maioria dos sistemas, uma estrutura relativamente rasa e com firewall, mais próxima da categoria Type 3 / Neuro;Symbolic: https://harshakokel.com/posts/neurosymbolic-systems
Acho que a verdadeira mágica virá quando formos para uma integração mais fundamental; na nossa empresa (https://onton.com), também estamos pensando em sistemas pós-LLM com uma representação integrada que não seja puramente simbólica nem uma matriz densa de ponto flutuante, capacidade de aprendizado incremental a partir de poucos dados ruidosos evitando catastrophic forgetting, confiabilidade sólida em matemática e operações simbólicas, e ausência de alucinações
Colar sistemas existentes com uma pistola de cola também é útil, mas uma arquitetura integrada deve mudar tudo
Há um bug na parte do contrato de correção
Depois de
valid_opts = ['A', 'B', 'C'], apareceif v not in valid_sizes:, mas valid_sizes não está definido“Symbolic AI” já é um termo bem definido, então achei isso um pouco lamentável: https://en.m.wikipedia.org/wiki/Symbolic_artificial_intellig...
Posso mudar o nome, e no artigo há uma nota de rodapé sobre a escolha do nome
A intenção era dar crédito ao trabalho fundamental de Newell e Simon, que inspirou este projeto
Fiquei curioso sobre a estrutura de custos
Quero saber se, cada vez que uma linha que envolve computação em linguagem natural é executada, há custo de inferência do LLM, e se, ao usar uma API externa, realmente há cobrança a cada vez
Por exemplo, fico curioso sobre o que acontece se uma função “symbolic” for chamada dentro de um loop
Por exemplo, se você usar OpenAI, toda operação baseada em significado vira uma chamada à API da OpenAI
Se você hospedar um LLM local com
llama.cpp, não há cobrança de inferência além do custo de hospedagem do modeloHoje em dia, quem gera o código é o LLM, então fico curioso sobre como uma estrutura sintática específica como
Symbol, que contém contexto e pode ser manipulada com operadores do Python, ajuda em comparação com código Python comum criado quando uma pessoa instrui condições de verificação e equilíbrioPor exemplo, em vez de usar uma gramática que transforma frutas em legumes/verduras, também seria possível pedir ao LLM, via prompt, que crie um programa que receba uma lista de frutas e chame internamente um LLM para retornar os legumes/verduras correspondentes
Quero entender a diferença
Se você fizer o LLM criar um sistema formal, ele pode ser verificado com muito mais facilidade do que um programa de uso geral
Fiquei curioso se vocês também consideraram IA neuro-simbólica capaz de evoluir
https://deepwiki.com/dubprime/mythral/3.2-genome-system
Ou algo na direção de sentir emoções?
https://deepwiki.com/search/how-do-emotives-work_193cb616-54...
Também fico curioso se você leu Society of Mind, de Marvin Minsky
Também fiz experimentos que vão da teoria da mente até emoções, mas no momento sinto que os modelos ainda não chegaram suficientemente a esse nível, então parei porque o retorno em relação ao esforço diminuiu
Posso retomar facilmente, mas Minsky não é meu favorito; dessa geração, sou mais atraído por Newell/Simon
Mexi um pouco com regressão simbólica, fazendo um LLM revisar documentos e criar operadores primitivos para colocar no PySR do GitHub (github.com/MilesCranmer/PySR), ou seja, criar operadores
Não fui muito longe porque foi difícil conectar tudo, mas com uma ferramenta dessas talvez eu tentasse de novo
Recomendo usar contratos
Já usei uma abordagem parecida em contratos que “costuravam” iterativamente grafos de ontologia quebrados
Como modelo de dados que poderia servir de inspiração, havia estruturas como
Merge,Bridge,Prune,Operation; cada uma definia os índices dos clusters a serem mesclados, relações de classe pai-filho e a lista de classes a podar, e então validadores impunham as condições de operações binárias/unáriasDe modo semelhante, dá para criar um modelo para operadores, fazer o contrato resolver um operador por vez e depois aplicar esse operador