메뉴
HN
Hacker News 26일 전

임베딩 모델 기반 비정확 중복 코드 탐지 CLI 도구

IMP
7/10
핵심 요약

Slopo는 임베딩 모델을 활용하여 다른 모듈이나 원격 위치에 흩어져 있는 발견하기 어려운 유사 코드를 찾아내는 가벼운 CLI 도구입니다. 코드를 임베딩 벡터로 변환하여 유사도와 물리적 거리를 기반으로 중복 가능성이 있는 코드 클러스터를 분류합니다. 개발자와 AI 코딩 에이전트가 이 결과를 바탕으로 실제 중복 여부를 확인하고 리팩토링을 수행할 수 있어 코드 품질 관리에 매우 유용합니다.

번역된 본문

제목: Show HN: 임베딩 모델을 활용한 비정확 중복 코드 탐지 CLI 도구 소스: Hacker News

Slopo 임베딩 모델을 사용하여 비정확한(non-exact) 코드 중복을 탐지하는 가벼운 CLI 도구입니다. 이 도구는 탐지하기 가장 어렵고 가장 해로운 유사 코드, 즉 비슷한 방식으로 작성되었지만 코드베이스 내에서 물리적으로 멀리 떨어져 있거나, 종종 다른 모듈에 걸쳐 흩어져 있거나, 대용량 파일 내에서 분리되어 있는 코드 조각에 중점을 둡니다. 단순 복사 및 붙여넣기 기반의 완전한 중복은 다른 도구로도 쉽게 찾을 수 있으며, 서로 가까이 붙어있는 중복 코드는 사람이나 AI가 쉽게 발견할 수 있습니다. 이 문제에 대한 더 자세한 설명은 slopo.dev를 참조하세요.

지원 언어 Python, TypeScript, JavaScript, Java, Kotlin, C#, Go, Rust

작동 방식 일반적인 중복 탐지 도구와는 다른 접근 방식을 취합니다. 모든 코드 단위에 대해 임베딩을 계산한 다음, 임베딩 값이 가까운 쌍을 찾습니다. 유사한 코드가 반드시 중복은 아니기 때문에, 찾아낸 각 쌍은 확인이 필요한 잠재적 중복입니다. 즉, 동일한 기능을 수행하지만 완전히 다른 방식으로 구현된 코드는 거리가 먼 임베딩을 생성하므로 탐지되지 않습니다. 그 결과는 코드베이스 내 유사도와 물리적 거리를 기준으로 순위가 매겨진 유사 코드 단위의 클러스터입니다. 이러한 클러스터는 AI 코딩 에이전트(Coding Agent)의 입력 데이터로 사용되며, 에이전트는 해당 클러스터가 실제 중복인지 검증할 수 있습니다. 검토가 끝난 클러스터는 무시하도록 표시하거나 리팩토링을 위해 전달할 수 있습니다.

보고서 예시 Slopo 코드의 src 디렉토리(git tag v0.2.0)를 바탕으로 생성된 doc/example-report를 확인해 보세요. 이 예시는 각 언어에 대한 코드 파서가 많은 중복을 포함하고 있으며, 일부는 완전히 동일한 복사본이고 일부는 유사한 변형인 것을 확인해 주었습니다. 이 부분은 리팩토링이 필요합니다.

빠른 시작 설치: uv tool install slopo 이 명령은 Python 패키지 관리자인 uv(uv 설치)를 사용하여 PyPI에서 Slopo를 격리된 가상 환경에 설치합니다. Python을 별도로 설치할 필요가 없습니다.

설정 slopo init을 실행하여 추가 지침이 포함된 구성 파일 템플릿을 생성합니다. 분석할 코드가 있는 디렉터리와 임베딩 모델 구성만 있으면 충분합니다.

