Estrategia rápida: diseño de búsqueda semántica del asistente de IA de base de código

La semana pasada, para construir mejor el marco del Agente AI Chocolate Factory (en lo sucesivo, CF), agregamos una nueva aplicación: Code Base AI Assistant.

Durante el diseño, para proporcionar mejor esta capacidad en la parte inferior del marco, consultamos el código y las ideas de las aplicaciones Bloop, LangChain, Spring AI, el marco LlamaIndex, etc., y hicimos referencia/copiamos parte de la implementación VectorStore de LangChain4j ( basado en el protocolo Apache 2.0).

Para obtener más detalles, consulte la base del código: https://github.com/unit-mesh/chocolate-factory .

Para obtener documentación detallada, consulte: https://framework.unitmesh.cc/ .

Vídeo de demostración ver:

Introducción: Asistente de IA de Codebase

Primero, dejemos que ChatGPT resuma según nuestro material: ¿Qué es el código base del asistente de IA? Responsable de leer y formatear los datos para que se divida en partes adecuadas para su almacenamiento en la base de datos.

Los asistentes de Codebase AI son herramientas inteligentes, que a menudo utilizan procesamiento de lenguaje natural y técnicas de aprendizaje automático, diseñadas para ayudar a los desarrolladores a administrar y comprender grandes bases de código de manera más eficiente. Estos asistentes pueden responder preguntas sobre la base del código, proporcionar documentación, buscar el código, identificar la fuente de errores, reducir la duplicación de código, etc., mejorando así la eficiencia del desarrollo, reduciendo las tasas de error y reduciendo la carga de trabajo de los desarrolladores.

Su objetivo de diseño es acelerar el proceso de desarrollo de software permitiendo a los desarrolladores interactuar con el código base de una manera más intuitiva y natural, reduciendo las tediosas tareas de codificación y búsqueda de documentos.

En pocas palabras, los usuarios plantean preguntas directamente y continúan con tareas posteriores basadas en la implementación de la lógica empresarial existente, como por ejemplo: ¿Cómo se cumplen los requisitos? Analizar la relación con el código en función de errores y brindar sugerencias de reparación.

Veamos primero un ejemplo:

Ejemplo de preguntas y respuestas del asistente de IA de base de código

Pregunta: ¿Cómo se implementa el flujo de trabajo semántico?

ChatGPT devuelve la respuesta según el código verificado por CF:

Según el código proporcionado, podemos ver que CodeSemanticWorkflow es una clase heredada de Workflow, que implementa el método de ejecución para realizar la búsqueda de código semántico.

En el método de ejecución, primero crea un objeto ElasticsearchStore y obtiene el contenido del último mensaje del usuario como pregunta. Luego analiza el problema utilizando un objeto SemanticProblemAnalyzer, que utiliza un llmProvider para completar el análisis del problema. A continuación, utiliza el objeto SemanticSolutionExecutor para realizar una búsqueda de código semántico y convierte los resultados en un Flowable. Finalmente, llama al método toFlowableResult para convertir el resultado en Flowable y lo devuelve.

El siguiente es un diagrama de flujo dibujado con PlantUML que muestra el proceso de ejecución de CodeSemanticWorkflow:

@startuml
start
:创建 ElasticsearchStore对象;
:获取用户最后一条消息的内容;
:使用 SemanticProblemAnalyzer对象分析问题;
:使用 SemanticSolutionExecutor对象执行语义化的代码搜索;
:将结果转换为 Flowable<Answer>;
:将结果转换为 Flowable<WorkflowResult>;
stop
@enduml

Espero que la información anterior responda a su pregunta.

Diseño de asistente de IA basado en código CF

Al diseñar Chocolate Factory (en lo sucesivo, CF), adoptamos la idea de DDD.

La primera parte se centra en resolver el espacio del problema, analizando y transformando los problemas de los usuarios para obtener posibles soluciones.

La segunda parte se centra en la realización del espacio de soluciones, es decir, obtener respuestas a las preguntas correspondientes mediante el aumento de recuperación (RAG, Retrieval Augmented Generation).

