Nouvelle publication

Rechercher

Article
· Mai 20 3m de lecture

Un nocaut de peso

Desenho de animal com a boca aberta O conteúdo gerado por IA pode estar incorreto., Imagem 

 

Al igual que un golpe de gracia, sin darle ninguna oportunidad al oponente, Kubernetes, como plataforma de código abierto, tiene un universo de oportunidades debido a su disponibilidad (es decir, la facilidad para encontrar soporte, servicios y herramientas). Es una plataforma que permite gestionar trabajos y servicios en contenedores, lo que simplifica enormemente la configuración y automatización de estos procesos. 

Pero justifiquemos la imagen del título y demos el nombre “correcto” a la herramienta en cuestión: InterSystems Kubernetes Operator. 

El principio es básico, tú eliges los servicios y defines las reglas del juego (aquí refiriéndonos nuevamente a Knockout), y todo se proporcionará de la forma más transparente y eficiente posible, y esto es válido para la instalación, reparación o eventual restauración, cuando esta se desvíe de los requisitos predefinidos. 

Pero ¿qué diferencia a IKO de cualquier otro operador? Como una extensión de la API de Kubernetes (llamémosla K8s para abreviar), el componente personalizado IrisCluster, que tiene las opciones de implementarse como un clúster bloqueado de IRIS, un clúster de Caché distribuido o incluso una instancia anónima. Todo esto en las más diversas plataformas Kubernetes disponibles. Por último, pero no por ello menos importante, también incluye capacidades de gestión de clústeres de InterSystems, que permiten automatizar algunas tareas con la adición de nodos, algo que antes solo se podía hacer manualmente. 

Todo esto está muy bien, hace referencia a algún deporte o juego, pero ¿por qué necesito esto? La respuesta es relativamente sencilla. No necesito IrisCluster para llevar InterSystems IRIS a K8s, sin embargo, como K8s es una aplicación independiente, sería necesario crear las definiciones y los eventuales scripts para configurar estas instancias de IRIS. De esta forma IKO automatiza este proceso, facilitando el mantenimiento. El uso de contenedores es una excelente forma de empaquetar esta colección de actividades que deben realizarse. 

Sin embargo, aprovechando la oportunidad ¿sabes qué es un contenedor? Un consejo: no es sólo el juego de mesa. 

Container, the Shipping Container Board Game, Imagem 

La respuesta tiene mucho más que ver con el “transporte” de algún orden, ya que empaqueta y aísla aplicaciones y servicios, para que puedan ejecutarse por separado del resto. Facilitando así el “transporte” de un entorno a otro, según la necesidad. Aprovechando la extensa documentación de InterSystems, a continuación se muestra el enlace a los pasos de instalación de IKO y su posterior configuración y ajuste. 

Para que nadie tenga curiosidad por el apodo K8s. El origen del nombre Kubernetes proviene del griego, que significa nada más y nada menos que piloto o timonel, en definitiva, el que dirige. Y, el número de caracteres entre las letras “K” al principio y “S” al final, es 8. Por lo tanto, “K8s”. 

23 Comments
Discussion (23)7
Connectez-vous ou inscrivez-vous pour continuer
Annonce
· Mai 20

Votez pour la meilleure démo ! Les InterSystems Demo Games sont lancés !

Bonjour la communauté,

Nous avons quelque chose de passionnant pour vous : c'est l'heure du nouveau concours de vidéos de démonstration, et cette fois, c'est vous qui êtes juge !

📺 Demo Games pour les InterSystems Sales Engineers 📺

Pour ce concours, les Sales Engineers d'InterSystems du monde entier ont soumis de courtes vidéos de démonstration présentant des cas d'utilisation uniques, des solutions intelligentes et les puissantes fonctionnalités des technologies InterSystems.

À votre tour ! Nous ouvrons le vote à toute la communauté des développeurs. Votre expérience et votre point de vue de développeurs font de vous de parfaits experts.

👉 Comment participer

  • Regardez les démos sur la page du concours
  • Votez pour vos créations préférées (connexion à la communauté des développeurs requise)

🗓 Période du concours

