{"id":26506622,"url":"https://github.com/thijse/plagiarismdetector","last_synced_at":"2026-05-06T23:43:32.730Z","repository":{"id":200220732,"uuid":"705047633","full_name":"thijse/PlagiarismDetector","owner":"thijse","description":"A sample showing how vector comparison can be used to detect plagiarismm using a simple in-memory vector store.","archived":false,"fork":false,"pushed_at":"2023-10-14T23:58:12.000Z","size":1081,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-20T22:55:51.380Z","etag":null,"topics":["csharp","large-language-models","openai","plagiarism","plagiarism-detection","rag","vector"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thijse.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-10-14T22:08:36.000Z","updated_at":"2025-01-31T00:01:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"d947443a-3824-4922-b3e2-aa8c60821316","html_url":"https://github.com/thijse/PlagiarismDetector","commit_stats":null,"previous_names":["thijse/plagiarismdetector"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/thijse/PlagiarismDetector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thijse%2FPlagiarismDetector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thijse%2FPlagiarismDetector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thijse%2FPlagiarismDetector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thijse%2FPlagiarismDetector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thijse","download_url":"https://codeload.github.com/thijse/PlagiarismDetector/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thijse%2FPlagiarismDetector/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32716948,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T19:35:05.142Z","status":"ssl_error","status_checked_at":"2026-05-06T19:35:03.996Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","large-language-models","openai","plagiarism","plagiarism-detection","rag","vector"],"created_at":"2025-03-20T22:55:54.207Z","updated_at":"2026-05-06T23:43:32.714Z","avatar_url":"https://github.com/thijse.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\n# Plagiarism Dectector\nA sample showing how Vector comparison can be used to easily and effectively detect plagiarismm using a  simple in-memory vector store \n\nThe repository contains three main projects:\n- Memory Vector Store project, which focuses on storing vectors in memory;\n- Chunk Creator project, which extracts vectors from PDF files;\n-Plagiarism project, which demonstrates how to perform similarity searches using the stored vectors and use OpenAI . Each project has its own set of code and resources, allowing you to explore and understand the implementation details.\n\n This code is based on the code in [MemoryVectorStore](https://github.com/thijse/MemoryVectorStore)\n\n\n## Code example\n\nFirst we need to make chunks both PDFs and build the embedding vectors\n\n```cs\n//  OpenAI service that we are going to use for embedding\n_openAiService = new OpenAIService(new OpenAiOptions()  {ApiKey = apiKey });\n\n// Set up a MemoryVector database, to be filled with chunks of documents\n// including an embedding vector of 1536 dimensions\n// Also included is a callback that embeds any text item into a vector\n_vectorCollection = new MemoryVectorDB.VectorDB\u003cChunk\u003e(1536, ChunkEmbedingAsync);\n\n// Get text fom pdf \n_document = PdfTextExtractor.GetText(documentPath);\n\n// Generate sentences of max 50 words\n_chunkGenerator = new ChunkGenerator(50,  _document);\n\n// Loop through chunks\nforeach (var chunk in _chunkGenerator.GetChunk())\n{\n    // Add the source reference to the chunk\n    chunk.Source = documentPath;\n\n    // Add the chunk to the vector store\n    await _vectorCollection.AddAsync(chunk);\n\n    // We remove the text from the chunk to safe memory:\n    // we just need the vector, start index, length and source\n    // so we can recover the the chunk from the original document later\n    chunk.Text = null!;\n}\n```\n\nNow we can find the best matching sentences between both documents\n\n```cs\nvar vectorObjects1 = _embedding1.VectorCollection.VectorObjects;\nvar vectorObjects2 = _embedding2.VectorCollection.VectorObjects;\n\n// Find the closest matching vectors between the 2 documents\nvar bestMatches    = FindNearestSorted(vectorObjects1, vectorObjects2, 100);\n\n// And here they are\nforeach (var item in bestMatches)\n{\n    ShowMatch(true, item.Value.Item1, item.Value.Item2);\n}\n```\nNote that the FindNearestSorted is just a brute-force comparison of the (normalized) dot products between the query vector and all chunk vectors. For larger vector stores,  a database should be used that implements an indexing system for efficient nearest neighbour searches  [using something like this library](https://github.com/curiosity-ai/hnsw-sharp)\n\nHowever, not all closely matching vectors might constitute plagiarism. Luckily we have the LLM to compare the highest ranking vector in-porducts\n\n```cs\n// Format the query to post to the LLM:\nforeach (var item in bestMatches)\n{\n\tvar isPlagiarism = await FormulateComparisonAsync(item.Value.Item1, item.Value.Item2);\n}\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthijse%2Fplagiarismdetector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthijse%2Fplagiarismdetector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthijse%2Fplagiarismdetector/lists"}