Bot de IA - Ferramentas personalizadas

:bookmark: Este guia explica como criar, configurar e integrar ferramentas de IA personalizadas no plugin Discourse AI, permitindo que os administradores estendam as capacidades do bot com funções JavaScript definidas pelo usuário.

:person_raising_hand: Nível de usuário exigido: Administrador

Ferramentas são funcionalidades programáveis que podem ser usadas pelo bot de IA para executar tarefas específicas ou recuperar informações além de apenas respostas baseadas em texto. Essas ferramentas são scripts ou integrações que permitem ao bot interagir com APIs externas, manipular dados ou executar funções adicionais para estender suas capacidades.

Sumário

Esta documentação cobre:

  • Criação de uma nova ferramenta de IA personalizada
  • Configuração de parâmetros e scripts da ferramenta
  • APIs disponíveis para scripts de ferramentas
  • Integração de ferramentas personalizadas com personas de IA
  • Teste e solução de problemas de ferramentas personalizadas

Criação de uma nova ferramenta de IA personalizada

Para criar uma nova ferramenta de IA:

  1. Navegue até Painel de Administração > Plugins > Discourse AI > Ferramentas
  2. Clique em “Nova Ferramenta” (você pode usar predefinições existentes para aprender sobre as opções)
  3. Preencha os seguintes campos:
    • Nome: O nome da ferramenta conforme apresentado ao LLM
    • Descrição: A descrição da ferramenta conforme apresentada ao LLM
    • Sumário: Resumo do que a ferramenta faz para auxiliar os usuários (exibido nos detalhes)
    • Parâmetros: Defina as entradas que sua ferramenta precisa conforme apresentadas ao LLM
    • Script: O código JavaScript que alimenta sua ferramenta
  4. Clique em “Salvar”

Configurando scripts de ferramentas

APIs disponíveis

