Name: Towards AI Legal Name: Towards AI, Inc. Description: Towards AI is the world's leading artificial intelligence (AI) and technology publication. Read by thought-leaders and decision-makers around the world. Phone Number: +1-650-246-9381 Email: pub@towardsai.net
228 Park Avenue South New York, NY 10003 United States
Website: Publisher: https://towardsai.net/#publisher Diversity Policy: https://towardsai.net/about Ethics Policy: https://towardsai.net/about Masthead: https://towardsai.net/about
Name: Towards AI Legal Name: Towards AI, Inc. Description: Towards AI is the world's leading artificial intelligence (AI) and technology publication. Founders: Roberto Iriondo, , Job Title: Co-founder and Advisor Works for: Towards AI, Inc. Follow Roberto: X, LinkedIn, GitHub, Google Scholar, Towards AI Profile, Medium, ML@CMU, FreeCodeCamp, Crunchbase, Bloomberg, Roberto Iriondo, Generative AI Lab, Generative AI Lab Denis Piffaretti, Job Title: Co-founder Works for: Towards AI, Inc. Louie Peters, Job Title: Co-founder Works for: Towards AI, Inc. Louis-François Bouchard, Job Title: Co-founder Works for: Towards AI, Inc. Cover:
Towards AI Cover
Logo:
Towards AI Logo
Areas Served: Worldwide Alternate Name: Towards AI, Inc. Alternate Name: Towards AI Co. Alternate Name: towards ai Alternate Name: towardsai Alternate Name: towards.ai Alternate Name: tai Alternate Name: toward ai Alternate Name: toward.ai Alternate Name: Towards AI, Inc. Alternate Name: towardsai.net Alternate Name: pub.towardsai.net
5 stars – based on 497 reviews

Frequently Used, Contextual References

TODO: Remember to copy unique IDs whenever it needs used. i.e., URL: 304b2e42315e

Resources

Take our 85+ lesson From Beginner to Advanced LLM Developer Certification: From choosing a project to deploying a working product this is the most comprehensive and practical LLM course out there!

Publication

Dear IT Departments, Please Stop Trying To Build Your Own RAG
Artificial Intelligence   Latest   Machine Learning

Dear IT Departments, Please Stop Trying To Build Your Own RAG

Last Updated on November 14, 2024 by Editorial Team

Author(s): Alden Do Rosario

Originally published on Towards AI.

Look:

You would never ever in a million years build your own CRM system or custom CMS — or in most cases, your own LLM.

Would you?

And yet, everywhere I look, I see IT departments convincing themselves that building their own RAG-based chat is somehow different. It’s not. It’s actually worse.

Image Credit : Alden Do Rosario

Let me paint you a picture: Last week, I watched a team of brilliant engineers demo their shiny new RAG pipeline. All built in-house. They were proud. They were excited. They had vector embeddings! They had prompt engineering! They had… no idea what was coming.

And trust me, I’ve seen this movie before. Multiple times. It always ends the same way: with burned-out engineers, blown budgets, and a CTO wondering why they didn’t just buy a solution in the first place.

The “It Looks Simple” Trap

I get it. Really, I do. You look at RAG and think:

“Vector DB + LLM = Done!”

Throw in some open source tools, maybe some Langchain (oh, we’ll get to that), and you’re good to go, right?

Wrong. So, so wrong.

Let me tell you about a mid-market company I talked to recently. Their “simple” RAG project started in January. By March, they had:

  • 1 full-time engineer debugging hallucinations and accuracy problems.
  • 1 full-time data guy dealing with ETL and ingestion problems.
  • 1 full-time DevOps engineer fighting with scalability and infrastructure issues.
  • 1 very unhappy CTO looking at a budget that had tripled.

And that’s not even the worst part. The worst part was watching them slowly realize that what looked like a two-month project was actually going to become an ongoing nightmare.

Here’s are some of the things that they didn’t account for:

  • Document and knowledge base pre-processing complexity (try ingesting various data sources like Sharepoint, Google Drive and websites)
  • Document formats and all sorts of PDF issues (or try importing epub)
  • Accuracy issues in production (Oh wait — everything worked well in testing, but production usage in front of actual users sucks!)
  • Hallucinations!
  • Response quality assurance
  • Integration with existing systems
  • Change-data-capture (e.g. data on website changes, does the RAG remain in sync?)
  • Compliance and audit requirements
  • Security issues and data leakages (is your internal system going to be SOC-2 Type 2 compliant?)