Le vote est ouvert du 26 mai au 31 juillet 2025, et les gagnants seront annoncés peu après.

De nouvelles vidéos seront ajoutées tout au long du concours ; consultez régulièrement la page. Vous pourriez trouver votre préférée à la fin !

✅ Comment voter :

Tous les membres actifs ayant apporté une contribution valable à la Communauté des Développeurs ou à Open Exchange, par exemple en posant ou en répondant à des questions, en rédigeant des articles ou en publiant des applications, peuvent voter. Cela inclut les clients, les partenaires et les employés qui se sont inscrits avec leur adresse e-mail professionnelle.

Pour voter :

  1. Connectez-vous (ou créez un compte) à la Communauté des développeurs
  2. Visitez la page du concours
  3. Sélectionnez vos 3 vidéos préférées et cliquez sur le bouton « Vote » pour chacune d'elles.

🏆 Système de notation :

  • 1er place = 9 points
  • 2e place = 6 points
  • 3e place = 3 points

🔁 Les votes des modérateurs officiels de la communauté* comptent double ; vos meilleurs choix comptent donc vraiment !

* Les modérateurs sont indiqués par un cercle vert autour de leur avatar.


Que les Demo Games commencent – ​​et que la meilleure démo gagne 

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer
Annonce
· Mai 20

Vote for the Best Demo! The InterSystems Demo Games Are On!

Hi Community,

We’ve got something exciting for you — it’s time for a new demo video contest, and this time, you’re in the judge’s seat!

📺 Demo Games for InterSystems Sales Engineers 📺

For this contest, InterSystems Sales Engineers from around the world submitted short demo videos showcasing unique use cases, smart solutions, and powerful capabilities of InterSystems technologies.

Now it’s your turn! We’re opening up voting to the entire Developer Community. Your insight and perspective as developers make you the perfect experts.

👉 How to participate

  • Watch the demos on the Demo Games Contest Page
  • Vote for your favourite entries (Developer Community login required)

🗓 Contest period

Voting is open from May 26 until September 14, 2025, and winners will be announced shortly after.

New videos will be added throughout the contest — so keep checking back. You might find a favourite right at the end!

✅ How to vote: 

All active members who have made a valid contribution to the Developer Community or Open Exchange — such as asking or answering questions, writing articles, or publishing applications — are eligible to vote. This includes customers, partners, and employees who registered using their corporate email addresses.

To vote:

  1. Log in (or create an account) on the Developer Community
  2. Visit the Contest Page
  3. Select your top 3 favourite videos and click the “Vote” button for each

🏆 Scoring system:

  • 1st place vote = 9 points
  • 2nd place = 6 points
  • 3rd place = 3 points

🔁 Votes from the Official Community Moderators* count double, so your top picks really matter!

* Moderators are indicated by a green circle around their avatar. 


Let the Demo Games begin – and may the best demo win!

Discussion (0)2
Connectez-vous ou inscrivez-vous pour continuer
Discussion (3)2
Connectez-vous ou inscrivez-vous pour continuer
Article
· Mai 20 7m de lecture

Uma Solução de Busca Semântica de Código para o TrakCare Utilizando o IRIS Vector Search

Este artigo apresenta uma solução em potencial para a busca semântica de código no TrakCare usando o IRIS Vector Search.

Aqui está uma breve visão geral dos resultados da busca semântica de código do TrakCare para a consulta: "Validação antes de salvar o objeto no banco de dados".

 

  • Modelo de Embedding de Código

Existem diversos modelos de embedding desenvolvidos para frases e parágrafos, mas eles não são ideais para embeddings específicos de código.

Foram avaliados três modelos de embedding específicos para código: voyage-code-2, CodeBERT e GraphCodeBERT. Embora nenhum desses modelos tenha sido pré-treinado para a linguagem ObjectScripts, eles ainda superaram os modelos de embedding de propósito geral nesse contexto.

O CodeBERT foi escolhido como o modelo de embedding para esta solução, oferecendo desempenho confiável sem a necessidade de uma chave de API.😁