Para ello, en la primera parte, analizaremos la pregunta y responderemos preguntas para construir un DSL para la solución. Luego, busque en el DSL para obtener las respuestas correspondientes y finalmente entréguelo al LLM para su resumen.

Estrategia de construcción inmediata Fase 1: resolución de problemas

En términos de diseño, para realizar mejor la recuperación, al diseñar CoUnit, lo dividimos en tres condiciones de verificación:

  • englishQuery , traduce chino al inglés y luego busca en inglés.

  • originLanguageQuery , si estamos usando chino, la traducción al inglés puede no ser estándar, pero los comentarios pueden estar en chino, por lo que la similitud será muy confiable.

  • hipotheticalDocument , un documento hipotético, que genera código basado en la solicitud del usuario y luego combina el código generado con una búsqueda similar.

Por lo tanto, en la etapa uno, LLM necesita analizar el problema del usuario y proporcionar las tres condiciones de verificación mencionadas anteriormente. documento hipotético se refiere al diseño de Bloop:

  • hipotheticalDocument  es un fragmento de código que hipotéticamente podría ser devuelto por un motor de búsqueda de código como respuesta.

  • El fragmento de código del documento hipotético  debe tener entre 5 y 10 líneas de largo.

Sin embargo, dado que se dan tres condiciones a la vez, todavía existe ocasionalmente el problema de errores probabilísticos hipotéticos en los documentos.

Fase 2 de la estrategia de construcción inmediata: mejora de la recuperación

En el diseño existente, la esencia de un asistente de IA basado en código también es RAG (Generación Aumentada de Recuperación), por lo que se puede dividir en la etapa de indexación y la etapa de consulta.

Asistente de IA de base de código: etapa de indexación

d8571b8774e6c43852998339edb83792.png

En la etapa de indexación, básicamente es:

  • División de texto (TextSplitter). Una herramienta o componente responsable de dividir los datos de origen en unidades más pequeñas (Chunks).

  • Vectorización de textos (Vectoring). Responsable de convertir el Chunk dividido en una matriz vectorizada.

  • La base de datos (Vector Database) es responsable de realizar una recuperación rápida de fragmentos de documentos a través de una tecnología eficiente de recuperación de vectores.

Para la vectorización de texto, utilizamos  SentenceTransformer un modelo de PNL mínimo localizado (aproximadamente 22 millones). En cuanto al código, está estructurado y ha sido completamente verificado por GitHub Copilot y Bloop, por lo que la precisión no es mala.

Dado que se utiliza un modelo localizado, los cálculos se pueden completar rápidamente usando la CPU, por lo que la estrategia de actualización se puede integrar con CI y CD. Una vez que se actualiza el código, se puede indexar.

Asistente de Codebase AI: etapa de consulta

e065f4a27279032752044d0663aaf736.png

En la etapa de consulta, nos centraremos en el DSL en la etapa 1 y primero convertiremos el texto del DSL al formato vectorizado correspondiente.

Luego busque el contenido correspondiente:

// 基于英语的相关代码列表
val list = store.findRelevant(query, 15, 0.6)
// 基于中文的相关代码列表
val originLangList = store.findRelevant(originQuery, 15, 0.6)
// 相关的假设性代码列表
val hydeDocs = store.findRelevant(hypotheticalDocument, 15, 0.6)

Luego se clasifican los resultados. Teniendo en cuenta el impacto de artículos como "Perdidos en el medio: cómo los modelos de lenguaje usan contextos largos" en textos largos, también hemos introducido los métodos correspondientes en CF, por lo que el resultado del código ordenado es el siguiente:

0.7847863// canonicalName: cc.unitmesh.cf.domains.semantic.CodeSemanticWorkflowTest
0.76635444// canonicalName: cc.unitmesh.cf.domains.semantic.CodeSemanticDecl
0.74648994// canonicalName: cc.unitmesh.cf.core.flow.ProblemAnalyzer
0.7410852// canonicalName: cc.unitmesh.cf.domains.spec.SpecDomainDecl
0.72767156// canonicalName: cc.unitmesh.cf.core.flow.DomainDeclaration
0.73245597// canonicalName: cc.unitmesh.cf.core.flow.model.WorkflowResult
0.7434818// canonicalName: cc.unitmesh.cf.domains.interpreter.CodeInterpreterWorkflow.execute
0.757218// canonicalName: cc.unitmesh.cf.core.flow.Workflow
0.7722022// canonicalName: cc.unitmesh.cf.domains.semantic.flow.SemanticProblemAnalyzer
0.807935// canonicalName: cc.unitmesh.cf.domains.semantic.CodeSemanticWorkflow.execute