Each one of these could be its own project. Each one has its own gotchas. Each one can blow up your timeline.

The Cost Nobody Talks About

“But we have the talent! We have the tools! Open source is free!”

Stop. Just stop.

Let me break down the real costs of your “free” RAG system:

Infrastructure Costs

  • Vector database hosting
  • Model inference costs
  • Development environments
  • Testing environments
  • Production environments
  • Backup systems
  • Monitoring systems

Personnel Costs

  • ML Engineers ($150k-$250k/year)
  • DevOps Engineers ($120k-$180k/year)
  • AI Security Specialists ($160k-$220k/year)
  • Quality Assurance ($90k-$130k/year)
  • Project Manager ($100k-$200k/year)

Ongoing Operational Costs

  • 24/7 monitoring
  • Security updates
  • Model upgrades
  • Data cleaning
  • Performance optimization
  • Documentation updates
  • Training for new team members
  • Compliance audits
  • Feature parity (as AI evolves)

And here’s the kicker: while you’re burning cash building all this, your competitors are already in production with their bought solution, spending a fraction of the cost.

Why you ask?

Because the purchased solution has been tested across thousands of customers. And the cost of building it too has been amortized across thousands of customers. In your case, the entire time + money cost has been “Divided by One

The Security Nightmare

Want to lose sleep? Try being responsible for an AI system that:

  • Has access to your company’s entire knowledge base
  • Could potentially leak sensitive information
  • Might hallucinate confidential data
  • Needs constant security updates
  • Could be vulnerable to prompt injection attacks
  • Might expose internal data through model responses
  • Could be susceptible to adversarial attacks

I recently spoke with a CISO who discovered their in-house RAG system was accidentally leaking internal document titles through its responses. Fun times. They spent three weeks fixing that one. Then they found five more similar issues.

And guess what? The threats evolve faster than your team can keep up with. Last month’s security measures might be obsolete today. The attack surface is constantly expanding, and the bad actors are getting more sophisticated.

Consider this: every new document you add to your knowledge base is a potential security risk. Every prompt is an attack vector. Every response needs to be screened. It’s not just about building a secure system — it’s about maintaining security in an environment that changes daily.

The Maintenance Horror Show

Remember that startup I mentioned that launched with Langchain? Here’s what happened next:

  • Week 1: Everything works great
  • Week 2: Latency issues
  • Week 3: Weird edge cases
  • Week 4: Complete rewrite
  • Week 5: New hallucination issues
  • Week 6: New data ingestion project.
  • Week 7: Vector DB migration and performance problems
  • Week 8: Another rewrite

They’re not alone. This is the typical lifecycle of an in-house RAG system. And it gets better (worse):

Daily Maintenance Tasks

  • Monitoring response quality
  • Checking for hallucinations
  • Debugging edge cases
  • Handling data processing issues.
  • Managing API quotas and infrastructure issues.

Weekly Maintenance Tasks

  • Performance optimization
  • Security audits
  • Data quality checks
  • User feedback analysis
  • System updates

Monthly Maintenance Tasks

  • Large-scale testing
  • AI model updates.
  • Compliance reviews
  • Cost optimization
  • Capacity planning
  • Architecture reviews
  • Strategy alignment
  • Feature requests.

And all of this needs to happen while you’re also trying to add new features, support new use cases, and keep the business happy.

The Expertise Gap

“But we have great engineers!”

Sure you do. But RAG isn’t just engineering. Let me break down what you actually need:

ML Operations

  • LLM Model deployment expertise
  • RAG pipeline management
  • Version control for models
  • Accuracy optimization
  • Resource management
  • Scaling knowledge

RAG Expertise

  • Understanding accuracy
  • Anti-hallucination optimization
  • Context window optimization.
  • Understanding latency and costs.
  • Prompt engineering
  • Quality metrics

Infrastructure Knowledge

  • Vector database optimization
  • Logging and monitoring.
  • API management
  • Cost optimization
  • Scaling architecture