임베딩 모델 임베딩은 외부 제공자(provider)를 통해 계산됩니다. 최상의 결과를 원한다면 코드 전용 모델(예: Voyage AI, 512와 같은 저차원에서도 잘 작동함)을 사용해 보세요. LiteLLM과 호환되는 모든 모델 제공자를 사용할 수 있으며, 자세한 내용은 이곳에서 확인하세요. 보안을 위해 제공자의 API 키는 환경 변수로 설정할 수 있습니다.

분석 slopo show-config를 실행하여 구성의 유효성을 검사하고 설정 가능한 모든 매개변수를 확인하세요. 대부분은 합리적인 기본값이 설정되어 있어 선택 사항입니다. 이제 코드를 인덱싱하고, 임베딩을 계산하고, 보고서를 생성할 준비가 되었습니다: slopo index slopo embed slopo analyze

실제 워크플로우 이 섹션은 Slopo를 실제 개발 워크플로우에서 어떻게 사용할 수 있는지 보여줍니다. 증분 재인덱싱(변경된 파일만으로 인덱스 업데이트)과 이미 검토한 클러스터를 버리는 slopo.ignore.txt 파일을 활용합니다.

첫 번째 분석을 생성하고 결과를 확인하세요. 모든 클러스터 목록과 파일별 클러스터 세부 정보가 포함된 index.md를 발견할 수 있을 것입니다. 일부 디렉터리나 파일 패턴을 제외하고 싶을 수도 있으며, 보통 테스트 파일을 제외하는 것이 좋습니다. 결과가 너무 많거나 적다면 임계점(threshold)을 조정할 수도 있습니다.

분석 결과에 만족하면, AI 코딩 에이전트에게 실제 중복이 아닌 클러스터를 필터링해 달라고 요청하세요. 모든 유사 코드가 반드시 처리해야 할 중복은 아니기 때문에 이는 매우 일반적인 과정입니다. AI 에이전트에게 버릴 클러스터 해시를 slopo.ignore.txt에 추가하도록 요청하세요. 검토된 클러스터가 제외된 보고서를 생성하기 위해 분석을 다시 실행합니다.

이것이 AI 에이전트가 수행할 수 있는 리팩토링의 기반입니다. 이 ignore 파일은 Git 리포지토리에 커밋하여 팀 간에 재사용할 수 있습니다. 새로 추가되거나 수정된 클러스터는 다시 보고서에 나타납니다. API 키가 없는 구성 파일 또한 커밋할 수 있습니다. 단, 로컬 데이터인 slopo.db는 커밋하지 마세요.

구성 언제든지 slopo --helpslopo show-config를 실행하여 직접 탐색해 보세요. 대부분의 구성은 구성 파일로 이루어지지만 두 가지 예외가 있습니다. 구성 파일의 위치는 --config 옵션으로 재정의할 수 있습니다. API 키는 SLOPO_EMBEDDING_API_KEY 환경 변수로 설정할 수 있으며, 이 변수는 자동으로 불러와집니다.

