Você não gosta de ler as mensagens de compromisso de outras pessoas? Não? Bem, eu gosto e, enquanto lia uma mensagem de confirmação muito perspicaz, percebi todo o conteúdo inexplorado que existe em vários logs do Git (supondo que o desenvolvedor que você segue esteja escrevendo mensagens úteis, é claro). Então, não seria ótimo se você pudesse fazer perguntas a um repositório? Vamos ver como isso pode ser feito usando o RAG com o Couchbase Shell.
TL;DR
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# com bash, extraia seu histórico de commits para json fonte git-registro-json.sh && git-registro-json > registro de compromisso.json # com cbsh, criar escopo, coleção e índice primário de coleção escopos criar gitlog; cb-env escopo gitlog;coleções criar compromissos; cb-env coleção compromissos; consulta "CREATE PRIMARY INDEX ON `default`:`cbsh`.`gitlog`.`commits`" # Importar o documento na coleção selecionada aberto registro de compromisso.json | envoltório conteúdo | inserir id { |ele| eco $it.conteúdo.commitHash } | doc upsert # Enriqueça o documento com o modelo padrão consulta "SELECT c.*, meta().id as id, c.subject || ' ' || c.body as text FROM `commits` as c" | envoltório conteúdo| vetor enriquecer-doc texto | doc upsert # Criar um índice vetorial vetor criar-índice --similaridade-métrica ponto_produto compromissos textVector 1536 # Executar RAG vetor enriquecer-texto "gêmeos" | vetor pesquisa compromissos textVector --vizinhos 20| selecionar id |doc obter| selecionar conteúdo | rejeitar -i conteúdo.textVector | par-cada {|x| para json} | envoltório conteúdo| perguntar "Quando e em qual commit foi adicionado o suporte ao gemini llm" |
Configuração do Couchbase Shell
A etapa inicial é instalar e configurar o cbsh. Vou usar minha instância do Capella. Para obter a configuração, você pode acessar a seção Conectar de seu cluster do Capella e selecione Shell do Couchbase. Esta é a configuração em [[cluster]]. Para configurar o modelo, dê uma olhada no que está em [[llm]]. Eu escolhi o OpenAI, mas há outros. Você precisa definir o modelo usado para a incorporação (que é o que transforma o texto em um vetor) e um para o Chat. Esse modelo recebe a pergunta e algum contexto adicional para responder à pergunta. E, é claro, você precisará de uma chave de API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
versão = 1 [[llm]] identificador = "OpenAI" provedor = "OpenAI" incorporar_modelo = "text-embedding-3-small" bate-papo_modelo = "gpt-3.5-turbo" API_chave = "sk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" [[cluster]] identificador = "capella" conector = "couchbases://cb.xxxxxxx.cloud.couchbase.com" nome de exibição do usuário = "Laurent Doguin" nome de usuário = "USUÁRIO" senha = "PASSWORD" cesto padrão = "cbsh" escopo padrão = "gitlog" |
Você também precisa ter o Git instalado e, então, estará tudo pronto.
Importar o registro de confirmação do Git
A primeira etapa é obter todos os commits do repositório em JSON. Por ser preguiçoso e velho, e por velho quero dizer que não estou acostumado a perguntar a uma IA, pesquisei isso no Google, encontrei vários Gists com links para outros Gists e, por fim, resolvi neste caso.
Eu o baixei, fiz o sourcing, entrei no meu repositório git local do couchbase-shell e o chamei.
1 |
fonte git-registro-json.sh && git-registro-json > registro de compromisso.json |
Mas, para que o leitor se pergunte se tomei a decisão certa, vamos perguntar ao modelo configurado. A Cbsh tem um perguntar permitindo que você faça isso:
1 2 3 4 5 6 |
👤 Laurent Doguin 🏠 capela em ☁️ cbsh.gitlog.commits > perguntar "obter os commits completos em json para um repositório git" Para obter o completo compromissos em a Git repositório como JSON, você pode uso o seguintes comando: git registro --bonito=formato:'{%n "commit": "%H",%n "author": "%an <%ae>",%n "date": "%ad",%n "message": "%f"%n},' --data=iso --reverso --todos > compromissos.json |
Esse comando produzirá cada commit no repositório como um objeto JSON com o hash do commit, o nome e o e-mail do autor, a data do commit e a mensagem do commit. O --tudo
garante que todas as ramificações sejam incluídas. A bandeira --reverso
lista os commits em ordem cronológica inversa. Por fim, a saída é redirecionada para um arquivo commits.json
arquivo.
Certifique-se de executar esse comando no diretório raiz do repositório Git do qual você deseja obter os commits.
E, como se vê, ele não funciona imediatamente (chocante, eu sei). E não tinha todas as informações de que eu precisava, como a parte do corpo da mensagem. É claro que poderíamos gastar tempo ajustando isso, mas é muito específico, com muitos casos extremos.
De qualquer forma, agora tenho uma lista de commits no formato JSON:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
[ { .... }, { "autor": { "name" (nome): "Michael Nitschinger", "email": "michael@nitschinger.at", "data": "Thu, 20 Feb 2020 21:29:20 +0100", "dateISO8601": "2020-02-20T21:29:20+01:00" }, "corpo": "", "commitHash": "7a0d269fffd10045a63d40ca460deba944531890", "commitHashAbbreviated": "7a0d269", "committer": { "name" (nome): "Michael Nitschinger", "email": "michael@nitschinger.at", "data": "Thu, 20 Feb 2020 21:29:20 +0100", "dateISO8601": "2020-02-20T21:29:20+01:00" }, "encoding" (codificação): "", "notas": "", "pai": "", "parentAbbreviated": "", "refs": "", "assinatura": { "chave": "A6BCCB72D65B0D0F", "signatário": "", "verificationFlag": "E" }, "assunto": "Compromisso inicial", "subjectSanitized": "Initial-commit" (Compromisso inicial), "árvore": "3db442f3ef0438de58f72235e2658e5368a6752b", "treeAbbreviated": "3db442f" }] |
Então, o que você pode fazer com uma matriz JSON de objetos JSON? Você pode importá-lo por meio da interface do usuário do Capella ou importá-lo com o Couchbase Shell. Primeiro, eu crio o array escopo e coleção e selecioná-los com cb-env e, em seguida, criar o índice SQL++.
1 |
escopos criar gitlog; cb-env escopo gitlog; coleções criar compromissos; cb-env coleção compromissos; consulta "CREATE PRIMARY INDEX ON `default`:`cbsh`.`gitlog`.`commits`" |
Como o cbsh é baseado no Nushell, o arquivo JSON resultante pode ser facilmente aberto, transformado em um dataframe, transformado em um documento do Couchbase e inserido dessa forma:
1 2 3 4 5 6 7 8 |
👤 Laurent Doguin 🏠 capela em ☁️ cbsh.gitlog.compromissos > aberto registro de compromisso.json |envoltório conteúdo | inserir id { |ele| eco $ele.conteúdo.commitHash }| doc upsert ╭───┬───────────┬─────────┬────────┬──────────┬─────────╮ │ # │ processado │ sucesso │ falha │ falhas │ cluster │ ├───┼───────────┼─────────┼────────┼──────────┼─────────┤ │ 0 │ 660 │ 660 │ 0 │ │ capela │ │ ╰───┴───────────┴─────────┴────────┴──────────┴─────────╯ |
Vamos obter alguns documentos só para ver como funcionou:
1 2 3 4 5 6 7 |
👤 Laurent Doguin 🏠 capela em ☁️ cbsh.gitlog.compromissos > consulta "SELECT subject, body FROM `commits` LIMIT 1" ╭───┬──────────────┬──────┬─────────╮ │ # │ sujeito │ corpo │ cluster │ ├───┼──────────────┼──────┼─────────┤ │ 0 │ Bump Nushell │ │ capela │ ╰───┴──────────────┴──────┴─────────╯ |
Portanto, esse é o conteúdo que poderíamos usar para o RAG. É hora de enriquecer esses documentos.
Enriqueça o documento com um modelo de IA
Para enriquecer o documento, você precisa ter um modelo configurado. Aqui estou usando o OpenAI e o enriquecer-doc comando cbsh:
1 2 3 4 5 6 7 8 |
👤 Laurent Doguin 🏠 capela em ☁️ cbsh.gitlog.compromissos > consulta "SELECT c.*, meta().id as id, c.subject || ' ' || c.body as text FROM `commits` as c" | envoltório conteúdo| vetor enriquecer-doc texto | doc upsert Incorporação lote 1/1 ╭───┬───────────┬─────────┬────────┬──────────┬─────────╮ │ # │ processado │ sucesso │ falha │ falhas │ cluster │ ├───┼───────────┼─────────┼────────┼──────────┼─────────┤ │ 0 │ 61 │ 61 │ 0 │ │ capela │ ╰───┴───────────┴─────────┴────────┴──────────┴─────────╯ |
A cláusula SELECT retornará um objeto JSON com o conteúdo do documento e campos adicionais id e texto. O texto é o assunto e o corpo anexados em uma única string. O objeto é agrupado em um objeto de conteúdo e fornecido ao vetor enriquecer-doc com texto como parâmetro, pois esse é o campo que será transformado em um vetor. Agora deve haver um textVector em cada documento.
Pesquisa de vetores
Para pesquisar esses vetores, precisamos criar um índice Vector Search. Isso pode ser feito por meio da API ou da interface do usuário para algo personalizável. Aqui, estou satisfeito com as opções padrão e, por isso, uso o cbsh:
1 2 |
👤 Laurent Doguin 🏠 capela em ☁️ cbsh.gitlog.compromissos > vetor criar-índice --similaridade-métrica ponto_produto compromissos textVector 1536 |
O índice criado usará ponto_produto como um algoritmo de similaridade, a dimensionalidade do vetor será de 1536, o nome do índice é comprometer e o campo indexado é textVector. O bucket, o escopo e a coleção são os selecionados por meio de cb-env.
Para testar a pesquisa vetorial, a consulta de pesquisa deve ser transformada em um vetor e depois canalizada para a pesquisa:
1 2 3 4 5 6 7 8 9 10 |
👤 Laurent Doguin 🏠 capela em ☁️ cbsh.gitlog.compromissos > vetor enriquecer-texto "Suporte a TLS" | vetor pesquisa compromissos textVector Incorporação lote 1/1 ╭───┬──────────────────────────────────────────┬────────────┬─────────╮ │ # │ id │ score │ cluster │ ├───┼──────────────────────────────────────────┼────────────┼─────────┤ │ 0 │ f2c1f124269884c88ab3925c7c5a8914298a2fbc │ 0.37283808 │ capela │ │ 1 │ da28adf7adbe910cd06c960d9c25d7316d666d1c │ 0.33915368 │ capela │ │ 2 │ f0f82353e7c060030cc2511ffab1edbcc263d099 │ 0.3294143 │ capela │ ╰───┴──────────────────────────────────────────┴────────────┴─────────╯ |
Ele retorna 3 linhas por padrão. Vamos estendê-lo para ver o conteúdo do documento. Estou adicionando rejeitar -i textVector
para remover o campo vetorial, pois ninguém precisa de um campo de 1536 linhas na saída do terminal:
Pergunte ao seu repositório Git
A partir daí, você tem todos os commits de um repositório Git armazenados no Couchbase, enriquecidos com um modelo de IA, e todos indexados e pesquisáveis. A última coisa a fazer é chamar o modelo para executar uma consulta com o RAG. Ele começa transformando uma pergunta em um vetor, canaliza-a para uma pesquisa de vetor, obtém o documento completo a partir dos IDs de retorno, seleciona o objeto de conteúdo sem o campo de vetor, transforma cada objeto em um documento JSON (dessa forma, podemos enviar o conteúdo e seus metadados estruturados), envolve o jsonText em uma tabela e, por fim, canalizá-lo para o perguntar comando:
1 2 3 4 5 6 7 8 9 10 11 12 |
👤 Laurent Doguin 🏠 capela em ☁️ cbsh.gitlog.compromissos > vetor enriquecer-texto "gêmeos" | vetor pesquisa compromissos textVector --vizinhos 10| selecionar id |doc obter| selecionar conteúdo | rejeitar -i conteúdo.textVector | par-cada {|x| para json} | envoltório conteúdo| perguntar "Quando e em qual commit foi adicionado o suporte ao gemini llm" Incorporação lote 1/1 Gêmeos LLM suporte foi adicionado em o comprometer com o assunto "Adicionar suporte para o Gemini llm". Isso comprometer foi autoria por Jack Westwood em Maio 15, 2024, com o comprometer hash "3da9b4a3532ab4f432428319361909cc14a035af". 👤 Laurent Doguin 🏠 capela em ☁️ cbsh.gitlog.compromissos > git show 3da9b4a3532ab4f432428319361909cc14a035af comprometer 3da9b4a3532ab4f432428319361909cc14a035af Autor: Jack Westwood <macaco.Westwood@couchbase.com> Data: Quarta Maio 15 15:40:13 2024 +0100 Adicionar suporte para Gêmeos lm .... |
Perguntar ao LLM quando o suporte ao Gemini foi introduzido. Obtemos uma data e um hash de confirmação. Assim, é fácil verificar usando git show
. Há um pouco de repetição aqui, portanto, você pode declarar uma variável para sua pergunta e reutilizá-la:
1 2 3 4 |
👤 Laurent Doguin 🏠 capela em ☁️ cbsh.gitlog.compromissos > deixar pergunta = "Por que a base do cliente foi reescrita? "; vetor enriquecer-texto $pergunta | vetor pesquisa compromissos textVector --vizinhos 10| selecionar id |doc obter| selecionar conteúdo | rejeitar -i conteúdo.textVector | par-cada {|x| para json} | envoltório conteúdo| perguntar $pergunta Incorporação lote 1/1 O cliente caixote foi reescrito para endereço problemas tais como inconsistência, dificuldade em uso, e código organização. O reescrever dividir o cliente em chave-valor (kv) e HTTP clientes, cada consumindo a comum HTTP manipulador. Isso separação em múltiplos clientes e arquivos aprimorado código organização e feito o clientes mais fácil para entender e uso. Adicionalmente, diversos melhorias foram feito para o HTTP manipulador, erros, e tempo de execução instanciação dentro de o cliente caixote para aprimorar geral funcionalidade e desempenho. O reescrever esforço destinado para simplificar o cliente caixote, fazendo ele mais robusto, sustentável, e usuário-amigável. |
E agora todos nós sabemos por que a grade do cliente teve de ser reescrita. Talvez isso não responda às suas perguntas, mas agora você sabe como obter respostas de qualquer repositório!
-
- Comece a usar Capella de graça
- Leia nosso Guia para LLM Embeddings
- Leia mais sobre meus blogs de desenvolvedores sobre pesquisa de vetores e muito mais
- Tente Shell do Couchbase hoje
Muito legal. Seria interessante incluir o registro de alterações completo, para dar mais contexto ao LLM.
Sim, eu também estava pensando no Github PR. Há muito potencial!