---
title: NL2SQL Tool
description: O `NL2SQLTool` foi projetado para converter linguagem natural em consultas SQL.
icon: language
mode: "wide"
---

## Visão Geral

Esta ferramenta é utilizada para converter linguagem natural em consultas SQL. Quando passada para o agente, ela irá gerar as consultas e, em seguida, utilizá-las para interagir com o banco de dados.

Isso possibilita múltiplos fluxos de trabalho, como por exemplo ter um Agente acessando o banco de dados para buscar informações com base em um objetivo e, então, usar essas informações para gerar uma resposta, relatório ou qualquer outro tipo de saída. Além disso, permite que o Agente atualize o banco de dados de acordo com seu objetivo.

**Atenção**: Por padrão, a ferramenta opera em modo somente leitura (apenas SELECT/SHOW/DESCRIBE/EXPLAIN). Operações de escrita exigem `allow_dml=True` ou a variável de ambiente `CREWAI_NL2SQL_ALLOW_DML=true`. Quando o acesso de escrita estiver habilitado, certifique-se de que o Agente use um usuário de banco de dados com privilégios mínimos ou um Read-Replica sempre que possível.

## Modo Somente Leitura e Configuração de DML

O `NL2SQLTool` opera em **modo somente leitura por padrão**. Apenas os seguintes tipos de instrução são permitidos sem configuração adicional:

- `SELECT`
- `SHOW`
- `DESCRIBE`
- `EXPLAIN`

Qualquer tentativa de executar uma operação de escrita (`INSERT`, `UPDATE`, `DELETE`, `DROP`, `CREATE`, `ALTER`, `TRUNCATE`, etc.) resultará em erro, a menos que o DML seja habilitado explicitamente.

O modo somente leitura também bloqueia os caminhos indiretos para uma escrita:

| Bloqueado no modo somente leitura | Exemplo |
| --- | --- |
| Consultas com múltiplas instruções | `SELECT 1; DROP TABLE users` |
| CTEs de escrita, incluindo a forma `MATERIALIZED` | `WITH d AS MATERIALIZED (DELETE FROM users RETURNING *) SELECT * FROM d` |
| Uma escrita após uma CTE | `WITH d AS (SELECT 1) DELETE FROM users` |
| `EXPLAIN ANALYZE`, que executa seu argumento | `EXPLAIN ANALYZE DELETE FROM users` |
| Escrita no sistema de arquivos do servidor de banco de dados | `SELECT * FROM users INTO OUTFILE '/var/www/shell.php'` |
| Funções que alcançam o sistema de arquivos do servidor ou abrem uma nova conexão | `SELECT pg_read_file('/etc/passwd')`, `dblink_exec(...)` |
| Uma instrução `WITH` que não pode ser confirmada como somente leitura | `WITH d AS DELETE FROM users` |

As instruções são analisadas com literais de texto e comentários mascarados, de modo que uma palavra-chave escondida em um literal não é confundida com um comando (`SELECT 'DROP TABLE users'` é permitido) e um comentário colocado entre palavras-chave não esconde nenhum (`EXPLAIN /*x*/ ANALYZE DELETE ...` é bloqueado). Um ponto e vírgula dentro de um literal não conta como separador de instruções, portanto `SELECT ';'` é uma única instrução válida.

No modo somente leitura, a ferramenta também marca a transação como `SET TRANSACTION READ ONLY`, de forma que PostgreSQL e MySQL rejeitam escritas no próprio banco de dados, independentemente de como a instrução foi escrita. Backends sem essa sintaxe (SQLite, SQL Server, Snowflake) registram uma mensagem de depuração e voltam a depender apenas da validação de instruções — mais um motivo para confiar em um papel somente leitura em vez da análise textual.

<Warning>
As verificações internas de somente leitura são defesa em profundidade, não uma fronteira completa. Elas inspecionam o texto da instrução, e SQL é específico de cada banco: uma instrução que começa com `SELECT` ainda pode alcançar o sistema de arquivos do servidor (`SELECT ... INTO OUTFILE`, `pg_read_file()`) ou chamar uma função com efeitos colaterais. Os caminhos conhecidos são bloqueados explicitamente, mas o único controle completo são os privilégios concedidos em `db_uri`. **Aponte a ferramenta para um papel de banco de dados somente leitura e com privilégio mínimo.**
</Warning>

### Habilitando Operações de Escrita

Você pode habilitar DML (Linguagem de Manipulação de Dados) de duas formas:

**Opção 1 — parâmetro do construtor:**