Security Expertise

  • AI-specific security measures
  • Prompt injection prevention
  • Data privacy management
  • Access control
  • Audit logging
  • Compliance management

And good luck hiring for all that in this market. Even if you can find these people, can you afford them? Can you keep them? Because every other company is also looking for the same talent.

And more importantly: As other RAG platforms continue to improve their service and add more features and better KPIs like accuracy and anti-hallucination, will your RAG team do the same? Over the next 20 years?

The Time-to-Market Reality

While you’re building your RAG system:

  • Your competitors are deploying production solutions
  • The technology is evolving (sometimes weekly)
  • Your requirements are changing
  • Your business is losing opportunities
  • The market is moving forward
  • Your initial design is becoming obsolete
  • User expectations (tempered by OpenAI) are increasing daily.

Let’s talk about a real timeline for building a production-ready RAG system:

Month 1: Initial Development

  • Basic architecture
  • First prototype
  • Initial testing
  • Early feedback

Month 2: Reality Hits

  • Security issues emerge
  • Performance problems surface
  • Edge cases multiply
  • Requirements change

Month 3: The Rebuild

  • Architecture revisions
  • Security improvements
  • Performance optimization
  • Documentation catch-up

Month 4: Enterprise Readiness

  • Compliance implementation
  • Monitoring setup
  • Disaster recovery
  • User training

And that’s if everything goes well. Which it won’t. Just wait till things hit production!

The Buy Alternative

Look, I’m not saying never build. I’m saying be smart about what AND why you are building.

Image Credit: CustomGPT.ai

Modern RAG solutions provide:

Infrastructure Management

  • Scalable architecture
  • Automatic updates
  • Performance optimization
  • Security maintenance

Enterprise Features

  • Role-based access control
  • Audit logging
  • Compliance management
  • Data privacy controls

Operational Benefits

  • Expert support
  • Regular updates
  • Security patches
  • Performance monitoring

Business Advantages

  • Faster time-to-market
  • Lower total cost
  • Reduced risk
  • Proven solutions

When Should You Build?

Okay, fine. There are exactly three scenarios where building makes sense:

1. You have truly unique regulatory requirements that no vendor can meet

  • Custom government regulations
  • Specific industry compliance needs
  • Unique security protocols

2. You’re building RAG as your core product

  • It’s your main value proposition
  • You’re innovating in the space
  • You have deep expertise

3. You have unlimited time and money (if this is you, call me)

  • Seriously, though, this doesn’t exist
  • Even with resources, opportunity cost matters
  • Time-to-market still matters

Here’s What You Should Do Instead

1. Focus on your actual business problems

  • What are your users actually trying to achieve?
  • What are your unique value propositions?
  • Where can you make the biggest impact?

2. Choose a reliable RAG provider

  • Evaluate based on your needs (Hint: Look at case studies)
  • Check security credentials (Hint: Check for SOC-2 Type 2)
  • Verify enterprise readiness (Hint: Ask for case studies!)
  • Test performance (Hint: Look at published benchmarks)
  • Check support quality (Hint: Call support!)

3. Spend your engineering time on things that actually differentiate your business

  • Custom integrations
  • Unique features
  • Business logic
  • User experience

Because here’s the truth: In five years, no one will care if you built or bought your RAG system. They’ll only care if their pain point is solved.

The Bottom Line

Stop trying to reinvent the wheel. Especially when that wheel is actually a complex, AI-powered spacecraft that needs constant maintenance and could explode if you get the details wrong.

Building your own RAG system is like deciding to build your own email server in 2024. Sure, you could do it. But why would you want to?

Your future self will thank you. Your engineers will thank you. Your budget will thank you.

And most importantly, your business will thank you when you’re actually solving real problems instead of debugging accuracy problems at 3 AM.

The choice is yours. But please, choose wisely.

Join thousands of data leaders on the AI newsletter. Join over 80,000 subscribers and keep up to date with the latest developments in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming a sponsor.

Published via Towards AI

Feedback ↓

