aia
é um utilitário de linha de comando que facilita a interação com modelos de IA. Ele automatiza o gerenciamento de prompts pré-composicionais e executa comandos generativos de IA (Gen-AI) nesses prompts, aproveitando o aumento do tamanho da janela de contexto dos LLMs modernos.
Ele aproveita a gem prompt_manager
para gerenciar prompts para mods
e utilitários CLI sgpt
. Ele utiliza "ripgrep" para procurar arquivos de prompt. Ele usa fzf
para seleção imediata com base em um termo de pesquisa e correspondência difusa.
Mudança mais recente : consulte o Changelog
Apenas para sua informação ... Estou trabalhando no ramo
develop
para eliminar a dependência de processadores LLM de back-end, como mods e llm. Estou refatorando aia para usar minha própria gem de cliente universal chamada ai_client, que dá acesso a todos os modelos e todos os provedores.
aia
llm
sgpt
plz
Instale a gem executando:
gem install aia
Instale os utilitários de linha de comando executando:
brew install mods fzf ripgrep
Você também precisará estabelecer um diretório em seu sistema de arquivos onde sejam mantidos os arquivos de texto de prompt, os últimos parâmetros usados e os arquivos de log de uso.
Configure uma variável de ambiente do sistema (envar) chamada "AIA_PROMPTS_DIR" que aponta para o diretório de prompts. O padrão está no diretório HOME chamado ".prompts". O envar "AIA_ROLES_DIR" aponta para o seu diretório de funções onde você tem prompts que definem as diferentes funções que você deseja que o LLM assuma quando estiver fazendo seu trabalho. O diretório de funções padrão está dentro do diretório de prompts. Seu nome é "papéis".
Você também pode instalar o script de conclusão para seu shell. Para obter uma cópia do script de conclusão, faça:
aia --completion bash
fish
e zsh
também estão disponíveis.
O relatório de uso obtido usando -h
ou --help
é implementado como uma página man
padrão. Você pode usar ambos --help --verbose
de -h -v
juntos para obter não apenas a página man aia
mas também o relatório de uso da ferramenta de processamento backend
LLM.
$ aia --help
Os padrões de configuração aia
podem ser substituídos por variáveis de ambiente do sistema (envars) com o prefixo "AIA_" seguido pelo nome do item de configuração também em letras maiúsculas. Todos os itens de configuração podem ser substituídos desta forma por um envar. A tabela a seguir mostra alguns exemplos.
Item de configuração | Valor padrão | chave envar |
---|---|---|
back-end | moda | AIA_BACKEND |
arquivo_config | zero | AIA_CONFIG_FILE |
depurar | falso | AIA_DEBUG |
editar | falso | AIA_EDIT |
extra | '' | AIA_EXTRA |
difuso | falso | AIA_FUZZY |
arquivo_de_log | ~/.prompts/_prompts.log | AIA_LOG_FILE |
redução | verdadeiro | AIA_MARKDOWN |
modelo | gpt-4-1106-visualização | AIA_MODEL |
arquivo_de_saída | STDOUT | AIA_OUT_FILE |
prompts_dir | ~/.prompts | AIA_PROMPTS_DIR |
modelo de fala. | tts-1 | AIA_SPEECH_MODEL |
detalhado | FALSO | AIA_VERBOSE |
voz | liga | AIA_VOICE |
Veja o hash @options
no arquivo cli.rb
para obter uma lista completa. Existem alguns itens de configuração que não fazem necessariamente sentido para uso como substituição de envar. Por exemplo, se você definir export AIA_DUMP_FILE=config.yaml
, então aia
descartará a configuração atual config.yaml e sairá toda vez que for executado até que você finalmente unset AIA_DUMP_FILE
Além desses itens de configuração para aia
os parâmetros de linha de comando opcionais para os utilitários de processamento de prompt de backend (mods e sgpt) também podem ser definidos usando envars com o prefixo "AIA_". Por exemplo, "export AIA_TOPP = 1.0" definirá a opção de linha de comando "--topp 1.0" para o utilitário mods
quando for usado como processador backend.
Usar a opção --shell
permite que aia
acesse o ambiente shell do seu terminal a partir do texto do prompt.
aia
pode substituir qualquer referência de variável de ambiente do sistema (envar) no texto do prompt pelo valor do envar. Padrões como
O conteúdo dinâmico pode ser inserido no prompt usando o padrão
Considere o poder de personalizar um prompt para seu sistema operacional específico:
As a system administration on a $(uname -v) platform what is the best way to [DO_SOMETHING]
ou insira conteúdo de um arquivo em seu diretório inicial:
Given the following constraints $(cat ~/3_laws_of_robotics.txt) determine the best way to instruct my roomba to clean my kids room.
Quando você usa a opção --shell
para iniciar uma sessão de bate-papo, a integração do shell fica disponível em seus prompts de acompanhamento. Suponha que você iniciou uma sessão de bate-papo usando um rolo de "Ruby Expert" esperando conversar sobre mudanças que poderiam ser feitas em uma classe específica, MAS você esqueceu de incluir o arquivo fonte da classe como parte do contexto quando começou. Você pode inserir isso como seu prompt de acompanhamento para continuar:
The class I want to chat about refactoring is this one: $(cat my_class.rb)
Isso insere todo o arquivo de origem da classe no prompt de acompanhamento. Você pode continuar conversando com seu Assistente de IA sobre alterações na turma.
A inclusão de conteúdo dinâmico através da integração de shell fornecida pela opção --shell
é significativa. aia
também fornece todo o poder do processamento de código Ruby incorporado no texto do prompt.
A opção --erb
transforma o arquivo de texto do prompt em um modelo ERB totalmente funcional. A sintaxe do modelo Embedded Ruby (ERB) (2024) fornece uma boa visão geral da sintaxe e do poder do ERB.
A maioria dos sites que possuem informações sobre o ERB fornecerão exemplos de como usar o ERB para gerar conteúdo HTML dinâmico para aplicativos baseados na web. Esse é um caso de uso comum para ERB. aia
por outro lado, usa ERB para gerar texto de prompt dinâmico.
Em uma sessão de bate-papo, iniciada pela opção --chat
ou seu equivalente com uma diretiva dentro de um arquivo de texto de prompt, o comportamento é um pouco diferente com sua ligação e atribuições de variáveis locais. Como uma sessão de bate-papo, por definição, possui vários prompts, definir uma variável local em um prompt e esperar que ela esteja disponível em um prompt subsequente não funciona. Você precisa usar variáveis de instância para realizar esse prompt para solicitar a transferência de informações.
Além disso, como se espera que as solicitações de acompanhamento sejam uma única coisa - frase ou parágrafo - terminadas por um único retorno, é provável que o aumento do ERB seja benéfico; mas você pode encontrar uma utilidade para isso.
As diretivas de processamento downstream foram adicionadas ao gem prompt_manager
usado por au
na versão 0.4.1. Essas diretivas são linhas no arquivo de texto do prompt que começam com "//" tendo este padrão:
//command parameters
Não há espaço entre "//" e o comando.
Ao combinar diretivas de prompt com parâmetros de prompt e substituições de envar do shell, você pode obter alguns prompts de composição poderosos.
Aqui está um exemplo de uma diretiva genérica pura.
//[DIRECTIVE_NAME] [DIRECTIVE_PARAMS]
Quando o prompt for executado, você será solicitado a fornecer um valor para cada um dos parâmetros. Você poderia responder "shell" para o nome da diretiva e "calc 22/7" se quisesse uma aproximação ruim do PI.
Experimente este arquivo de prompt:
//shell calc [FORMULA]
What does that number mean to you?
aia
Neste momento aia
possui apenas algumas diretrizes que são detalhadas abaixo.
A diretiva //config
dentro de um arquivo de texto de prompt é usada para personalizar o ambiente de configuração específico do prompt. Todos os itens de configuração estão disponíveis para terem seus valores alterados. A ordem de atribuição de valor para um item de configuração começa com o valor padrão que é substituído pelo valor envar que é substituído pelo valor da opção de linha de comando que é substituído pelo valor do arquivo de configuração.
O //config
é a última e última maneira de alterar o valor de um item de configuração para um prompt específico.
As opções de switch são tratadas como booleanas. Eles são true
ou false
. Seu nome no contexto de uma diretiva //config
sempre termina com um "?" personagem - ponto de interrogação.
Para definir o valor de um switch usando ``//config for example
--terse` ou `--chat` para isto:
//config chat? = true
//config terse? = true
Um item de configuração como --out_file
ou --model
possui um valor associado na linha de comando. Para definir esse valor com a diretiva //config
faça assim:
//config model = gpt-3.5-turbo
//config out_file = temp.md
//config backend = mods
Aliás: o "=" é completamente opcional. Na verdade, é ignorado como ":=" se você escolher isso como seu operador de atribuição. Além disso, o número de espaços entre o item e o valor é totalmente arbitrário. Eu gosto de alinhar as coisas para que esta sintaxe seja igualmente válida:
//config model gpt-3.5-turbo
//config out_file temp.md
//config backend mods
//config chat? true
//config terse? true
//config model gpt-4
NOTA: se você especificar o mesmo nome de item de configuração mais de uma vez no arquivo de prompt, será o último que será definido quando o prompt for finalmente processado por meio do LLM. Por exemplo, no exemplo acima, gpt-4
será o modelo usado. Ser o primeiro não conta neste caso.
Exemplo:
//include path_to_file
O path_to_file
pode ser absoluto ou relativo. Se for relativo, é atribuído à PCD. Se path_to_file
incluir envars, a opção --shell
CLI deverá ser usada para substituir o envar na diretiva por seu valor real.
O arquivo incluído terá quaisquer comentários ou diretivas excluídos. Espera-se que o arquivo seja um arquivo de texto para que seu conteúdo possa ser anexado ao prompt existente; entretanto, se o arquivo for um arquivo de código-fonte (ex: file.rb) o código-fonte será incluído NO ENTANTO, qualquer linha de comentário ou linha que comece com "//" será excluída.
TODO: Considere adicionar uma opção de linha de comando --include_dir
para especificar o local de onde os arquivos relativos virão.
Exemplo:
//ruby any_code_that_returns_an_instance_of_String
Esta diretiva é um complemento ao ERB. Neste ponto, a diretiva //ruby
é limitada pela ligação atual que está dentro do método AIA::Directives#ruby
. Como tal, não é provável que tenha muita utilidade.
No entanto, como foi implementado como um simples eval(code)
existe um potencial para uso como este:
//ruby load(some_ruby_file); execute_some_method
Cada execução de uma diretiva //ruby
será uma nova execução do método AIA::Directives#ruby
, portanto você não pode transportar variáveis locais de uma invocação para outra; entretanto, você poderia fazer algo com variáveis de instância ou variáveis globais. Você pode até adicionar algo ao objeto AIA.config
para ser colado na próxima invocação da diretiva no contexto do mesmo prompt.
Exemplo:
//shell some_shell_command
Espera-se que o comando shell retorne algum texto para STDOUT que será pré-pendente ao texto de prompt existente no arquivo de prompt.
Não há limitações sobre o que o comando shell pode ser. Por exemplo, se você quiser ignorar a remoção de comentários e diretivas de um arquivo, poderá fazer algo assim:
//shell cat path_to_file
Que faz basicamente a mesma coisa que a diretiva //include
, exceto que usa todo o conteúdo do arquivo. Para caminhos de arquivos relativos, o mesmo se aplica. O caminho do arquivo será relativo ao PWD.
Veja o código-fonte das diretivas suportadas pelos backends que neste momento também são baseados em configuração.
Por exemplo, mods
tem um item de configuração topp
que pode ser definido diretamente por uma diretiva em um arquivo de texto de prompt.
//topp 1.5
Se mods
não for o backend, a diretiva //topp
será ignorada.
Quando você estiver em uma sessão de bate-papo, poderá usar uma diretiva como prompt de acompanhamento. Por exemplo, se você iniciou a sessão de chat com a opção --terse
esperando obter respostas curtas do backend; mas, então você decide que deseja respostas mais abrangentes, pode fazer o seguinte:
//config terse? false
A diretiva é executada e um novo prompt de acompanhamento pode ser inserido com uma resposta mais longa gerada no backend.
Por que você precisa/deseja usar uma sequência de prompts em uma situação em lote? Talvez você tenha um prompt complexo que exceda as limitações de token do seu modelo para entrada, então você precisa dividi-lo em várias partes. Ou suponha que seja um prompt simples, mas o número de tokens na saída seja limitado e você não obtenha exatamente o tipo de resposta completa que estava procurando.
Às vezes, são necessárias uma série de solicitações para obter o tipo de resposta desejada. A resposta de um prompt se torna um contexto para o próximo prompt. Isso é fácil de fazer em uma sessão chat
onde você insere e ajusta manualmente seus prompts até obter o tipo de resposta que deseja.
Se precisar fazer isso regularmente ou em lote, você pode usar aia
e as opções de linha de comando --next
e --pipeline
.
Essas duas opções especificam a sequência de IDs de prompt a serem processados. Ambas as opções estão disponíveis para serem usadas em um arquivo de prompt usando a diretiva //config
. Como todas as diretivas incorporadas, você pode aproveitar as vantagens da integração do shell de parametrização e do Ruby. Estou começando a me sentir como o TIm Tool man - mais poder!
Considere a condição em que você tem 4 IDs de prompt que precisam ser processados em sequência. Os IDs e os nomes dos arquivos de prompt associados são:
ID do prompt | Arquivo de prompt |
---|---|
um. | um.txt |
dois. | dois.txt |
três. | três.txt |
quatro. | quatro.txt |
export AIA_OUT_FILE=temp.md
aia one --next two
aia three --next four temp.md
ou dentro de cada um dos arquivos de prompt você usa a diretiva config:
one.txt contains //config next two
two.txt contains //config next three
three.txt contains //config next four
MAS se você tiver mais de dois prompts em sua sequência, considere usar a opção --pipeline.
A diretiva //next é a abreviação de //config next
aia one --pipeline two,three,four
ou dentro do arquivo de prompt one.txt
use esta diretiva:
//config pipeline two,three,four
A diretiva //pipeline é a abreviação de //config pipeline
Como a resposta de um prompt é inserida no próximo prompt da sequência, em vez de todos os prompts gravarem suas respostas no mesmo arquivo de saída, use estas diretivas dentro dos arquivos de prompt associados:
Arquivo de prompt | Diretiva |
---|---|
um.txt | //config out_file one.md |
dois.txt | //config out_file dois.md |
três.txt | //config out_file três.md |
quatro.txt | //config out_file quatro.md |
Dessa forma você pode ver a resposta que foi gerada para cada prompt da sequência.
TODO: o áudio para texto ainda está em desenvolvimento.
Suponha que você tenha um arquivo de áudio de uma reunião. Você deseja obter uma transcrição do que foi dito naquela reunião. Às vezes, as transcrições brutas escondem o valor real da gravação, então você criou uma pompa que pega as transcrições brutas e faz um resumo técnico com uma lista de itens de ação.
Crie dois prompts chamados transcribe.txt e tech_summary.txt
# transcribe.txt
# Desc: takes one audio file
# note that there is no "prompt" text only the directive
//config backend client
//config model whisper-1
//next tech_summary
e
# tech_summary.txt
//config model gpt-4-turbo
//config out_file meeting_summary.md
Review the raw transcript of a technical meeting,
summarize the discussion and
note any action items that were generated.
Format your response in markdown.
Agora você pode fazer isso:
aia transcribe my_tech_meeting.m4a
Seu resumo da reunião está no arquivo meeting_summary.md
Existem dois tipos de prompts
Esse segundo tipo de prompt é chamado de função. Às vezes, a função é incorporada à instrução. Por exemplo, "Como um mágico, faça um coelho sair da cartola." Para reutilizar a mesma função em vários prompts, aia
incentiva você a designar um roles_dir
especial no qual você coloca prompts específicos para personificação - funções.
O roles_dir
padrão é um subdiretório dos papéis nomeados prompts_dir
. Você pode, entretanto, colocar seu roles_dir
em qualquer lugar que faça sentido para você.
A opção --role
é usada para identificar um prompt de personificação em seu diretório de funções que define o contexto no qual o LLM deve fornecer sua resposta. O texto do ID da função é anexado ao texto do prompt principal para formar um prompt completo a ser processado pelo back-end.
Por exemplo, considere:
aia -r ruby refactor my_class.rb
Dentro do diretório de funções, o conteúdo do arquivo de texto ruby.txt
será pré-anexado ao conteúdo do arquivo refactor.txt
do diretório de prompts para produzir um prompt completo. Esse prompt completo terá todos os parâmetros seguidos por diretivas processados antes de enviar o texto do prompt combinado para o backend.
Observe que --role
é apenas uma maneira de adicionar este arquivo de texto de prompt à frente deste outro arquivo de texto de prompt. O conteúdo do prompt “role” pode ser qualquer coisa. Não precisa necessariamente ser uma função real.
aia
suporta totalmente uma árvore de diretórios dentro de prompts_dir
como forma de organização ou classificação de seus diferentes arquivos de texto de prompt.
aia -r sw_eng doc_the_methods my_class.rb
Neste exemplo, o arquivo de texto de prompt $AIA_ROLES_DIR/sw_eng.txt
é anexado ao arquivo de texto de prompt $AIA_PROMPTS_DIR/doc_the_methods.txt
Como aia
suporta prompts parametrizados, você pode fazer com que uma palavra-chave como "[ROLE]" faça parte do seu prompt. Por exemplo, considere este prompt:
As a [ROLE] tell me what you think about [SUBJECT]
Quando este prompt for processado, aia
solicitará um valor para a palavra-chave "ROLE" e a palavra-chave "SUBJECT" para completar o prompt. Como aia
mantém um histórico de suas respostas anteriores, você pode simplesmente escolher algo que usou no passado ou responder com um valor completamente novo.
Para instalar os programas CLI externos usados pela aia:
preparar instalar fzf mods rg brilho
fzf Localizador difuso de linha de comando escrito em Go https://github.com/junegunn/fzf
mods AI na linha de comando https://github.com/charmbracelet/mods
Ferramenta de pesquisa rg como grep e The Silver Searcher https://github.com/BurntSushi/ripgrep
marcação de renderização de brilho na CLI https://github.com/charmbracelet/glow
Um editor de texto cujo executável é configurado na variável de ambiente do sistema 'EDITOR' assim:
exportar EDITOR = "subl -w"
llm
llm Access large language models from the command-line
| brew install llm
|__ https://llm.datasette.io/
A partir aia v0.5.13
o processador backend llm
está disponível em uma integração limitada. É uma implementação muito poderosa baseada em python que possui seu próprio sistema de modelos de prompt. A razão pela qual foi incluído no ambiente aia
é sua capacidade de fazer uso de modelos LLM locais.
sgpt
shell-gpt
também conhecido como sgpt
também é uma implementação python de uma ferramenta CLI que processa prompts por meio do OpenAI. Possui menos recursos que mods
e llm
e é menos flexível.
plz
plz-cli
também conhecido como plz
não está integrado ao aia
, no entanto, recebe uma menção honrosa por sua capacidade de excluir um prompt adaptado para fazer algo na linha de comando. Sua resposta é um comando CLI (às vezes uma sequência canalizada) que realiza a tarefa definida no prompt. Ele retornará os comandos a serem executados nos arquivos de dados que você especificou com uma consulta para executar o comando.
Você pode configurar uma função de conclusão em seu shell que será concluída no prompt_id salvo em seu prompts_dir
- funções para bash
, fish
e zsh
estão disponíveis. Para obter uma cópia dessas funções, faça o seguinte:
aia --completion bash
Se você não é fã de "nascer de novo", substitua bash
por um dos outros.
Copie a função para um local onde ela possa ser instalada na instância do seu shell. Pode ser um arquivo .profile
ou .bashrc
, etc.
Isso é apenas entre você e eu, então não fique contando isso para todo mundo. Meu prompt mais poderoso está em um arquivo chamado ad_hoc.txt
. Parece assim:
[O QUE AGORA HUMANO]
Sim. Apenas um único parâmetro para o qual posso fornecer o valor de qualquer coisa que esteja em minha mente no momento. Sua vantagem é que não poluo o histórico de comandos do meu shell com muito texto.
O que você acha melhor ter no arquivo de histórico do seu shell?
mods " As a certified public accountant specializing in forensic audit and analysis of public company financial statements, what do you think of mine? What is the best way to hide the millions dracma that I've skimmed? " < financial_statement.txt
ou
aia ad_hoc financial_statement.txt
Ambos fazem a mesma coisa; entretanto, aia
não coloca o texto do prompt no arquivo de histórico do shell... é claro que o valor da palavra-chave/parâmetro é salvo no arquivo JSON do prompt e o prompt com a resposta é registrado, a menos que --no-log
seja especificado ; mas não está atrapalhando o histórico do shell!
Eu uso o shell bash
. No meu arquivo .bashrc
eu forneço outro arquivo chamado .bashrc__aia
que se parece com isto:
# ~/.bashic_aia
# AI Assistant
# These are the defaults:
export AIA_PROMPTS_DIR= ~ /.prompts
export AIA_OUT_FILE=./temp.md
export AIA_LOG_FILE= $AIA_PROMPTS_DIR /_prompts.log
export AIA_BACKEND=mods
export AIA_MODEL=gpt-4-1106-preview
# Not a default. Invokes spinner.
export AIA_VERBOSE=true
alias chat= ' aia chat --terse '
# rest of the file is the completion function
Esta é a aparência do meu arquivo de prompt chat
:
# ~/.prompts/chat.txt
# Desc: Start a chat session
//config chat ? = true
[WHAT]
Esta ferramenta CLI começou como algumas linhas de Ruby em um arquivo em meu repositório de scripts. Continuei crescendo conforme decidi adicionar mais recursos e mais ferramentas de back-end. Não havia arquitetura real para guiar o design. O que sobrou foi uma grande bagunça de código que está sendo lentamente refatorada em algo mais sustentável. Esse trabalho está ocorrendo no ramo develop
. Congratulo-me com sua ajuda. Dê uma olhada no que está acontecendo naquele ramo e me envie um PR contra isso.
Claro que se você vir algo no branch principal me envie um PR contra aquele para que possamos resolver o problema para todos.
Relatórios de bugs e solicitações pull são bem-vindos no GitHub em https://github.com/MadBomber/aia.
Quando você encontrar problemas com aia
, anote-os como um problema. Esta coisa foi escrita principalmente por um humano e você sabe como os humanos são propensos a erros. Deve haver muitos erros para encontrar.
Não estou satisfeito com a maneira como algumas opções de linha de comando para comandos externos são codificadas. Estou falando especificamente sobre a maneira como as ferramentas rg
e fzf
são usadas. Essas opções decidem a aparência básica do recurso de pesquisa na linha de comando. Talvez eles devessem fazer parte da configuração geral para que os usuários possam ajustar sua IU da maneira que desejarem.
A gema está disponível como código aberto sob os termos da licença MIT.