```python
from crewai_tools import NL2SQLTool

nl2sql = NL2SQLTool(
    db_uri="postgresql://example@localhost:5432/test_db",
    allow_dml=True,
)
```

**Opção 2 — variável de ambiente:**

```bash
CREWAI_NL2SQL_ALLOW_DML=true
```

```python
from crewai_tools import NL2SQLTool

# DML habilitado via variável de ambiente
nl2sql = NL2SQLTool(db_uri="postgresql://example@localhost:5432/test_db")
```

### Exemplos de Uso

**Somente leitura (padrão) — seguro para análise e relatórios:**

```python
from crewai_tools import NL2SQLTool

# Apenas SELECT/SHOW/DESCRIBE/EXPLAIN são permitidos
nl2sql = NL2SQLTool(db_uri="postgresql://example@localhost:5432/test_db")
```

**Com DML habilitado — necessário para workloads de escrita:**

```python
from crewai_tools import NL2SQLTool

# INSERT, UPDATE, DELETE, DROP, etc. são permitidos
nl2sql = NL2SQLTool(
    db_uri="postgresql://example@localhost:5432/test_db",
    allow_dml=True,
)
```

<Warning>
Habilitar DML concede ao agente a capacidade de modificar ou destruir dados. Ative apenas quando o seu caso de uso exigir explicitamente acesso de escrita e certifique-se de que as credenciais do banco de dados estejam limitadas aos privilégios mínimos necessários.
</Warning>

## Requisitos

- SqlAlchemy
- Qualquer biblioteca compatível com o banco de dados (ex.: psycopg2, mysql-connector-python)

## Instalação

Instale o pacote crewai_tools

```shell
pip install 'crewai[tools]'
```

## Uso

Para utilizar o NL2SQLTool, você precisa passar a URI do banco de dados para a ferramenta. O formato da URI deve ser `dialect+driver://username:password@host:port/database`.

```python Code
from crewai_tools import NL2SQLTool

# psycopg2 foi instalado para rodar este exemplo com PostgreSQL
nl2sql = NL2SQLTool(db_uri="postgresql://example@localhost:5432/test_db")

@agent
def researcher(self) -> Agent:
    return Agent(
        config=self.agents_config["researcher"],
        allow_delegation=False,
        tools=[nl2sql]
    )
```

## Exemplo

O objetivo principal da tarefa era:

"Recupere a receita mensal média, máxima e mínima para cada cidade, mas inclua apenas cidades que tenham mais de um usuário. Além disso, conte o número de usuários em cada cidade e classifique os resultados pela receita mensal média em ordem decrescente"

Assim, o Agente tentou obter informações do banco de dados; a primeira vez está errada, então o Agente tenta novamente, consegue a informação correta e repassa para o próximo agente.

![alt text](https://github.com/crewAIInc/crewAI-tools/blob/main/crewai_tools/tools/nl2sql/images/image-2.png?raw=true)
![alt text](https://github.com/crewAIInc/crewAI-tools/raw/main/crewai_tools/tools/nl2sql/images/image-3.png)

O segundo objetivo da tarefa foi:

"Revise os dados e crie um relatório detalhado e, em seguida, crie a tabela no banco de dados com os campos baseados nos dados fornecidos. Inclua informações sobre a receita mensal média, máxima e mínima para cada cidade, mas apenas inclua cidades que possuam mais de um usuário. Também conte o número de usuários em cada cidade e classifique os resultados pela receita mensal média em ordem decrescente."

Agora as coisas começam a ficar interessantes: o Agente gera a consulta SQL não só para criar a tabela, mas também inserir os dados na tabela. E, ao final, o Agente ainda retorna o relatório final que condiz exatamente com o que estava no banco de dados.

![alt text](https://github.com/crewAIInc/crewAI-tools/raw/main/crewai_tools/tools/nl2sql/images/image-4.png)
![alt text](https://github.com/crewAIInc/crewAI-tools/raw/main/crewai_tools/tools/nl2sql/images/image-5.png)

![alt text](https://github.com/crewAIInc/crewAI-tools/raw/main/crewai_tools/tools/nl2sql/images/image-9.png)
![alt text](https://github.com/crewAIInc/crewAI-tools/raw/main/crewai_tools/tools/nl2sql/images/image-7.png)

Este é um exemplo simples de como o NL2SQLTool pode ser utilizado para interagir com o banco de dados e gerar relatórios baseados nos dados do banco.

A ferramenta oferece possibilidades infinitas para a lógica do Agente e como ele pode interagir com o banco de dados.

```md
 DB -> Agent -> ... -> Agent -> DB
```