Sign Up for the Course
`; } else { console.error('Element with id="subscribe" not found within the page with class "home".'); } } }); // Remove duplicate text from articles /* Backup: 09/11/24 function removeDuplicateText() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, strong'); // Select the desired elements const seenTexts = new Set(); // A set to keep track of seen texts const tagCounters = {}; // Object to track instances of each tag elements.forEach(el => { const tagName = el.tagName.toLowerCase(); // Get the tag name (e.g., 'h1', 'h2', etc.) // Initialize a counter for each tag if not already done if (!tagCounters[tagName]) { tagCounters[tagName] = 0; } // Only process the first 10 elements of each tag type if (tagCounters[tagName] >= 2) { return; // Skip if the number of elements exceeds 10 } const text = el.textContent.trim(); // Get the text content const words = text.split(/\s+/); // Split the text into words if (words.length >= 4) { // Ensure at least 4 words const significantPart = words.slice(0, 5).join(' '); // Get first 5 words for matching // Check if the text (not the tag) has been seen before if (seenTexts.has(significantPart)) { // console.log('Duplicate found, removing:', el); // Log duplicate el.remove(); // Remove duplicate element } else { seenTexts.add(significantPart); // Add the text to the set } } tagCounters[tagName]++; // Increment the counter for this tag }); } removeDuplicateText(); */ // Remove duplicate text from articles function removeDuplicateText() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, strong'); // Select the desired elements const seenTexts = new Set(); // A set to keep track of seen texts const tagCounters = {}; // Object to track instances of each tag // List of classes to be excluded const excludedClasses = ['medium-author', 'post-widget-title']; elements.forEach(el => { // Skip elements with any of the excluded classes if (excludedClasses.some(cls => el.classList.contains(cls))) { return; // Skip this element if it has any of the excluded classes } const tagName = el.tagName.toLowerCase(); // Get the tag name (e.g., 'h1', 'h2', etc.) // Initialize a counter for each tag if not already done if (!tagCounters[tagName]) { tagCounters[tagName] = 0; } // Only process the first 10 elements of each tag type if (tagCounters[tagName] >= 10) { return; // Skip if the number of elements exceeds 10 } const text = el.textContent.trim(); // Get the text content const words = text.split(/\s+/); // Split the text into words if (words.length >= 4) { // Ensure at least 4 words const significantPart = words.slice(0, 5).join(' '); // Get first 5 words for matching // Check if the text (not the tag) has been seen before if (seenTexts.has(significantPart)) { // console.log('Duplicate found, removing:', el); // Log duplicate el.remove(); // Remove duplicate element } else { seenTexts.add(significantPart); // Add the text to the set } } tagCounters[tagName]++; // Increment the counter for this tag }); } removeDuplicateText(); //Remove unnecessary text in blog excerpts document.querySelectorAll('.blog p').forEach(function(paragraph) { // Replace the unwanted text pattern for each paragraph paragraph.innerHTML = paragraph.innerHTML .replace(/Author\(s\): [\w\s]+ Originally published on Towards AI\.?/g, '') // Removes 'Author(s): XYZ Originally published on Towards AI' .replace(/This member-only story is on us\. Upgrade to access all of Medium\./g, ''); // Removes 'This member-only story...' }); //Load ionic icons and cache them if ('localStorage' in window && window['localStorage'] !== null) { const cssLink = 'https://code.ionicframework.com/ionicons/2.0.1/css/ionicons.min.css'; const storedCss = localStorage.getItem('ionicons'); if (storedCss) { loadCSS(storedCss); } else { fetch(cssLink).then(response => response.text()).then(css => { localStorage.setItem('ionicons', css); loadCSS(css); }); } } function loadCSS(css) { const style = document.createElement('style'); style.innerHTML = css; document.head.appendChild(style); } //Remove elements from imported content automatically function removeStrongFromHeadings() { const elements = document.querySelectorAll('h1, h2, h3, h4, h5, h6, span'); elements.forEach(el => { const strongTags = el.querySelectorAll('strong'); strongTags.forEach(strongTag => { while (strongTag.firstChild) { strongTag.parentNode.insertBefore(strongTag.firstChild, strongTag); } strongTag.remove(); }); }); } removeStrongFromHeadings(); "use strict"; window.onload = () => { /* //This is an object for each category of subjects and in that there are kewords and link to the keywods let keywordsAndLinks = { //you can add more categories and define their keywords and add a link ds: { keywords: [ //you can add more keywords here they are detected and replaced with achor tag automatically 'data science', 'Data science', 'Data Science', 'data Science', 'DATA SCIENCE', ], //we will replace the linktext with the keyword later on in the code //you can easily change links for each category here //(include class="ml-link" and linktext) link: 'linktext', }, ml: { keywords: [ //Add more keywords 'machine learning', 'Machine learning', 'Machine Learning', 'machine Learning', 'MACHINE LEARNING', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, ai: { keywords: [ 'artificial intelligence', 'Artificial intelligence', 'Artificial Intelligence', 'artificial Intelligence', 'ARTIFICIAL INTELLIGENCE', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, nl: { keywords: [ 'NLP', 'nlp', 'natural language processing', 'Natural Language Processing', 'NATURAL LANGUAGE PROCESSING', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, des: { keywords: [ 'data engineering services', 'Data Engineering Services', 'DATA ENGINEERING SERVICES', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, td: { keywords: [ 'training data', 'Training Data', 'training Data', 'TRAINING DATA', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, ias: { keywords: [ 'image annotation services', 'Image annotation services', 'image Annotation services', 'image annotation Services', 'Image Annotation Services', 'IMAGE ANNOTATION SERVICES', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, l: { keywords: [ 'labeling', 'labelling', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, pbp: { keywords: [ 'previous blog posts', 'previous blog post', 'latest', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, mlc: { keywords: [ 'machine learning course', 'machine learning class', ], //Change your article link (include class="ml-link" and linktext) link: 'linktext', }, }; //Articles to skip let articleIdsToSkip = ['post-2651', 'post-3414', 'post-3540']; //keyword with its related achortag is recieved here along with article id function searchAndReplace(keyword, anchorTag, articleId) { //selects the h3 h4 and p tags that are inside of the article let content = document.querySelector(`#${articleId} .entry-content`); //replaces the "linktext" in achor tag with the keyword that will be searched and replaced let newLink = anchorTag.replace('linktext', keyword); //regular expression to search keyword var re = new RegExp('(' + keyword + ')', 'g'); //this replaces the keywords in h3 h4 and p tags content with achor tag content.innerHTML = content.innerHTML.replace(re, newLink); } function articleFilter(keyword, anchorTag) { //gets all the articles var articles = document.querySelectorAll('article'); //if its zero or less then there are no articles if (articles.length > 0) { for (let x = 0; x < articles.length; x++) { //articles to skip is an array in which there are ids of articles which should not get effected //if the current article's id is also in that array then do not call search and replace with its data if (!articleIdsToSkip.includes(articles[x].id)) { //search and replace is called on articles which should get effected searchAndReplace(keyword, anchorTag, articles[x].id, key); } else { console.log( `Cannot replace the keywords in article with id ${articles[x].id}` ); } } } else { console.log('No articles found.'); } } let key; //not part of script, added for (key in keywordsAndLinks) { //key is the object in keywords and links object i.e ds, ml, ai for (let i = 0; i < keywordsAndLinks[key].keywords.length; i++) { //keywordsAndLinks[key].keywords is the array of keywords for key (ds, ml, ai) //keywordsAndLinks[key].keywords[i] is the keyword and keywordsAndLinks[key].link is the link //keyword and link is sent to searchreplace where it is then replaced using regular expression and replace function articleFilter( keywordsAndLinks[key].keywords[i], keywordsAndLinks[key].link ); } } function cleanLinks() { // (making smal functions is for DRY) this function gets the links and only keeps the first 2 and from the rest removes the anchor tag and replaces it with its text function removeLinks(links) { if (links.length > 1) { for (let i = 2; i < links.length; i++) { links[i].outerHTML = links[i].textContent; } } } //arrays which will contain all the achor tags found with the class (ds-link, ml-link, ailink) in each article inserted using search and replace let dslinks; let mllinks; let ailinks; let nllinks; let deslinks; let tdlinks; let iaslinks; let llinks; let pbplinks; let mlclinks; const content = document.querySelectorAll('article'); //all articles content.forEach((c) => { //to skip the articles with specific ids if (!articleIdsToSkip.includes(c.id)) { //getting all the anchor tags in each article one by one dslinks = document.querySelectorAll(`#${c.id} .entry-content a.ds-link`); mllinks = document.querySelectorAll(`#${c.id} .entry-content a.ml-link`); ailinks = document.querySelectorAll(`#${c.id} .entry-content a.ai-link`); nllinks = document.querySelectorAll(`#${c.id} .entry-content a.ntrl-link`); deslinks = document.querySelectorAll(`#${c.id} .entry-content a.des-link`); tdlinks = document.querySelectorAll(`#${c.id} .entry-content a.td-link`); iaslinks = document.querySelectorAll(`#${c.id} .entry-content a.ias-link`); mlclinks = document.querySelectorAll(`#${c.id} .entry-content a.mlc-link`); llinks = document.querySelectorAll(`#${c.id} .entry-content a.l-link`); pbplinks = document.querySelectorAll(`#${c.id} .entry-content a.pbp-link`); //sending the anchor tags list of each article one by one to remove extra anchor tags removeLinks(dslinks); removeLinks(mllinks); removeLinks(ailinks); removeLinks(nllinks); removeLinks(deslinks); removeLinks(tdlinks); removeLinks(iaslinks); removeLinks(mlclinks); removeLinks(llinks); removeLinks(pbplinks); } }); } //To remove extra achor tags of each category (ds, ml, ai) and only have 2 of each category per article cleanLinks(); */ //Recommended Articles var ctaLinks = [ /* ' ' + '

