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 |
# with bash, extract your commit history to json source git-log-json.sh && git-log-json > commitlog.json # with cbsh, create scope, collection and collection Primary Index scopes create gitlog; cb-env scope gitlog;collections create commits; cb-env collection commits; query "CREATE PRIMARY INDEX ON `default`:`cbsh`.`gitlog`.`commits`" # Import the doc in selected collection open commitlog.json | wrap content | insert id { |it| echo $it.content.commitHash } | doc upsert # Enrich the document with default model query "SELECT c.*, meta().id as id, c.subject || ' ' || c.body as text FROM `commits` as c" | wrap content| vector enrich-doc text | doc upsert # Create a Vector Index vector create-index --similarity-metric dot_product commits textVector 1536 # Run RAG vector enrich-text "gemini" | vector search commits textVector --neighbors 20| select id |doc get| select content | reject -i content.textVector | par-each {|x| to json} | wrap content| ask "when and in which commit was gemini llm support added" |
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 |
version = 1 [[llm]] identifier = "OpenAI" provider = "OpenAI" embed_model = "text-embedding-3-small" chat_model = "gpt-3.5-turbo" api_key = "sk-proj-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" [[cluster]] identifier = "capella" connstr = "couchbases://cb.xxxxxxx.cloud.couchbase.com" user-display-name = "Laurent Doguin" username = "USER" password = "PASSWORD" default-bucket = "cbsh" default-scope = "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 |
source git-log-json.sh && git-log-json > commitlog.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 🏠 capella in ☁️ cbsh.gitlog.commits > ask "get the full commits in json for a git repo" To get the full commits in a Git repository as JSON, you can use the following command: git log --pretty=format:'{%n "commit": "%H",%n "author": "%an <%ae>",%n "date": "%ad",%n "message": "%f"%n},' --date=iso --reverse --all > commits.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 |
[ { .... }, { "author": { "name": "Michael Nitschinger", "email": "michael@nitschinger.at", "date": "Thu, 20 Feb 2020 21:29:20 +0100", "dateISO8601": "2020-02-20T21:29:20+01:00" }, "body": "", "commitHash": "7a0d269fffd10045a63d40ca460deba944531890", "commitHashAbbreviated": "7a0d269", "committer": { "name": "Michael Nitschinger", "email": "michael@nitschinger.at", "date": "Thu, 20 Feb 2020 21:29:20 +0100", "dateISO8601": "2020-02-20T21:29:20+01:00" }, "encoding": "", "notes": "", "parent": "", "parentAbbreviated": "", "refs": "", "signature": { "key": "A6BCCB72D65B0D0F", "signer": "", "verificationFlag": "E" }, "subject": "Initial commit", "subjectSanitized": "Initial-commit", "tree": "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 |
scopes create gitlog; cb-env scope gitlog; collections create commits; cb-env collection commits; query "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 🏠 capella in ☁️ cbsh.gitlog.commits > open commitlog.json |wrap content | insert id { |it| echo $it.content.commitHash }| doc upsert ╭───┬───────────┬─────────┬────────┬──────────┬─────────╮ │ # │ processed │ success │ failed │ failures │ cluster │ ├───┼───────────┼─────────┼────────┼──────────┼─────────┤ │ 0 │ 660 │ 660 │ 0 │ │ capella │ │ ╰───┴───────────┴─────────┴────────┴──────────┴─────────╯ |
Vamos obter alguns documentos só para ver como funcionou:
|
1 2 3 4 5 6 7 |
👤 Laurent Doguin 🏠 capella in ☁️ cbsh.gitlog.commits > query "SELECT subject, body FROM `commits` LIMIT 1" ╭───┬──────────────┬──────┬─────────╮ │ # │ subject │ body │ cluster │ ├───┼──────────────┼──────┼─────────┤ │ 0 │ Bump Nushell │ │ capella │ ╰───┴──────────────┴──────┴─────────╯ |
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 🏠 capella in ☁️ cbsh.gitlog.commits > query "SELECT c.*, meta().id as id, c.subject || ' ' || c.body as text FROM `commits` as c" | wrap content| vector enrich-doc text | doc upsert Embedding batch 1/1 ╭───┬───────────┬─────────┬────────┬──────────┬─────────╮ │ # │ processed │ success │ failed │ failures │ cluster │ ├───┼───────────┼─────────┼────────┼──────────┼─────────┤ │ 0 │ 61 │ 61 │ 0 │ │ capella │ ╰───┴───────────┴─────────┴────────┴──────────┴─────────╯ |
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 🏠 capella in ☁️ cbsh.gitlog.commits > vector create-index --similarity-metric dot_product commits 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 🏠 capella in ☁️ cbsh.gitlog.commits > vector enrich-text "TLS support" | vector search commits textVector Embedding batch 1/1 ╭───┬──────────────────────────────────────────┬────────────┬─────────╮ │ # │ id │ score │ cluster │ ├───┼──────────────────────────────────────────┼────────────┼─────────┤ │ 0 │ f2c1f124269884c88ab3925c7c5a8914298a2fbc │ 0.37283808 │ capella │ │ 1 │ da28adf7adbe910cd06c960d9c25d7316d666d1c │ 0.33915368 │ capella │ │ 2 │ f0f82353e7c060030cc2511ffab1edbcc263d099 │ 0.3294143 │ capella │ ╰───┴──────────────────────────────────────────┴────────────┴─────────╯ |
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 🏠 capella in ☁️ cbsh.gitlog.commits > vector enrich-text "gemini" | vector search commits textVector --neighbors 10| select id |doc get| select content | reject -i content.textVector | par-each {|x| to json} | wrap content| ask "when and in which commit was gemini llm support added" Embedding batch 1/1 Gemini LLM support was added in the commit with the subject "Add support for Gemini llm". This commit was authored by Jack Westwood on May 15, 2024, with the commit hash "3da9b4a3532ab4f432428319361909cc14a035af". 👤 Laurent Doguin 🏠 capella in ☁️ cbsh.gitlog.commits > git show 3da9b4a3532ab4f432428319361909cc14a035af commit 3da9b4a3532ab4f432428319361909cc14a035af Author: Jack Westwood <jack.westwood@couchbase.com> Date: Wed May 15 15:40:13 2024 +0100 Add support for Gemini llm .... |
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 🏠 capella in ☁️ cbsh.gitlog.commits > let question = "why was the client crate rewritten? "; vector enrich-text $question | vector search commits textVector --neighbors 10| select id |doc get| select content | reject -i content.textVector | par-each {|x| to json} | wrap content| ask $question Embedding batch 1/1 The client crate was rewritten to address issues such as inconsistency, difficulty in usage, and code organization. The rewrite split the client into key-value (kv) and HTTP clients, each consuming a common HTTP handler. This separation into multiple clients and files improved code organization and made the clients easier to understand and use. Additionally, various improvements were made to the HTTP handler, errors, and runtime instantiation within the client crate to enhance overall functionality and performance. The rewrite effort aimed to streamline the client crate, making it more robust, maintainable, and user-friendly. |
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!