El primer número es la puntuación de correlación y el siguiente nombre canónico es la información del código relevante, que puede ser una clase, un método de clase, un método, etc.

Estrategia rápida 3: estrategia de división de código

Diferentes marcos tienen diferentes estrategias para la segmentación de código: LangChain se basa en palabras clave, LlamaIndex se basa en TreeSitter y Bloop se crea en función de la expresión S de TreeSitter.

Utilizamos la estructura de código estandarizada de ArchGuard Scanner y, además de utilizar directamente la infraestructura CLI existente del proyecto ArchGuard, también es más precisa en forma y resultados. Por ejemplo, puede optimizar las reglas de división de fragmentos para la interfaz, la clase abstracta, etc., y crear un método canonicalName para facilitar la indexación y el posicionamiento.

reglas de división de código

La regla plegable a la que nos referimos es: https://docs.sweep.dev/blogs/chunking-2m-files . Ahora mismo:

  1. La proporción promedio de token a carácter del código es de aproximadamente 1:5 (300 tokens), mientras que el modelo de incrustación tiene un límite máximo de tokens de 512.

  2. 1500 caracteres corresponden a aproximadamente 40 líneas, lo que equivale aproximadamente a una función o clase de tamaño pequeño a mediano.

  3. El desafío es acercarse lo más posible a los 1500 caracteres y al mismo tiempo garantizar que los fragmentos sean semánticamente similares y estén vinculados con el contexto relevante.

El modelo correspondiente es el siguiente:

classCodeSplitter(
private val comment: String= "//",
private val chunkLines: Int= 40,
private val maxChars: Int= 1500,
// TODO: for unsupported languages, we can use the following heuristic to split the code
    val chunkLinesOverlap: Int= 15,
)

Por supuesto, chunkLinesOverlap aquí aún no está disponible.

Implementación de división de fragmentos

Generado por el asistente de IA de base de código de CF:

Pregunta: ¿Cómo se implementa CodeSplitter?

Respuesta:

Según el código proporcionado, CodeSplitter es una clase que se utiliza para dividir el código en varios documentos. Tiene una función de división que acepta un objeto CodeDataStruct y devuelve una lista de objetos de documento.

En la función de división, primero determina si es necesario dividir en función de la longitud del código. Si la longitud del código es menor o igual que maxChars (el valor predeterminado es 1500 caracteres), el código completo se devuelve directamente como un documento.

Si la longitud del código es mayor que maxChars, cada función en el objeto CodeDataStruct se itera y el contenido de la función se divide en varios documentos. El método de división consiste en dividir el contenido de la función en varias partes según las líneas de trozos (el valor predeterminado es 40 líneas). Si el número de líneas de la función excede ChunkLines, solo las primeras líneas de ChunkLines se toman como contenido de un documento.

El contenido del documento dividido consta del canonicalName y el contenido de la función. Si la longitud del contenido dividido excede maxChars, los primeros caracteres maxChars serán interceptados como contenido del documento.

resumen

Este artículo proporciona una exploración en profundidad de las estrategias de diseño e implementación de asistentes de IA de base de código, incluida la resolución de problemas, la mejora de la recuperación y la división de código. Estas estrategias ayudan a mejorar la eficiencia y precisión de la interacción de los desarrolladores con el código base y acelerar el proceso de desarrollo de software.

Para obtener más detalles, consulte la base del código: https://github.com/unit-mesh/chocolate-factory  .

Para obtener documentación detallada, consulte: https://framework.unitmesh.cc/  .

Supongo que te gusta

Origin blog.csdn.net/gmszone/article/details/132959932
Recomendado
Clasificación