4.0 KiB
4.0 KiB
| name | description |
|---|---|
| creating-jasmine-tools | Defines the standard for creating Tools compatible with Jasmine (Captain AI) and the Agents gem. Use when the user needs to create a new Ruby tool class. |
Objetivo
Padronizar a criação de ferramentas no escopo Captain::Tools para garantir compatibilidade com Agents::Tool, RubyLLM e o sistema de injeção de dependência da Jasmine.
Caminhos Padrão
- Local principal:
enterprise/lib/captain/tools/ - Alternativo (se service-heavy):
enterprise/app/services/captain/tools/
Template Base
module Captain
module Tools
class NomeDaSuaTool < Captain::Tools::BasePublicTool
# Definir tool_name se for diferente do nome da classe (Opcional)
# def name
# 'nome_da_tool'
# end
def description
'Descrição curta e objetiva do que a ferramenta faz. Isso é visível para a IA.'
end
# Definição de Parâmetros (DSL da gem Agents)
param :parametro_um, type: 'string', desc: 'Descrição do parâmetro', required: true
param :parametro_dois, type: 'integer', desc: 'Descrição do parâmetro opcional', required: false
# Método principal de execução
# tool_context: Objeto de contexto (pode conter estado da conversa)
# kwargs: Argumentos passados pela IA já normalizados
def perform(tool_context, **kwargs)
# 1. Logging Inicial Padronizado
Rails.logger.info "[#{self.class.name}] Iniciando execução. Params: #{kwargs.inspect}"
# 2. Resolução de Dependências (Conversa/Contato)
# O BasePublicTool já tenta popular @conversation e @user no initialize,
# mas podemos garantir reload ou fallback aqui.
ensure_context!(tool_context)
return "Erro: Conversa não identificada." unless @conversation
# 3. Lógica da Ferramenta
parametro_um = kwargs[:parametro_um]
result = executa_logica(parametro_um)
# 4. Retorno
# Sempre retornar String ou Hash serializável (JSON friendly)
result
rescue StandardError => e
handle_error(e)
end
private
def ensure_context!(tool_context)
# Se @conversation não veio no initialize, tenta extrair do contexto
if @conversation.nil? && tool_context.present?
state = resolve_context(tool_context)
@conversation = find_conversation(state)
end
end
def executa_logica(dado)
# Implementação...
"Sucesso: #{dado}"
end
def handle_error(exception)
Rails.logger.error "[#{self.class.name}] Erro: #{exception.message}"
Rails.logger.error exception.backtrace.first(5).join("\n")
"Ocorreu um erro técnico ao processar sua solicitação: #{exception.message}"
end
end
end
end
Checklist de Verificação
- Herança: A classe herda de
Captain::Tools::BasePublicTool(para tools públicas) ouCaptain::Tools::BaseTool? - Método
perform: Está implementandoperformao invés de apenasexecute(para compatibilidade total comAgents)? - Parâmetros: Os parâmetros estão definidos com
param :nome, type: ...? Isso ajuda a gerar o esquema JSON automaticamente para a LLM. - Logging: Existe log no início (
info) e no rescue (error) com prefixo[NomeClass]? - Contexto: A ferramenta lida com o fato de
@conversationpoder ser nulo (ex: uso fora do fluxo web)? - Retorno: O retorno é texto ou JSON string (algo que a LLM possa ler)?
Boas Práticas
- Snake Case: Nomes de arquivo em snake_case (ex:
check_availability_tool.rb). - Nomes Claros: O método
name(ou o nome da classe inferido) deve ser claro (ex:consultar_saldoé melhor queacao_banco). - Idempotência: Se possível, a ferramenta deve ser segura de rodar múltiplas vezes (ex: checar disponibilidade não altera estado, reservar altera - cuidado).
- Tratamento de Erros: Nunca deixe uma exception explodir para a LLM. Capture
StandardErrore retorne uma mensagem amigável de erro.