Las revisiones de código siempre han sido cruciales para mantener altos estándares y reforzar las mejores prácticas en un proyecto de codificación. Esta no es una publicación sobre cómo los desarrolladores deberían revisar el código, sino más bien sobre delegar una parte de este a la IA. Como menciona Michael Lynch en su artículo , deberíamos de la revisión de código. Si bien Michael hace hincapié en una herramienta de formato, me gustaría dar un paso más y dejar que la inteligencia artificial se encargue de ello. Es decir, ¿por qué no aprovechar el auge de la IA en la industria? "Cómo hacer revisiones de código como un ser humano" dejar que las computadoras se encarguen de las partes aburridas Ahora bien, no estoy diciendo que la IA deba utilizarse en lugar de herramientas de formato y depuradores. En cambio, debe utilizarse además de eso, para detectar cosas triviales que un humano podría pasar por alto. Por eso, decidí crear una cuyo código revisa una diferencia de una solicitud de extracción y genera sugerencias utilizando IA. Déjame explicarte cómo hacerlo. acción de GitHub 🚨 NOTA: Esta acción de GitHub ahora está disponible en el . mercado de GitHub Es una acción de javascript: obtenga más información sobre . cómo crear acciones de javascript en Github Obteniendo la diferencia Para interactuar con la API de Github, he utilizado , que es una especie de SDK o una de forma idiomática. octokit biblioteca cliente para interactuar con la API de Github Para que pueda obtener la diferencia de la solicitud de extracción generada, debe pasar el encabezado con el valor junto con los parámetros requeridos. Accept application/vnd.github.diff async function getPullRequestDetails(octokit, { mode }) { let AcceptFormat = "application/vnd.github.raw+json"; if (mode === "diff") AcceptFormat = "application/vnd.github.diff"; if (mode === "json") AcceptFormat = "application/vnd.github.raw+json"; return await octokit.rest.pulls.get({ owner: github.context.repo.owner, repo: github.context.repo.repo, pull_number: github.context.payload.pull_request.number, headers: { accept: AcceptFormat, }, }); } Si no está familiarizado en absoluto con las acciones de Github, aquí hay una y es un buen comienzo. serie de acciones de Github 101 de Victoria Lo Una vez que obtengo la diferencia, la analizo y elimino los cambios no deseados y luego la devuelvo en un esquema que se muestra a continuación: /** using zod */ schema = z.object({ path: z.string(), position: z.number(), line: z.number(), change: z.object({ type: z.string(), add: z.boolean(), ln: z.number(), content: z.string(), relativePosition: z.number(), }), previously: z.string().optional(), suggestions: z.string().optional(), }) Ignorar archivos Ignorar archivos es bastante sencillo. La lista de entrada del usuario requiere una cadena de patrones glob separados por punto y coma. Luego se analiza, se concatena con la lista predeterminada de archivos ignorados y se eliminan los duplicados. **/*.md; **/*.env; **/*.lock; const filesToIgnoreList = [ ...new Set( filesToIgnore .split(";") .map(file => file.trim()) .filter(file => file !== "") .concat(FILES_IGNORED_BY_DEFAULT) ), ]; La lista de archivos ignorados se utiliza luego para eliminar los cambios de diferencias que hacen referencia a esos archivos ignorados. Esto le proporciona una carga útil sin procesar que contiene solo los cambios que desea. Generando sugerencias Una vez que obtengo la carga útil sin procesar después de analizar la diferencia, la paso a la API de la plataforma. Aquí se muestra una implementación de la API de OpenAI. async function useOpenAI({ rawComments, openAI, rules, modelName, pullRequestContext }) { const result = await openAI.beta.chat.completions.parse({ model: getModelName(modelName, "openai"), messages: [ { role: "system", content: COMMON_SYSTEM_PROMPT, }, { role: "user", content: getUserPrompt(rules, rawComments, pullRequestContext), }, ], response_format: zodResponseFormat(diffPayloadSchema, "json_diff_response"), }); const { message } = result.choices[0]; if (message.refusal) { throw new Error(`the model refused to generate suggestions - ${message.refusal}`); } return message.parsed; } Es posible que notes el uso del formato de respuesta en la implementación de la API. Esta es una característica que ofrecen muchas plataformas LLM y que te permite indicarle al modelo que genere la respuesta en un esquema o formato específico. Es especialmente útil en este caso, ya que no quiero que el modelo alucine y genere sugerencias de archivos o posiciones incorrectos en la solicitud de extracción, o que agregue nuevas propiedades a la carga útil de la respuesta. El mensaje del sistema está ahí para darle al modelo más contexto sobre cómo debe hacer la revisión del código y qué cosas hay que tener en cuenta. Puedes ver el mensaje del sistema aquí . El mensaje del usuario contiene la diferencia real, las reglas y el contexto de la solicitud de incorporación de cambios. Es lo que da inicio a la revisión del código. github.com/murtuzaalisurti/better Esta acción de GitHub es compatible con los modelos OpenAI y Anthropic. Así es como implementa la API de Anthropic: async function useAnthropic({ rawComments, anthropic, rules, modelName, pullRequestContext }) { const { definitions } = zodToJsonSchema(diffPayloadSchema, "diffPayloadSchema"); const result = await anthropic.messages.create({ max_tokens: 8192, model: getModelName(modelName, "anthropic"), system: COMMON_SYSTEM_PROMPT, tools: [ { name: "structuredOutput", description: "Structured Output", input_schema: definitions["diffPayloadSchema"], }, ], tool_choice: { type: "tool", name: "structuredOutput", }, messages: [ { role: "user", content: getUserPrompt(rules, rawComments, pullRequestContext), }, ], }); let parsed = null; for (const block of result.content) { if (block.type === "tool_use") { parsed = block.input; break; } } return parsed; } Añadiendo comentarios Finalmente, después de recuperar las sugerencias, las limpio y las paso a la API de GitHub para agregar comentarios como parte de la revisión. Elegí la siguiente forma de agregar comentarios porque al crear una nueva reseña, puedes agregar todos los comentarios de una sola vez en lugar de agregar un solo comentario a la vez. Agregar comentarios uno por uno también puede activar la limitación de velocidad porque agregar comentarios activa las notificaciones y no quieres enviarles spam a los usuarios con notificaciones. function filterPositionsNotPresentInRawPayload(rawComments, comments) { return comments.filter(comment => rawComments.some(rawComment => rawComment.path === comment.path && rawComment.line === comment.line) ); } async function addReviewComments(suggestions, octokit, rawComments, modelName) { const { info } = log({ withTimestamp: true }); // eslint-disable-line no-use-before-define const comments = filterPositionsNotPresentInRawPayload(rawComments, extractComments().comments(suggestions)); try { await octokit.rest.pulls.createReview({ owner: github.context.repo.owner, repo: github.context.repo.repo, pull_number: github.context.payload.pull_request.number, body: `Code Review by ${modelName}`, event: "COMMENT", comments, }); } catch (error) { info(`Failed to add review comments: ${JSON.stringify(comments, null, 2)}`); throw error; } } Conclusión Quería mantener la acción de GitHub abierta y abierta a integraciones y es por eso que puedes usar cualquier modelo de tu elección , o puedes ajustar y crear tu propio modelo personalizado sobre los modelos base compatibles y usarlo con esta acción de GitHub. (consulta la lista de ) modelos compatibles Si encuentra algún , es posible que desee actualizar los límites de su modelo consultando la documentación de la plataforma respectiva. problema con el token o limitación de velocidad Entonces, ¿qué estás esperando? Si tienes un repositorio en GitHub, prueba la acción ahora: está en el . mercado de acciones de GitHub