Subscribe to our AI newsletter!

' + */ '

Take our 85+ lesson From Beginner to Advanced LLM Developer Certification: From choosing a project to deploying a working product this is the most comprehensive and practical LLM course out there!

'+ '

Towards AI has published Building LLMs for Production—our 470+ page guide to mastering LLMs with practical projects and expert insights!

' + '
' + '' + '' + '

Note: Content contains the views of the contributing authors and not Towards AI.
Disclosure: This website may contain sponsored content and affiliate links.

' + 'Discover Your Dream AI Career at Towards AI Jobs' + '

Towards AI has built a jobs board tailored specifically to Machine Learning and Data Science Jobs and Skills. Our software searches for live AI jobs each hour, labels and categorises them and makes them easily searchable. Explore over 10,000 live jobs today with Towards AI Jobs!

' + '
' + '

🔥 Recommended Articles 🔥

' + 'Why Become an LLM Developer? Launching Towards AI’s New One-Stop Conversion Course'+ 'Testing Launchpad.sh: A Container-based GPU Cloud for Inference and Fine-tuning'+ 'The Top 13 AI-Powered CRM Platforms
' + 'Top 11 AI Call Center Software for 2024
' + 'Learn Prompting 101—Prompt Engineering Course
' + 'Explore Leading Cloud Providers for GPU-Powered LLM Training
' + 'Best AI Communities for Artificial Intelligence Enthusiasts
' + 'Best Workstations for Deep Learning
' + 'Best Laptops for Deep Learning
' + 'Best Machine Learning Books
' + 'Machine Learning Algorithms
' + 'Neural Networks Tutorial
' + 'Best Public Datasets for Machine Learning
' + 'Neural Network Types
' + 'NLP Tutorial
' + 'Best Data Science Books
' + 'Monte Carlo Simulation Tutorial
' + 'Recommender System Tutorial
' + 'Linear Algebra for Deep Learning Tutorial
' + 'Google Colab Introduction
' + 'Decision Trees in Machine Learning
' + 'Principal Component Analysis (PCA) Tutorial
' + 'Linear Regression from Zero to Hero
'+ '