class GraphCodeBERTEmbeddingModel:
    def __init__(self, model_name="microsoft/codebert-base"):
        self.tokenizer = RobertaTokenizer.from_pretrained(model_name)
        self.model = RobertaModel.from_pretrained(model_name)
    
    def get_embedding(self, text):
        """
        Generate a CodeBERT embedding for the given text.
        """
        inputs = self.tokenizer(text, return_tensors="pt", max_length=512, truncation=True, padding="max_length")
        with torch.no_grad():
            outputs = self.model(**inputs)
        # Use the [CLS] token embedding for the representation
        cls_embedding = outputs.last_hidden_state[:, 0, :].squeeze().numpy()
        return cls_embedding

 

  • Banco de Dados Vetorial IRIS

Uma tabela é definida com uma coluna do tipo VECTOR para armazenar os embeddings. Observe que o índice COLUMNAR não é suportado para colunas do tipo VECTOR.

Os embeddings do CodeBERT possuem 768 dimensões. Ele pode processar textos com comprimento máximo de 512 tokens.

CREATE TABLE TrakCareCodeVector (
                file VARCHAR(150),
                codes VARCHAR(2000),
                codes_vector VECTOR(DOUBLE,768)
            ) 

  

  • API DB Python

A API DB Python é utilizada para estabelecer uma conexão com a instância IRIS e executar as instruções SQL.

  1. Construir o Banco de Dados Vetorial para o Código Fonte TrakCare
  2. Recuperar os Top_K Embeddings de Código com Maior DOT_PRODUCT do Banco de Dados Vetorial IRIS
# build IRIS vector database
import iris
import os
from dotenv import load_dotenv

load_dotenv()

class IrisConn:
    """Connection with IRIS instance to execute the SQL statements """
    def __init__(self) -> None:
        connection_string = os.getenv("CONNECTION_STRING")
        username = os.getenv("IRISUSERNAME")
        password = os.getenv("PASSWORD")

        self.connection = iris.connect(
            connectionstr=connection_string,
            username=username,
            password=password,
            timeout=10000,
        )
        self.cursor = self.connection.cursor()

    def insert(self, params: list):
        try:
            sql = "INSERT INTO TrakCareCodeVector (file, codes, codes_vector) VALUES (?, ?, TO_VECTOR(?,double))"
            self.cursor.execute(sql,params)
        except Exception as ex:
            print(ex)
    
    def fetch_query(self, query: str):
        self.cursor.execute(query)
        return self.cursor.fetchall()

    def close_db(self):
        self.cursor.close()
        self.connection.close()
        
from transformers import AutoTokenizer, AutoModel, RobertaTokenizer, RobertaModel, logging
import torch
import numpy as np
import os
from db import IrisConn
from GraphcodebertEmbeddings import MethodEmbeddingGenerator
from IRISClassParser import parse_directory
import sys, getopt

class GraphCodeBERTEmbeddingModel:
    def __init__(self, model_name="microsoft/codebert-base"):
        self.tokenizer = RobertaTokenizer.from_pretrained(model_name)
        self.model = RobertaModel.from_pretrained(model_name)
    
    def get_embedding(self, text):
        """
        Generate a CodeBERT embedding for the given text.
        """
        inputs = self.tokenizer(text, return_tensors="pt", max_length=512, truncation=True, padding="max_length")
        with torch.no_grad():
            outputs = self.model(**inputs)
        # Use the [CLS] token embedding for the representation
        cls_embedding = outputs.last_hidden_state[:, 0, :].squeeze().numpy()
        return cls_embedding
        
class IrisVectorDB:
    def __init__(self, vector_dim):
        """
        Initialize the IRIS vector database.
        """
        self.conn = IrisConn()
        self.vector_dim = vector_dim

    def insert(self, description: str, codes: str, vector):
        params=[description, codes, f'{vector.tolist()}']
        self.conn.insert(params)

    def search(self, query_vector, top_k=5):
        query_vectorStr = query_vector.tolist()
        query = f"SELECT TOP {top_k} file,codes FROM TrakCareCodeVector ORDER BY VECTOR_COSINE(codes_vector, TO_VECTOR('{query_vectorStr}',double)) DESC"
        results = self.conn.fetch_query(query)
        return results
    