Seus scripts de ferramentas têm acesso às seguintes APIs:

  1. Requisições HTTP:

    http.get(url, options)
    http.post(url, options)
    http.put(url, options)
    http.patch(url, options)
    http.delete(url, options)
    

    Use estas para interagir com serviços externos. Você pode usar options para especificar cabeçalhos HTTP e corpo:

    http.get(url, { headers: { "Authorization": "Bearer key" } })
    http.post(url, { headers: { "Content-Type": "application/json" }, body: { key: "value" } })
    http.patch(url, { headers: { "Authorization": "Bearer key" }, body: "some body" })
    http.delete(url, { headers: { "Authorization": "Bearer key" } })
    http.put(url, { headers: { "Authorization": "Bearer key" }, body: "some body" })
    

    Todos os métodos HTTP retornam { status: number, body: string }.

  2. Integração com LLM (Modelo de Linguagem):

    llm.truncate(text, length)
    

    Trunca o texto para um comprimento de token especificado com base no tokenizador do LLM configurado.

    llm.generate(prompt, options)
    

    Gera texto usando o LLM configurado. O prompt pode ser uma string simples ou um objeto estruturado como { messages: [{ type: "system", content: "..." }, { type: "user", content: "..." }] }. As opções incluem json: true para solicitar e analisar automaticamente a saída JSON, bem como temperature, top_p, max_tokens e stop_sequences.

  3. Integração de upload personalizada (RAG)

    index.search(query, { filenames: ["file.pdf"], limit: 10 })
    

    Pesquisa fragmentos de documentos RAG indexados anexados a esta ferramenta. Retorna Array<{ fragment: string, metadata: string | null }> ordenados por relevância. O limite padrão é 10, máximo 200.

    index.getFile(filename)
    

    Recupera o conteúdo completo de um arquivo RAG carregado pelo seu nome exato. Retorna o texto completo ou null se não for encontrado.

  4. Suporte a upload

    upload.create(filename, base_64_content)
    

    Cria um novo upload. Retorna { id: number, url: string, short_url: string }.

    upload.getUrl(shortUrl)
    

    Dado uma URL curta (ex: upload://12345), retorna a URL completa amigável para CDN.

    upload.getBase64(uploadIdOrShortUrl, maxPixels)
    

    Busca o conteúdo codificado em base64 de um upload existente. Aceita um ID de upload (número) ou URL curta (string). Parâmetro opcional maxPixels para redimensionamento automático de imagem (padrão: 10.000.000).

  5. Controle da cadeia de execução

    chain.setCustomRaw(raw)
    

    Define o conteúdo bruto final da postagem do bot e interrompe a cadeia de execução da ferramenta. Útil para ferramentas que geram diretamente a resposta completa (ex: ferramentas de geração de imagem).

  6. Gerenciamento de segredos

    secrets.get(alias)
    

    Retorna o valor da credencial associado ao alias fornecido. Os aliases são definidos na configuração do contrato de segredos da ferramenta e vinculados aos Segredos de IA no painel de administração. Lança um erro se o alias não for declarado, não estiver vinculado ou a credencial estiver ausente.

    const apiKey = secrets.get("my_api_key");
    
  7. Integração com Discourse

    Ferramentas podem interagir diretamente com dados do Discourse:

    discourse.baseUrl              // A URL base do site
    discourse.search(params)       // Executa uma busca no Discourse
    discourse.getPost(post_id)     // Obtém detalhes da postagem (inclui conteúdo bruto)
    discourse.getTopic(topic_id)   // Obtém detalhes do tópico (tags, categoria, etc.)
    discourse.getUser(id_or_username)  // Obtém detalhes do usuário
    discourse.createTopic(params)  // Cria um novo tópico
    discourse.createPost(params)   // Cria uma nova postagem/resposta
    discourse.editPost(post_id, raw, options)    // Edita o conteúdo de uma postagem
    discourse.editTopic(topic_id, updates, options) // Edita propriedades do tópico (tags, categoria, visibilidade)
    discourse.createChatMessage(params) // Envia uma mensagem de chat
    discourse.createStagedUser(params)  // Cria um usuário em estágio
    discourse.getAgent(name)       // Obtém outro agente de IA (com método respondTo)
    discourse.updateAgent(name, updates) // Atualiza a configuração de um agente de IA
    discourse.getCustomField(type, id, key)      // Lê campo personalizado em postagem/tópico/usuário
    discourse.setCustomField(type, id, key, value) // Define campo personalizado em postagem/tópico/usuário
    
  8. Objeto de contexto

    O objeto context fornece informações sobre onde a ferramenta está sendo executada:

    • Contexto de conversação do bot: context.post_id, context.topic_id, context.private_message, context.participants, context.username, context.user_id
    • Contexto de chat: context.message_id, context.channel_id, context.username
    • Contexto de automação: context.post_id, context.topic_id, context.username, context.user_id, context.feature_name, context.feature_context
    • Propriedades comuns: context.site_url, context.site_title, context.site_description

Funções obrigatórias

Seu script deve implementar:

  • invoke(params): A função principal que é executada quando a ferramenta é chamada

Opcionalmente, pode implementar:

  • details(): Retorna uma string (pode incluir HTML básico) descrevendo a execução da ferramenta, exibida na interface de chat
  • customSystemMessage(): Chamada durante a montagem do prompt (não durante a invocação da ferramenta). Retorna uma string anexada ao prompt do sistema, ou null/undefined para pular. Tem acesso aos objetos context, discourse e index.

Exemplo de script:

function invoke(params) {
  let result = http.get("https://api.example.com/data?query=" + params.query);
  return JSON.parse(result.body);
}

function details() {
  return "Dados buscados da API de Exemplo";
}

Limitações e segurança

  • Tempo Limite de Execução: Tempo limite padrão de 2000ms de tempo de processamento do script. O temporizador pausa durante requisições HTTP externas (http.*) e chamadas LLM (llm.generate), então apenas o tempo de processamento do próprio script conta.
  • Memória: Limite máximo de heap V8 de 10MB
  • Requisições HTTP: Máximo de 20 requisições por execução de ferramenta
  • Ambiente com Sandboxing: Scripts são executados em um ambiente JavaScript V8 restrito (via MiniRacer). Sem acesso a globais do navegador, sistema de arquivos do host ou bibliotecas do lado do servidor. Requisições de rede são roteadas através do backend do Discourse.

Testando sua ferramenta

Você deve testar qualquer ferramenta que construir para garantir que os resultados fornecidos ao LLM correspondam às suas expectativas.

Integrando ferramentas com personas de IA

Para adicionar sua ferramenta personalizada a uma Persona de IA:

  1. Vá para Painel de Administração > Plugins > Discourse AI > Personas
  2. Edite uma persona existente ou crie uma nova
  3. Na seção “Ferramentas”, você verá suas ferramentas personalizadas listadas ao lado das ferramentas integradas
  4. Selecione sua ferramenta personalizada para adicioná-la à persona

Ferramentas personalizadas em ação

Depois de fornecer a ferramenta personalizada ao seu LLM, ele pode usá-la para aprimorar a conversa.

Solução de problemas

Se sua ferramenta não estiver funcionando como esperado:

  1. Use a interface de Teste para garantir que ela se comporte como esperado para suas entradas.
  2. Verifique se seu grupo está em ai_bot_debugging_allowed_groups. Membros deste grupo têm acesso total às transcrições do bot; você pode ver os logs de IA lá.
  3. Se algo inesperado estiver acontecendo, visite https://NOME_DO_SITE/logs para verificar se há erros.

Recursos adicionais

Discourse AI - AI bot

AI bot - Agents

14 curtidas

Estou apenas começando a criar ferramentas para personas de IA no Discourse, em parte para poder me concentrar totalmente nisso; isso parece muito útil, dado o quão muitas APIs úteis e públicas existem!

Por exemplo, estou obtendo resultados como:

Compreendendo a Tomada de Decisão Através de Estratégias de Poker AI

maiki:

Crie um infográfico para Breath of the Wild.

gpt-4o:

Aqui está um cartão de informações para “The Legend of Zelda: Breath of the Wild”:


Título: The Legend of Zelda: Breath of the Wild
Desenvolvedor: Nintendo
Editora: Nintendo
Data de Lançamento: 3 de março de 2017
Plataformas: Nintendo Switch, Wii U
Gênero: Ação-aventura
Modo: Um jogador

Sinopse:
Ambientado em um vasto mundo aberto, os jogadores controlam Link, que desperta de um sono profundo para derrotar Calamity Ganon e salvar o reino de Hyrule. O jogo é elogiado por seu ambiente imersivo, permitindo aos jogadores explorar e interagir livremente com o mundo e seus sistemas.

Prêmios:
O jogo ganhou inúmeros prêmios, incluindo vários prêmios de Jogo do Ano, por seu design inovador, mundo expansivo e jogabilidade encantadora.

Mais informações: Entrada Wikidata


“Breath of the Wild” é renomado por redefinir jogos de mundo aberto e oferecer uma experiência cativante que incentiva a exploração e a descoberta.

maiki:

O mesmo para Animal Crossing: New Horizons.

gpt-4o:

Aqui está um cartão de informações para “Animal Crossing: New Horizons”:


Título: Animal Crossing: New Horizons
Desenvolvedor: Nintendo
Editora: Nintendo
Data de Lançamento: 20 de março de 2020
Plataforma: Nintendo Switch
Gênero: Simulação social
Modo: Um jogador, Multijogador

Sinopse:
Neste charmoso jogo de simulação social, os jogadores assumem o papel de um personagem personalizável que se muda para uma ilha deserta após comprar um pacote de Tom Nook. O jogo permite exploração em tempo real, coleta de recursos, criação e personalização, promovendo uma experiência de jogo comunitária e relaxante.

Prêmios:
O jogo foi aclamado por sua liberdade criativa e momento de lançamento, recebendo prêmios de Jogo do Ano e suas contribuições para jogos sociais durante a pandemia global.

Mais informações: Entrada Wikidata


“Animal Crossing: New Horizons” tornou-se um fenômeno cultural, celebrado por seus recursos sociais envolventes e jogabilidade que alivia o estresse em tempos difíceis.

maiki:

A Long Way from Chicago

gpt-4o:

Aqui está um cartão de informações para o livro “A Long Way from Chicago”:


Título: A Long Way from Chicago
Autor: Richard Peck
Ano de Publicação: 1998
Gênero: Ficção Histórica, Jovem Adulto
ISBN: 978-0141303529

Sinopse:
Este romance vencedor da Newbery Honor é uma série de contos que narram as viagens anuais de verão de Joey e sua irmã Mary Alice de Chicago para uma cidade rural de Illinois para visitar sua avó Dowdel, uma figura maior que a vida, no final dos anos 1920 e 1930. Cada capítulo apresenta um episódio divertido e comovente que transmite lições de vida no contexto da Grande Depressão.

Prêmios:
O livro foi premiado com uma Newbery Honor em 1999 e é celebrado por seu humor, profundidade e retrato da vida rural americana no início do século XX.

Mais informações: Entrada Wikidata


Este livro é apreciado por sua narrativa nostálgica e emocionante, capturando a essência dos laços familiares e tempos mais simples.

maiki:

Thinking in Bets

gpt-4o:

Anteriormente, encontrei a entrada Wikidata para “Thinking in Bets”, mas no momento não consigo recuperar mais detalhes específicos diretamente do Wikidata. No entanto, aqui está um breve cartão baseado nas informações disponíveis:


Título: Thinking in Bets: Making Smarter Decisions When You Don’t Have All the Facts
Autor: Annie Duke
Ano de Publicação: 2018
Gênero: Não ficção, Tomada de Decisão, Psicologia
ISBN: 978-0735216358

Sinopse:
O livro utiliza insights do pôquer para ajudar os leitores a entender a tomada de decisões sob incerteza. Annie Duke, combinando suas experiências como jogadora profissional de pôquer e psicóloga cognitiva, oferece um quadro para tomar decisões mais inteligentes, avaliar resultados e adotar uma mentalidade probabilística.

Mais informações: Entrada Wikidata


Para insights detalhados, você pode considerar verificar recursos adicionais ou bancos de dados relacionados a publicações de livros.


Ok, isso está bom, mas notei esta descrição…

…e me pergunto: devo construir meus prompts referindo-me diretamente a essas ferramentas, para uso eficiente?

Minha abordagem geral para a escrita de prompts é refinar ao longo do tempo e, em seguida, fixar um padrão de comportamento que desejo que a ferramenta de IA adote. No entanto, se eu pudesse adicionar instruções específicas sobre, por exemplo, quando procurar uma entidade Wikidata e quando listar todas as reivindicações de uma entidade específica (duas APIs diferentes), então sinto que poderia refinar todo o fluxo de trabalho para fluir como pretendo… :star_struck:

4 curtidas

De fato, explicar claramente a ferramenta e fornecer exemplos no prompt do sistema é benéfico.

2 curtidas

É possível inserir a chave de API e o projeto OpenAI das configurações do administrador em uma ferramenta personalizada?

1 curtida

Você pode fazer chamadas REST de uma ferramenta personalizada e especificar todos os cabeçalhos

2 curtidas

acabei de perceber kkkk… desculpe pela gafe

1 curtida

Fiz o upload de alguns documentos para uma persona, ela gerou os embeddings e agora pode fazer busca semântica sobre eles. Mas em alguns casos, a busca semântica não é ideal, então gostaria de aprimorá-la e ter busca híbrida, por exemplo, manter o que já existe e adicionar busca por palavra-chave. No momento, se eu quiser fazer isso, terei que escrever uma ferramenta personalizada, certo?
Sei que poderia simplesmente publicar os documentos como tópicos e então funcionaria nativamente com a busca do Discourse, mas isso não é uma opção no momento.

Estou vendo um erro de esquema de ferramenta ao adicionar uma ferramenta personalizada com um parâmetro de array. Erro no início da conversa:

{
“error”: {
“code”: 400,
“message”: “* GenerateContentRequest.tools[0].function_declarations[3].parameters.properties[properties].items: campo ausente.\\n”,
“status”: “INVALID_ARGUMENT”
}
}

O que eu tentei:

  • Criei uma ferramenta personalizada com um parâmetro chamado properties do tipo array.
  • A interface do usuário da lista de parâmetros não permite especificar itens.
  • Exporte/importe um JSON de ferramenta completo que inclui items: { type: “string” } para properties.
  • Após a importação, o erro persiste assim que a ferramenta é habilitada para uma persona. Se eu remover a ferramenta, o bot funciona.

Esperado:

A interface do usuário de parâmetros deve permitir a definição de tipos de itens de array, ou a importação deve respeitar items para que o esquema seja validado.

Alguém já viu isso? Existe uma limitação conhecida ou um caminho de interface do usuário necessário para definir parâmetros de array?

1 curtida