', /* + '

Join thousands of data leaders on the AI newsletter. It’s free, we don’t spam, and we never share your email address. Keep up to date with the latest work in AI. From research to projects and ideas. If you are building an AI startup, an AI-related product, or a service, we invite you to consider becoming a sponsor.

',*/ ]; var replaceText = { '': '', '': '', '
': '
' + ctaLinks + '
', }; Object.keys(replaceText).forEach((txtorig) => { //txtorig is the key in replacetext object const txtnew = replaceText[txtorig]; //txtnew is the value of the key in replacetext object let entryFooter = document.querySelector('article .entry-footer'); if (document.querySelectorAll('.single-post').length > 0) { //console.log('Article found.'); const text = entryFooter.innerHTML; entryFooter.innerHTML = text.replace(txtorig, txtnew); } else { // console.log('Article not found.'); //removing comment 09/04/24 } }); var css = document.createElement('style'); css.type = 'text/css'; css.innerHTML = '.post-tags { display:none !important } .article-cta a { font-size: 18px; }'; document.body.appendChild(css); //Extra //This function adds some accessibility needs to the site. function addAlly() { // In this function JQuery is replaced with vanilla javascript functions const imgCont = document.querySelector('.uw-imgcont'); imgCont.setAttribute('aria-label', 'AI news, latest developments'); imgCont.title = 'AI news, latest developments'; imgCont.rel = 'noopener'; document.querySelector('.page-mobile-menu-logo a').title = 'Towards AI Home'; document.querySelector('a.social-link').rel = 'noopener'; document.querySelector('a.uw-text').rel = 'noopener'; document.querySelector('a.uw-w-branding').rel = 'noopener'; document.querySelector('.blog h2.heading').innerHTML = 'Publication'; const popupSearch = document.querySelector$('a.btn-open-popup-search'); popupSearch.setAttribute('role', 'button'); popupSearch.title = 'Search'; const searchClose = document.querySelector('a.popup-search-close'); searchClose.setAttribute('role', 'button'); searchClose.title = 'Close search page'; // document // .querySelector('a.btn-open-popup-search') // .setAttribute( // 'href', // 'https://medium.com/towards-artificial-intelligence/search' // ); } // Add external attributes to 302 sticky and editorial links function extLink() { // Sticky 302 links, this fuction opens the link we send to Medium on a new tab and adds a "noopener" rel to them var stickyLinks = document.querySelectorAll('.grid-item.sticky a'); for (var i = 0; i < stickyLinks.length; i++) { /* stickyLinks[i].setAttribute('target', '_blank'); stickyLinks[i].setAttribute('rel', 'noopener'); */ } // Editorial 302 links, same here var editLinks = document.querySelectorAll( '.grid-item.category-editorial a' ); for (var i = 0; i < editLinks.length; i++) { editLinks[i].setAttribute('target', '_blank'); editLinks[i].setAttribute('rel', 'noopener'); } } // Add current year to copyright notices document.getElementById( 'js-current-year' ).textContent = new Date().getFullYear(); // Call functions after page load extLink(); //addAlly(); setTimeout(function() { //addAlly(); //ideally we should only need to run it once ↑ }, 5000); }; function closeCookieDialog (){ document.getElementById("cookie-consent").style.display = "none"; return false; } setTimeout ( function () { closeCookieDialog(); }, 15000); console.log(`%c 🚀🚀🚀 ███ █████ ███████ █████████ ███████████ █████████████ ███████████████ ███████ ███████ ███████ ┌───────────────────────────────────────────────────────────────────┐ │ │ │ Towards AI is looking for contributors! │ │ Join us in creating awesome AI content. │ │ Let's build the future of AI together → │ │ https://towardsai.net/contribute │ │ │ └───────────────────────────────────────────────────────────────────┘ `, `background: ; color: #00adff; font-size: large`); //Remove latest category across site document.querySelectorAll('a[rel="category tag"]').forEach(function(el) { if (el.textContent.trim() === 'Latest') { // Remove the two consecutive spaces (  ) if (el.nextSibling && el.nextSibling.nodeValue.includes('\u00A0\u00A0')) { el.nextSibling.nodeValue = ''; // Remove the spaces } el.style.display = 'none'; // Hide the element } }); // Add cross-domain measurement, anonymize IPs 'use strict'; //var ga = gtag; ga('config', 'G-9D3HKKFV1Q', 'auto', { /*'allowLinker': true,*/ 'anonymize_ip': true/*, 'linker': { 'domains': [ 'medium.com/towards-artificial-intelligence', 'datasets.towardsai.net', 'rss.towardsai.net', 'feed.towardsai.net', 'contribute.towardsai.net', 'members.towardsai.net', 'pub.towardsai.net', 'news.towardsai.net' ] } */ }); ga('send', 'pageview'); -->