원문 보기
원문 보기 (영어)
Slopo A lightweight CLI tool for detecting non-exact code duplication using embedding models. It focuses on the similar code that is hardest to detect and most harmful: snippets written similarly, sitting far apart in the codebase, often spread across different modules or separated within a large file. Exact copy-paste is easy to spot by other tools, and duplicates that are close together are easy to spot by humans or AI. For more high-level description of the problem see slopo.dev . Supported languages Python, TypeScript, JavaScript, Java, Kotlin, C#, Go, Rust How it works It takes a different approach than typical duplication detection. For every code unit, it calculates an embedding, then looks for pairs whose embeddings are close. Similar code is not necessarily a duplicate, so each pair is a potential duplicate to confirm. Code doing the same thing but implemented in a completely different way produces distant embeddings and won't be detected. The result is clusters of similar code units, ranked by similarity and by distance in the codebase. These clusters are meant as input for your AI coding agent, which can check whether a cluster is a real duplicate. Reviewed clusters can be marked as ignored or passed on for refactoring. Example report See doc/example-report generated from Slopo code, src directory, git tag v0.2.0 . This example confirmed that code parsers for each language have a lot of duplication, some are exact-copy, some are similar variants. It needs to be refactored. Quick start Installation uv tool install slopo This command uses uv ( installing uv ), a Python package manager, to install Slopo from PyPI in an isolated virtual environment. No need to get Python separately. Setup Run slopo init to create a config file template containing further instructions. Only the directory with code for analysis and embedding model configuration is required. Embedding model Embeddings are calculated using an external provider. For best results, consider models dedicated to code, e.g. Voyage AI (it works fine with low dimensions like 512 ). You can use any model provider compatible with LiteLLM, see details here . The provider API key can be set as an environment variable for better security. Analysis Run slopo show-config to validate your config and show all configurable parameters, most are optional with sensible defaults. Now you are ready to index code, calculate embeddings and generate a report: slopo index slopo embed slopo analyze Real workflow This section demonstrates how Slopo can be used in a real development workflow. It utilizes incremental re-indexing (update index with changed files only) and slopo.ignore.txt to discard already reviewed clusters. Create your first analysis and check results. You will notice index.md containing a list of all clusters and cluster details per file. You may want to exclude some directories or file patterns, usually excluding tests is a good idea. You can also tune thresholds if the result is too big or too small. Once satisfied with analysis results, ask your AI coding agent to filter out clusters that are not real duplicates. This is a common case because not every similar code is a duplication to act on. Ask the AI agent to add discarded cluster hashes to slopo.ignore.txt . Re-run the analysis to generate a report without reviewed clusters. This is a basis for refactoring, which can be done by an AI agent. ignore file can be committed to your Git repository and reused cross-team. New and modified clusters will reappear in the report. A configuration file without an API key can also be committed. Don't commit slopo.db , this is your local data. Configuration Run slopo --help and slopo show-config to explore it by yourself anytime. Most configuration is done with a configuration file with two exceptions: The location of the configuration file can be overridden with the --config option. The API key can be set with the SLOPO_EMBEDDING_API_KEY environment variable, also picked up from a .env file in the current directory. Be aware that some parameters can't be changed after first indexing. You need to remove slopo.db and index/embed from the beginning: source_dir , embedding_model , embedding_dimensions , body_node_count_threshold . All configurable parameters source_dir : Source directory with code to index, absolute or relative path. source_dir_exclude : .gitignore-style patterns to exclude from indexing. db_file : SQLite database file with tool data. report_dir : Output directory for analysis report. ignore_file : Text file with ignored clusters. embedding_model : Embedding model name in LiteLLM format. embedding_dimensions : Embedding dimensions compatible with the used model. embedding_api_key : API key for embedding provider. Optional if configured with an environment variable. embedding_batch_size and embedding_batch_chars : Requests to the embedding API are batched for performance. Defaults are fine for most cases. similarity_threshold : Controls minimal cosine similarity between embeddings. rerank_threshold : Controls minimal similarity after applying a boost reflecting distance in the codebase. body_node_count_threshold : Number of AST nodes inside the body (excluding signature and annotations). This value reflects the minimum code complexity of the included code unit, more precise than text length. Increase if you notice unwanted, too-small code units in the report. Details Ranking thresholds Similar code units are filtered in two passes, each with its own configurable threshold. The pipeline is as follows: similarity_threshold filters out code unit pairs whose embeddings are not similar enough. The calculated value is cosine similarity ranging from -1 to 1 where 1 means the same. Similar pairs are grouped in clusters. Units in clusters are reranked after applying a boost. Boost is calculated based on the number of directory hops required to reach the other file in the pair (max. 15%). If they are in the same file, the boost is calculated based on distance in number of lines (max. 10%). rerank_threshold filters out clusters whose highest-scoring pair is not high enough. Exact-copy duplicates The main goal of this tool is to detect non-exact code duplication, but exact copies (identical code at multiple paths) are reported too, just handled a little differently from merely similar code: The report shows the code once, listing every path where it appears, instead of repeating identical snippets. The analyze command reports the "similarity ratio" (the share of code units flagged as similar) in two variants: including and excluding exact copies.