# Chatbot for code retrieval
class CodeRetrieveChatbot:
    def __init__(self, embedding_model, vector_db):
        self.embedding_model = embedding_model
        self.vector_db = vector_db
    
    def add_to_database(self, description, code_snippet, embedding = None):
        if embedding is None:
            embedding = self.embedding_model.get_embedding(code_snippet)
        self.vector_db.insert(description, code_snippet, embedding)
    
    def retrieve_code(self, query, top_k=5):
        """
        Retrieve the most relevant code snippets for the given query.
        """
        query_embedding = self.embedding_model.get_embedding(query)
        results = self.vector_db.search(query_embedding, top_k)
        return results
  • Fragmentos de Código (Code Chunks)

Como o CodeBERT consegue processar textos com um comprimento máximo de 512 tokens, classes e métodos muito grandes precisam ser divididos em partes menores. Cada uma dessas partes, ou fragmentos de código, é então incorporada (embedded) e armazenada no banco de dados vetorial.

from transformers import AutoTokenizer, AutoModel, RobertaTokenizer, RobertaModel
import torch
from IRISClassParser import parse_directory

class MethodEmbeddingGenerator:
    def __init__(self, model_name="microsoft/codebert-base"):
        """
        Initialize the embedding generator with CodeBERT.

        :param model_name: The name of the pretrained CodeBERT model.
        """
        self.tokenizer = RobertaTokenizer.from_pretrained(model_name)
        self.model = RobertaModel.from_pretrained(model_name)
        self.max_tokens = self.tokenizer.model_max_length  # Typically 512 for CodeBERT
    def chunk_method(self, method_implementation):
        """
        Split method implementation into chunks based on lines of code that approximate the token limit.

        :param method_implementation: The method implementation as a string.
        :return: A list of chunks.
        """
        lines = method_implementation.splitlines()
        chunks = []
        current_chunk = []
        current_length = 0
        for line in lines:
            # Estimate tokens of the line
            line_token_estimate = len(self.tokenizer.tokenize(line))
            if current_length + line_token_estimate <= self.max_tokens - 2:
                current_chunk.append(line)
                current_length += line_token_estimate
            else:
                # Add the current chunk to chunks and reset
                chunks.append("\n".join(current_chunk))
                current_chunk = [line]
                current_length = line_token_estimate

        # Add the last chunk if it has content
        if current_chunk:
            chunks.append("\n".join(current_chunk))

        return chunks

    def get_embeddings(self, method_implementation):
        """
        Generate embeddings for a method implementation, handling large methods by chunking.

        :param method_implementation: The method implementation as a string.
        :return: A list of embeddings (one for each chunk).
        """
        chunks = self.chunk_method(method_implementation)
        embeddings = {}

        for chunk in chunks:
            inputs = self.tokenizer(chunk, return_tensors="pt", truncation=True, padding=True, max_length=self.max_tokens)
            with torch.no_grad():
                outputs = self.model(**inputs)
                # Use the [CLS] token embedding (index 0) as the representation
                cls_embedding = outputs.last_hidden_state[:, 0, :].squeeze(0)
                embeddings[chunk] = cls_embedding.numpy()

        return embeddings

    def process_methods(self, methods):
        """
        Process a list of methods to generate embeddings for each.

        :param methods: A list of dictionaries with method names and implementations.
        :return: A dictionary with method names as keys and embeddings as values.
        """
        method_embeddings = {}
        for method in methods:
            method_name = method["name"]
            implementation = method["implementation"]
            print(f"Processing method embedding: {method_name}")
            method_embeddings[method_name] = self.get_embeddings(implementation)
        return method_embeddings
  • Interface do Usuário - O Aplicativo Angular

A arquitetura utiliza Angular como frontend e Python (Flask) como backend.

 

  • Próximos Passos 

O resultado da busca não é perfeito porque o modelo de embedding não foi pré-treinado para ObjectScripts.

Discussion (0)1
Connectez-vous ou inscrivez-vous pour continuer