Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.
Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.
AWS to Azure Migration: A Cloudy Journey of Challenges and Triumphs
Memory Leak Due to Time-Taking finalize() Method
Generative AI
AI technology is now more accessible, more intelligent, and easier to use than ever before. Generative AI, in particular, has transformed nearly every industry exponentially, creating a lasting impact driven by its (delivered) promises of cost savings, manual task reduction, and a slew of other benefits that improve overall productivity and efficiency. The applications of GenAI are expansive, and thanks to the democratization of large language models, AI is reaching every industry worldwide.Our focus for DZone's 2025 Generative AI Trend Report is on the trends surrounding GenAI models, algorithms, and implementation, paying special attention to GenAI's impacts on code generation and software development as a whole. Featured in this report are key findings from our research and thought-provoking content written by everyday practitioners from the DZone Community, with topics including organizations' AI adoption maturity, the role of LLMs, AI-driven intelligent applications, agentic AI, and much more.We hope this report serves as a guide to help readers assess their own organization's AI capabilities and how they can better leverage those in 2025 and beyond.
Machine Learning Patterns and Anti-Patterns
Getting Started With Data Quality
In fintech, APIs power everything. Starting from payments to trading to real-time customer experiences, the API takes care of everything. Performance isn't optional, but it's critical for user trust and business success. As a fintech API and cloud optimization expert, I constantly face the challenge of balancing quick development with high performance. When Microsoft announced GitHub Copilot for free, I asked myself a real-world question: Can GitHub Copilot go beyond writing boilerplate code and help optimize fintech Microservice APIs? Through a practical exercise on building and optimizing a real-world fintech microservice, we evaluate how GitHub Copilot accelerates development where expert judgment remains crucial. I used GitHub Copilot to: Build a high-throughput, stateless transaction API in Flask.Identify bottlenecks through load testing under realistic traffic.Apply AI-suggested performance improvements such as caching and concurrency enhancements.Compare Copilot's output with manual, industry-grade optimizations based on fintech best practices. Along the way, I will also highlight the strengths and limitations of AI-assisted coding, particularly in high-demand environments of fintech systems. Prerequisite Setup If you're new to Flask or need help setting up your development environment, check out my previous DZone article, where I walk through the full setup, installation, and basic app creation using GitHub Copilot. Once your Flask app environment is ready, continue here to focus on performance optimization for fintech-grade microservices. Step 1: Setting Up a Fintech Transaction API With GitHub Copilot 1. Create a New Flask Microservice Project (Setup instructions remain the same: create virtual environment, install Flask, enable Copilot.) 2. Let GitHub Copilot Generate the Transaction Processing Endpoint In the VSCode project, open routes.py (this is the file where the application's API routes would be generated by Copilot), type the comment below, and press enter. Then, we will see the API generated, which will be used for performance optimization. reStructuredText # Create a Flask API endpoint /process_transaction to process financial transactions. Accept account_id, amount, currency, transaction_type, timestamp. # Validate required fields, return success response with transaction details. Fintech realism: Handling transaction-specific fields properly. Step 2: Load Testing the Fintech API 1. Run the App Let's first begin with building and running the application locally by starting the Flask application. Python source venv/bin/activate export FLASK_APP="app:create_app" flask run Once the application is up and running, open another terminal in VSCode, where we will be triggering the load testing to analyze what is happening when 1000 transactions are requested concurrently. 2. Create a Realistic Payload File (transaction_data.json) Create a payload and place it under the project root directory. A sample JSON is shown below. JSON { "account_id": "ACC987654", "amount": 150.00, "currency": "USD", "transaction_type": "debit", "timestamp": "2025-04-25T10:30:00Z" } 3. Simulate Load With Apache Benchmark Open a new terminal parallel to the one that is running the Flask app. To evaluate how well the API handles multiple concurrent transaction requests, I have used Apache Benchmark (ab), a lightweight tool for simple load testing. The following command simulates 1000 transaction requests with 50 concurrent users against the /process_transaction endpoint. Python ab -n 1000 -c 50 -p transaction_data.json -T application/json http://127.0.0.1:5000/process_transaction Running 1000 transaction requests at a concurrency level of 50 gave me the following results: Requests per second: ~2715Mean time per request: ~18 ms99th percentile latency: ~45 msNo failed requests observed.No major CPU spikes at this basic processing level. This shows that, in a local development environment, even a basic Flask server can handle a high transaction rate, efficiently for simple payloads. However, in real fintech environments, API performance is lower due to additional layers like database read-write, encryption, network latencies, and compliance checks. APIs in a production environment would likely require further optimization, e.g., asynchronous handling, horizontal scaling, and caching layers to sustain similar throughput under real-world conditions. Step 3: Optimizing the Transaction API Using Copilot 1. Adding Caching to Improve Performance Adding caching is the standard approach that everyone, and even I, would take to improve the performance, but that is a standard approach we can use. Copilot would suggest using flask-caching to improve the performance. I left it to readers to try this option. However, we want to check for a production-ready application; when we prompt Copilot, what does it suggest? 2. Improving Concurrency With Gunicorn Prompted Copilot: # How to improve concurrency for production deployment, and press enter. We will see that the copilot suggests using Gunicorn, which is great! Now, let's stop or close the Flask terminal, which was still running. In a fresh terminal, let's install gunicorn and start the server. Python pip install gunicorn gunicorn -w 4 -b 127.0.0.1:5000 app:app We see that Copilot suggested a production-ready concurrency model (Gunicorn with workers) directly in the flow. The result: Handled far more concurrent requests smoothly and reduced processing time significantly. Running 1000 transaction requests in Gunicorn at a concurrency level of 50 resulted in: Requests per second: ~5602Mean time per request: ~8.9 ms99th percentile latency: ~15 msFailed requests: 0 We observe that: Requests/sec more than doubled compared to Flask Dev Server. Latency dropped from ~45ms to ~15ms. Server stability remained excellent. Step 4: Final Performance Benchmark Copilot-assisted caching and concurrency setups improved real-world throughput significantly under load. Metricflask dev server (before)gunicorn optimized (After) Requests/sec ~2715 ~5602 99th Percentile Latency ~45 ms ~15 ms CPU Usage Low to Moderate (locally) Optimized across workers Key Learnings (From API Tuning) Let me summarize the key learnings we saw and researched with Copilot's assistance, and when manual expertise was needed. areacopilot assistancemanual expertise needed Initial API Setup Generated fully None Transaction Field Handling Basic validation hints Stronger validation Caching Layer Flask-Caching suggested Redis in production (by most experts) Concurrency Setup Gunicorn suggestion Worker/memory tuning Security/Fraud Detection None Must design separately Conclusion Building high-performance APIs for fintech isn't just about functionality. It's about speed, reliability, and scale. GitHub Copilot accelerated initial development and suggested meaningful performance optimizations, such as caching and concurrency improvements. However, tuning for production readiness, scaling decisions, and security still require human expertise. The real advantage lies in vibe coding: Staying in flow, building fast, and applying best practices quickly. But by leaving critical architecture and risk assessment to experienced developers. While the optimizations showed minimal impact under a simple local setup initially, running the app behind Gunicorn demonstrated clear advantages. In production-grade fintech systems, such optimizations become essential to meet scalability, latency, and resilience requirements. Are you curious to see how AI-assisted development continues to evolve for fintech-grade performance? Stay tuned, we're just getting started.
Hey, DZone Community! We have an exciting year of research ahead for our beloved Trend Reports. And once again, we are asking for your insights and expertise (anonymously if you choose) — readers just like you drive the content we cover in our Trend Reports. Check out the details for our research survey below. Software Supply Chain Security Research Supply chains aren't just for physical products anymore; they're a critical part of how software is built and delivered. At DZone, we're taking a closer look at the state of software supply chain security to understand how development teams are navigating emerging risks through smarter tooling, stronger practices, and the strategic use of AI. Take our short research survey (~10 minutes) to contribute to our upcoming Trend Report. We're exploring key topics such as: SBOM adoption and real-world usageThe role of AI and ML in threat detectionImplementation of zero trust security modelsCloud and open-source security posturesModern approaches to incident response Join the Security Research We’ve also created some painfully relatable memes about the state of software supply chain security. If you’ve ever muttered “this is fine” while scanning dependencies, these are for you! Over the coming month, we will compile and analyze data from hundreds of respondents; results and observations will be featured in the "Key Research Findings" of our Trend Reports. Your responses help inform the narrative of our Trend Reports, so we truly cannot do this without you. Stay tuned for each report's launch and see how your insights align with the larger DZone Community. We thank you in advance for your help! —The DZone Content and Community team
Let’s talk about integration. Not the glossy vendor slide-deck version, but the messy, deeply architectural reality of connecting systems in the enterprise. Despite all our advances in tooling and frameworks, the way many organizations approach integration still hasn’t changed. Too often, we default to short-term fixes — point-to-point links, overstuffed middleware, or bespoke connectors — because they’re “fast.” But that speed comes at a price: brittle systems, tight coupling, and long-term technical debt that can paralyze change. In this article, we’ll look at why traditional integration strategies often fail and explore what a scalable, modern integration architecture really looks like. Spoiler: it starts with APIs, but it doesn’t end there. The Problem With Point-to-Point Integration Let’s start with the classic trap: point-to-point. It seems harmless at first. You need to sync data between System A and System B. A few lines of code, maybe a webhook or two, and you’re done. Then marketing wants analytics piped into System C. HR wants identity syncing with System D. Before long, you're stuck in a web of tightly coupled services that require tribal knowledge to maintain. Point-to-point integration doesn’t scale. It’s hard to test, hard to monitor, and almost impossible to reuse. Each new connection is a one-off contract — tightly scoped, undocumented, and often implemented inconsistently. You can’t version it. You can’t validate it centrally. And when you need to swap out a system, you’re left playing reverse Jenga. The irony? It feels productive. But what you’re really building is a distributed monolith. Middleware Can Obfuscate as Much as It Helps When point-to-point becomes unmanageable, the next step is usually middleware. Message buses, iPaaS tools, ETL frameworks — middleware promises to centralize and standardize integration. And to be fair, middleware can solve real problems. It provides abstraction layers, handles message routing, and can decouple producers from consumers. But here’s the trap: Abstraction without visibility creates chaos. Many middleware implementations become black boxes — difficult to debug, hard to document, and completely opaque to the teams that depend on them. Worse, they often centralize power into a single team (integration specialists), creating bottlenecks instead of enabling agility. Middleware isn’t magic. It’s just code you didn’t write — and still have to understand. Why Silos Persist (Even in “Integrated” Systems) Integration is supposed to break down silos. But all too often, we just build new silos with more sophisticated tooling. Silos form when teams optimize for their own goals without aligning on shared data models, APIs, or contracts. Even if everything is technically connected, if each integration is bespoke or opaque, your architecture lacks cohesion. The result? Fragile dependencies. Inconsistent data flows. A support team drowning in service tickets every time someone updates a schema. Real integration doesn’t just “connect systems” — it aligns them. The API-First Mindset: A Better Foundation So, how do we get this right? The answer is an API-first architecture — not “APIs as an afterthought,” not “we added a REST endpoint.” But a design approach where every system, service, and component is built with an API contract at the center. An API-first mindset has several advantages: Loose coupling: Systems interact via well-defined interfaces, not hidden internal state.Composability: You can stitch together services without rework.Testability: APIs are inherently testable, versionable, and observable.Developer autonomy: Teams can consume or expose APIs independently without waiting on centralized integration teams. By making APIs your integration surface, you build systems that are transparent, predictable, and maintainable. You stop hardwiring logic between systems and start building service contracts that evolve gracefully. It’s Not Just the API — It’s the Architecture Around It Of course, building an API doesn’t solve integration by itself. You need the supporting architecture: Governance: How are APIs discovered, authenticated, and versioned?Monitoring: Do you have observability into request/response cycles, latency, and errors?Orchestration: Can you compose APIs into workflows and data pipelines?Security: Are APIs protected with modern auth protocols and access control? This is where many organizations fall short. They build APIs, but don’t treat them as first-class citizens in the software lifecycle. Without tooling, automation, and standardization, APIs devolve into another kind of chaos. Integration at scale means treating interfaces as infrastructure. APIs aren’t just features—they’re architectural pillars. From Quick Fixes to Sustainable Patterns When someone says, “We just need to sync these two systems,” it’s tempting to reach for the nearest script, adapter, or webhook. But integration isn’t a one-off task. It’s a discipline — an architectural practice that determines how flexible and future-proof your systems really are. The next time you’re staring down an integration project, ask: What’s the contract?How is this testable?Can this be reused by another team?What happens when one side changes? Shortcuts now often lead to pain later. Building with APIs — and building the right infrastructure and discipline around them — is how you create integrations that don’t break every time your business changes. Integration Done Right Modern enterprises don’t run on isolated systems. They run on networks of services — each communicating, sharing data, and triggering workflows. When those connections are brittle, every change becomes a risk. When those connections are robust, change becomes a superpower. So yes, integration is hard. But it’s not supposed to be duct tape. It’s supposed to be architecture. And that architecture? It starts with APIs.
Security researchers and developers are raising alarms over “slopsquatting,” a new form of supply chain attack that leverages AI-generated misinformation commonly known as hallucinations. As developers increasingly rely on coding tools like GitHub Copilot, ChatGPT, and DeepSeek, attackers are exploiting AI’s tendency to invent software packages, tricking users into downloading malicious content. What is Slopsquatting? The term slopsquatting was originally coined by Seth Larson, a developer with the Python Software Foundation, and later popularized by tech security researcher Andrew Nesbitt. It refers to cases where attackers register software packages that don’t actually exist, but are mistakenly suggested by AI tools; once live, these fake packages can contain harmful code. If a developer installs one of these without verifying it — simply trusting the AI — they may unknowingly introduce malicious code into their project, giving hackers backdoor access to sensitive environments. Unlike typosquatting, where malicious actors count on human spelling mistakes, slopsquatting relies entirely on AI’s flaws and developers' misplaced trust in automated suggestions. AI-Hallucinated Software Packages Are on the Rise This issue is more than theoretical. A recent joint study by researchers at the University of Texas at San Antonio, Virginia Tech, and the University of Oklahoma analyzed more than 576,000 AI-generated code samples from 16 large language models (LLMs). They found that nearly 1 in 5 packages suggested by AI didn’t exist. “The average percentage of hallucinated packages is at least 5.2% for commercial models and 21.7% for open-source models, including a staggering 205,474 unique examples of hallucinated package names, further underscoring the severity and pervasiveness of this threat,” the study revealed. Even more concerning, these hallucinated names weren’t random. In multiple runs using the same prompts, 43% of hallucinated packages consistently reappeared, showing how predictable these hallucinations can be. As explained by the security firm Socket, this consistency gives attackers a roadmap — they can monitor AI behavior, identify repeat suggestions, and register those package names before anyone else does. The study also noted differences across models: CodeLlama 7B and 34B had the highest hallucination rates of over 30%; GPT-4 Turbo had the lowest rate at 3.59%. How Vibe Coding Might Increase This Security Risk A growing trend called vibe coding, a term coined by AI researcher Andrej Karpathy, may worsen the issue. It refers to a workflow where developers describe what they want, and AI tools generate the code. This approach leans heavily on trust — developers often copy and paste AI output without double-checking everything. In this environment, hallucinated packages become easy entry points for attackers, especially when developers skip manual review steps and rely solely on AI-generated suggestions. How Developers Can Protect Themselves To avoid falling victim to slopsquatting, experts recommend: Manually verifying all package names before installation.Using package security tools that scan dependencies for risks.Checking for suspicious or brand-new libraries.Avoiding copy-pasting install commands directly from AI suggestions. Meanwhile, there is good news: some AI models are improving in self-policing. GPT-4 Turbo and DeepSeek, for instance, have shown they can detect and flag hallucinated packages in their own output with over 75% accuracy, according to early internal tests.
When using the Go SDK for the Azure Cosmos DB NoSQL API, I often find myself writing boilerplate code for various operations. This includes database/container operations, querying, and more. The cosmosdb-go-sdk-helper (I know, not a great name!) is a package with convenience functions for some of these tasks. In this blog post, I will go over the packages in the repository with examples on how (and when) you can use them. It's early days for this project, but I hope to keep adding to it gradually. Overview auth: Simplifies authentication for both production and local development.common: Helps with common database and container operations.query: Offers type-safe, generic query helpers and optional metrics, and helps with Cosmos DB query metrics.functions: Eases the parsing of Azure Functions Cosmos DB trigger payloads.cosmosdb_errors: Extracts structured error information for simple error handling. Quick Start To get started, install the package: Go go get github.com/abhirockzz/cosmosdb-go-sdk-helper Try it out using the example below: Go package main import ( "fmt" "log" "github.com/abhirockzz/cosmosdb-go-sdk-helper/auth" "github.com/abhirockzz/cosmosdb-go-sdk-helper/common" "github.com/abhirockzz/cosmosdb-go-sdk-helper/query" ) func main() { endpoint := "https://ACCOUNT_NAME.documents.azure.com:443" type Task struct { ID string `json:"id"` Info string `json:"info"` } client, err := auth.GetCosmosDBClient(endpoint, false, nil) if err != nil { log.Fatalf("Azure AD auth failed: %v", err) } container, err := client.NewContainer(databaseName, containerName) if err != nil { log.Fatalf("NewContainer failed: %v", err) } task := Task{ ID: "45", Info: "Sample task", } insertedTask, err := common.InsertItemWithResponse(container, task, azcosmos.NewPartitionKeyString(task.ID), nil) if err != nil { log.Fatalf("InsertItem failed: %v", err) } fmt.Printf("Inserted task: %s (%s)\n", insertedTask.ID, insertedTask.Info) tasks, err := query.QueryItems[Task](container, sqlQuery, azcosmos.NewPartitionKey(), nil) if err != nil { log.Fatalf("QueryItems failed: %v", err) } for _, task := range tasks { fmt.Printf("Task: %s (%s)\n", task.ID, task.Info) } Let's quickly go over the packages. Authentication (auth) The auth package gets authenticated Cosmos DB client handle for both Azure AD and local Cosmos DB emulator. It simplifies the process, making it easier to switch between production and local development environments. Example When connecting to actual Cosmos DB endpoint, function uses DefaultAzureCredential. DefaultAzureCredential uses an ordered sequence of mechanisms for authentication (including environment variables, managed identity, Azure CLI credential etc.). Go client, err := auth.GetCosmosDBClient("https://your-account.documents.azure.com:443", false, nil) if err != nil { log.Fatalf("Azure AD auth failed: %v", err) When using the emulator, simply set useEmulator flag to true and pass the emulator URL (e.g. http://localhost:8081) without changing anything else. Go client, err := auth.GetCosmosDBClient("http://localhost:8081", true, nil) if err != nil { log.Fatalf("Emulator auth failed: %v", err) } Database and Container Operations (common) The common package lets you to create databases and containers only if they don't already exist. This is useful for idempotent resource management, especially in CI/CD pipelines. It also provides other utility functions, such as listing all databases and containers, etc. Example Go props := azcosmos.DatabaseProperties{ID: "tododb"} db, err := common.CreateDatabaseIfNotExists(client, props, nil) containerProps := azcosmos.ContainerProperties{ ID: "tasks", PartitionKeyDefinition: azcosmos.PartitionKeyDefinition{ Paths: []string{"/id"}, Kind: azcosmos.PartitionKeyKindHash, }, } container, err := common.CreateContainerIfNotExists(db, containerProps, nil) This is also goroutine-safe (can be used with concurrent programs), so you can run it in multiple instances without worrying about race conditions since its idempotent. Query Operations (query) The query package provides generic helpers for querying multiple or single items, returning strongly-typed results. This eliminates the need for manual unmarshalling and reduces boilerplate code. Example Go type Task struct { ID string `json:"id"` Info string `json:"info"` } tasks, err := query.QueryItems[Task](container, "SELECT * FROM c", azcosmos.NewPartitionKey(), nil) // Query a single item task, err := query.QueryItem[Task](container, "item-id", azcosmos.NewPartitionKeyString("item-id"), nil) Query Metrics (metrics) You can use the metrics package to conveniently execute queries and the get results as a Go struct (that includes the metrics). Example Go // Query with metrics result, err := query.QueryItemsWithMetrics[Task](container, "SELECT * FROM c WHERE c.status = 'complete'", azcosmos.NewPartitionKey(), nil) for i, metrics := range result.Metrics { fmt.Printf("Page %d: TotalExecutionTimeInMs=%f\n", i, metrics.TotalExecutionTimeInMs) } You can also parse the metrics string manually using ParseQueryMetrics: Go qm, err := metrics.ParseQueryMetrics("totalExecutionTimeInMs=12.5;queryCompileTimeInMs=1.2;...") fmt.Println(qm.TotalExecutionTimeInMs, qm.QueryCompileTimeInMs) The QueryItemsWithMetrics uses ParseQueryMetrics behind the scenes to parse the metrics string. It also provides a ParseIndexMetrics function that parses the index metrics string returned by Cosmos DB (decodes base64-encoded index metrics from query responses): Go indexMetrics, err := metrics.ParseIndexMetrics("base64-encoded-index-metrics") Azure Functions Triggers (functions/trigger) When using Azure Cosmos DB triggers with Azure Functions written in Go (using Custom handlers), you will need to make sense of the raw payload sent by Azure Functions. The payload contains the changed documents in a nested JSON format. The functions/trigger package simplifies this by providing helpers to parse the payload into a format you can use directly in your function. You can use ParseToCosmosDBDataMap to directly get the Cosmos DB documents data as a []map[string]any, which is flexible and easy to work with. Example Go // from the Azure Function trigger payload := `{"Data":{"documents":"\"[{\\\"id\\\":\\\"dfa26d32-f876-44a3-b107-369f1f48c689\\\",\\\"description\\\":\\\"Setup monitoring\\\",\\\"_rid\\\":\\\"lV8dAK7u9cCUAAAAAAAAAA==\\\",\\\"_self\\\":\\\"dbs/lV8dAA==/colls/lV8dAK7u9cA=/docs/lV8dAK7u9cCUAAAAAAAAAA==/\\\",\\\"_etag\\\":\\\"\\\\\\\"0f007efc-0000-0800-0000-67f5fb920000\\\\\\\"\\\",\\\"_attachments\\\":\\\"attachments/\\\",\\\"_ts\\\":1744173970,\\\"_lsn\\\":160}]\""},"Metadata":{"sys":{"MethodName":"cosmosdbprocessor","UtcNow":"2025-04-09T04:46:10.723203Z","RandGuid":"0d00378b-6426-4af1-9fc0-0793f4ce3745"}}` docs, err := trigger.ParseToCosmosDBDataMap(payload) Alternatively, you can use ParseToRawString to get the raw JSON string and then unmarshal it into your own struct. This is useful if you can define the structure of the data you expect and want to work with it in a more type-safe manner. Example Go // from the Azure Function trigger payload := `{"Data":{"documents":"\"[{\\\"id\\\":\\\"dfa26d32-f876-44a3-b107-369f1f48c689\\\",\\\"description\\\":\\\"Setup monitoring\\\",\\\"_rid\\\":\\\"lV8dAK7u9cCUAAAAAAAAAA==\\\",\\\"_self\\\":\\\"dbs/lV8dAA==/colls/lV8dAK7u9cA=/docs/lV8dAK7u9cCUAAAAAAAAAA==/\\\",\\\"_etag\\\":\\\"\\\\\\\"0f007efc-0000-0800-0000-67f5fb920000\\\\\\\"\\\",\\\"_attachments\\\":\\\"attachments/\\\",\\\"_ts\\\":1744173970,\\\"_lsn\\\":160}]\""},"Metadata":{"sys":{"MethodName":"cosmosdbprocessor","UtcNow":"2025-04-09T04:46:10.723203Z","RandGuid":"0d00378b-6426-4af1-9fc0-0793f4ce3745"}}` rawStringData, err := trigger.ParseToRawString(payload) type Task struct { ID string `json:"id"` Description string `json:"description"` } var documents []Task err := json.Unmarshal([]byte(rawStringData), &documents) Error Handling (cosmosdb_errors) The cosmosdb_errors package extracts status code and message from Cosmos DB SDK errors and returns a struct for easier downstream handling. I expect to improve/add to this. Example Go if err != nil { cosmosErr := cosmosdb_errors.GetError(err) if cosmosErr.Status == http.StatusNotFound { // Handle not found } else { // Handle other errors } } Conclusion Like I mentioned, its still early days and the cosmosdb-go-sdk-helper package provides simple convenience functions for common tasks to help reduce boilerplate. I expect to keep adding to it gradually, so if you have any suggestions or features you'd like to see, please open an issue. Resources Azure Cosmos DB Go SDK for API for NoSQLcosmosdb-go-sdk-helper
TL; DR: Ethical AI in Agile Agile teams face ethical challenges. However, there is a path to Ethical AI in Agile by establishing four pragmatic guardrails: Data Privacy (information classification), Human Value Preservation (defining AI vs. human roles), Output Validation (verification protocols), and Transparent Attribution (contribution tracking). This lightweight framework integrates with existing practices, protecting sensitive data and human expertise while enabling teams to confidently realize AI benefits without creating separate bureaucratic processes. Ethical AI in Agile Needs Scrum Masters as Guardians Agile practitioners are deeply concerned about Ethical AI in Agile, not as distant fears but as immediate challenges. In a recent survey I conducted with Agile professionals, respondents revealed widespread concerns about data privacy (“How to make sure I do not leak confidential information”), job security (“Will my dev colleagues just be AI machines? What is my job then as a Scrum master?”), and output reliability (“How can I evaluate the quality and correctness of results?”). My survey’s open-ended question about ethical concerns in AI and Agile uncovered remarkably consistent themes. Data privacy consistently emerged as the top concern, followed by job security anxiety and questions about AI reliability. These insights directly inform the guardrails presented in this article. Scrum Masters are uniquely positioned to address these concerns by establishing practical AI boundaries. Rather than becoming “AI police,” they can serve as ethical compasses, creating lightweight guardrails that integrate naturally with existing Agile practices. These guardrails ensure AI enhances rather than undermines Agile values, team effectiveness, and individual contributions. This approach isn’t about comprehensive AI governance — it’s about the pragmatic, immediate implementation of ethical boundaries that protect what matters most: sensitive data, human expertise, and work integrity. The Four Critical Guardrails for Ethical AI in Agile 1. Data Privacy and Compliance Guardrail The Challenge My survey data reveals this as practitioners’ #1 concern, with specific worries about protecting confidential information, GDPR, and EU AI Act compliance. As one respondent noted, “Data input usage by AI creators for machine learning: How do I make sure I do not leak confidential information?” Key Implementation Elements Data classification system (Public, Internal, Confidential, Restricted),Clear protocols for sanitizing inputs before sharing with external AI tools,Compliance checklists for different regulatory environments,Technical approaches to minimize data exposure. Why It Matters Ignoring this guardrail exposes the organization to significant legal, financial, and reputational damage, directly contravening Agile’s emphasis on trust and value delivery. Practical Implementation Approach Create a simple red/yellow/green classification system: Green: General Agile practices, non-proprietary knowledge,Yellow: Anonymized project elements requiring leader review,Red: Confidential data never to be shared with external AI. Example in Action A Scrum team creates a “data sensitivity categorization system” for product and project information. User story templates were classified as “public” (shareable with AI), specific feature descriptions as “internal” (requiring anonymization), and customer data as “restricted” (never shared). This system is embedded in their Definition of Done, requiring explicit verification that no restricted data was exposed during AI interactions. 2. Human Value Preservation Guardrail The Challenge Survey respondents expressed significant anxiety about AI replacing their roles: “Do we need an SM as we can just use ChatGPT,” and “How do we use AI to help ‘AI-proof’ our jobs from elimination?” Key Implementation Elements Clear delineation between AI-appropriate and human-essential activities,Protocols that position AI as enhancing rather than replacing practitioners,Identification of uniquely human elements of Agile roles,Team agreements about when human judgment takes precedence. Why It Matters Without this guardrail, teams risk over-delegating to AI, diminishing the human elements that make Agile effective, and creating anxiety that reduces engagement and creativity. Practical Implementation Approach Create a “human-AI partnership framework” that explicitly identifies: AI-optimal tasks: Routine documentation, initial draft creation, pattern recognition,Human-optimal areas: Stakeholder relationship building, conflict resolution, values-based decisions,Partnership activities: Areas where human direction and AI assistance create the best results. Example in Action A product team experiences anxiety about AI replacing team members and creates a “human-AI partnership framework” visualized as a spectrum. For example, AI might help generate initial user story drafts, but humans would lead stakeholder conversations to uncover needs. Implementing this framework may lead to team members feeling more secure about their unique contributions and more strategic about when to leverage AI assistance. 3. Output Validation Guardrail The Challenge Practitioners in my survey expressed significant concerns about AI reliability, noting “simply wrong responses” and asking, “At what point can you feel like AI output is reliable?” Key Implementation Elements Verification protocols for different types of AI outputs,Team practices for critical assessment of AI-generated content,Systems to track and improve AI reliability over time,Procedures for handling identified AI errors or hallucinations. Why It Matters Without systematic validation, teams risk implementing incorrect solutions, making decisions based on false information, and gradually losing trust in both AI and human oversight. Practical Implementation Approach Implement a “triangulation protocol” requiring: Independent verification from existing documentation or team knowledge,Clear marking of AI-generated content until verified,Tracking of reliability patterns to identify high-risk vs. low-risk use cases. Example in Action Developers require technical recommendations by AI to be verified against either existing documentation or a second team member’s confirmation. The team maintains a simple log of verification results, allowing them to identify which tasks are most appropriate for AI assistance. This approach has the potential to catch potential issues before implementation while still allowing the team to benefit from AI’s strengths. 4. Transparent Attribution Guardrail The Challenge Survey respondents raised concerns about intellectual property and disclosure, questioning “How to protect your company’s IP from being learned from” and whether “everyone should know when AI is involved in the loop.” Key Implementation Elements Clear disclosure standards for AI-generated content,Intellectual property protection protocols,Methods to maintain authenticity in AI-augmented communication,Documentation of AI contribution to work products. Why It Matters Without transparency, teams risk intellectual property disputes, erosion of stakeholder trust, and loss of authentic human voice in communications — all core elements of Agile’s emphasis on transparency and trust. Practical Implementation Approach Create an “AI contribution registry” documenting: Which elements were AI-generated vs. human-created,What source material was provided to the AI,How AI suggestions were modified before implementation,Appropriate attribution in final deliverables. Example in Action UX designers may use AI for design ideation to create a simple “contribution registry” documenting the provenance of different elements. If AI generates more than 50% of the content for customer-facing materials, they disclose it to stakeholders. For internal content, they maintained records of which components were AI-assisted in their design system. This practice helps them to maintain stakeholder trust while ensuring appropriate attribution. When a stakeholder questions a particular design approach, the team can immediately clarify which aspects were human-directed versus AI-suggested, building credibility. Implementing Ethical AI in Agile in Regulated Environments My survey respondents specifically highlighted challenges in governmental and regulated contexts, noting “Limitations of use in governmental context” and “unsure if I’m allowed to use AI for my work at a government agency.” For Teams With Strict Prohibitions Identify AI tools approved for organizational use,Create clear guidance on information that cannot be shared,Explore on-premises or private cloud solutions where appropriate,Develop fallback processes for scenarios where AI cannot be used. For Teams With Evolving Policies Document assumptions and decisions about AI use,Implement stringent verification protocols,Create transparency with compliance stakeholders,Regularly review practices as organizational policies evolve. Key Questions for Regulated Environments What specific regulations govern our data and AI use?Which AI tools are approved for organizational use?What verification is required before implementing AI suggestions?Who needs to be informed about AI use in our deliverables?What documentation must we maintain about AI interactions? Practical Next Steps for Ethical AI in Agile: Getting Started With Guardrails Begin implementing ethical guardrails with these focused activities to avoid AI usage from becoming opportunistic and getting out of hand quickly: 0. Team Buy-in and Context Setting (30 Minutes) Share survey findings about practitioner concerns,Discuss specific team worries about AI ethics,Establish a shared understanding of ethical guardrail benefits,Gain commitment to initial implementation. 1. Data Classification Workshop (Initial Session: 1-2 Hours) Identify types of information your team works with,Create simple categories (public, internal, confidential, restricted),Define clear rules for what can be shared with AI tools,Document in a visible, accessible format. 2. Human-AI Partnership Mapping (Initial Session: 1-2 Hours) Identify team activities that benefit from AI assistance,Clarify which aspects must remain primarily human-driven,Create a visual spectrum of appropriate AI involvement,Discuss anxieties and address concerns openly. 3. Verification Protocol Design (Initial Session: 1 Hour, With Refinement) Define verification requirements for different AI outputs,Create simple checklists for common AI use cases,Establish tracking for reliability patterns,Integrate into the Definition of Done. 4. Adding AI to Your Working Agreement (Initial Session: 1-2 Hours) Draft guidelines for when and how AI should be used,Define disclosure requirements for AI-generated content,Clarify how AI contributions should be documented,Establish an escalation path for ethical concerns. 5. Retrospective Integration (15-30 Minutes) Add “Ethical AI Use” as a regular retrospective topic,Create simple prompts to evaluate guardrail effectiveness,Celebrate successful ethical AI practices,Continuously improve based on team experience. The Benefits of Ethical AI Guardrails Implementing these Ethical AI in Agile guardrails delivers significant benefits: For Scrum Masters and Agile Coaches, they represent an opportunity for substantial role enhancement, positioning you as a forward-thinking leader in AI adoption within your organization. You’ll develop specialized expertise in ethical AI implementation that is increasingly valued by organizations navigating digital transformation. This proactive approach to Ethical AI in Agile helps you mitigate risks by preventing issues before they damage the team’s reputation or create regulatory concerns. Perhaps most importantly, you’ll gain greater confidence in navigating ambiguous situations with clear ethical guidelines, transforming uncertainty into structured decision-making. For Agile teams, implementing ethical guardrails creates psychological safety by establishing clarity about appropriate AI use in different contexts. This approach promotes balanced adoption, preventing over-reliance on AI for decisions requiring human judgment and under-utilizing AI where it could provide significant value. Teams develop consistent practices across members, establishing a shared understanding that reduces confusion and improves coordination. The guardrails enable innovation within boundaries, allowing teams to experiment creatively with AI while maintaining the ethical foundations that protect team members, customers, and the organization. For organizations, Ethical AI in Agile guardrails provides substantial risk reduction by mitigating legal, reputational, and operational risks associated with unchecked AI adoption. They ensure cultural alignment by connecting AI implementation directly to organizational values and principles. These frameworks position the organization for regulatory readiness, staying ahead of emerging AI regulations rather than scrambling to comply retroactively. Perhaps most critically, ethical guardrails maintain customer trust by preserving the integrity of products and services, ensuring that AI enhances rather than compromises the organization’s commitment to its customers. Mitigating Common Resistance Points You may encounter these objections when implementing ethical guardrails: “This will slow us down with bureaucracy.” Start with minimal viable guardrails focused on the highest risk areas and demonstrate value through risk prevention and efficiency. “AI ethics is too abstract and philosophical.” Focus on concrete, practical guidelines relevant to daily work. Connect to existing team values and principles. “This isn’t the Scrum Master’s domain.” Connect to core Scrum Master responsibilities of process health and impediment prevention, positioning it as an enhancement of the existing role. “We’re too small/early to worry about Ethical AI in Agile.” Demonstrate how early ethical guidance prevents rework and reputation damage. Start with a lightweight implementation. “The AI tools already handle ethics.” Illustrate gaps in commercial AI tools’ ethical safeguards. Show examples of potential issues specific to your context. Contextual Integration: A Complementary Approach For teams seeking to deepen their ethical AI practices, “Contextual AI Integration” offers a complementary framework that naturally reinforces these guardrails. It: Provides minimal necessary context for specific tasks, reducing data exposure risk,Creates clear situational framing for AI use, preserving human judgment,Connects AI to existing artifacts like Definition of Done, embedding ethical considerations,Establishes AI Working Agreements that can incorporate ethical boundaries. Conclusion: From Tools to Ethical Partners The path to effective AI integration for Agile teams requires deliberate, ethically bound practices that respect AI limitations and Agile values. By implementing these four guardrails — Data Privacy and Compliance, Human Value Preservation, Output Validation, and Transparent Attribution — Scrum Masters ensure AI enhances rather than undermines the human excellence at the heart of Agile. As one respondent in my survey asked: “How do we ensure AI is reflective of our thoughts and values?” These ethical guardrails provide a practical answer, not through abstract principles but through concrete practices embedded in daily Agile work. Start today. Pick one high-risk area or one concerned team member, and begin the conversation. Your first step might be scheduling the “Data Classification Workshop” outlined above. The Scrum Master who establishes these guardrails becomes not just a process facilitator but an ethical compass, helping their team navigate the complex terrain of AI-enhanced Agile with integrity, confidence, and purpose.
Retrieval-augmented generation (RAG) may sound complex, but it accurately represents the process of the system. RAG is a method that enhances the capabilities of large language models (LLMs) by integrating them with external knowledge sources. Each term represents a piece of the puzzle: Retrieval – data retrieved from some external source outside the LLM (most often a database, but can include files, webpages, etc)Augmented – "augmenting" (or adding to) an LLM's training data. This could include recent or private information that it did not have access to during its training period. Most often, this is done by adding the data to the prompt (or input) to the LLM.Generation – this is where LLMs are exceptional. They generate a response (text, image, video, etc.) that is similar to the data being provided in the input. This is generated from probabilities, so it cannot guarantee 100% consistency. Instead of relying solely on the model's internal training data, RAG retrieves relevant information from databases or document collections to ground its responses in factual and up-to-date content. This approach not only improves the accuracy and reliability of the generated outputs but also allows the system to adapt to specific contexts or domains, making it a powerful tool for many personal and professional applications. In this post, we will define each component and how it works together in a RAG system. Why RAG? Retrieval-augmented generation (RAG) solves a few different problems in the technical space. 1. It provides a way to dynamically add data/information to (augment) an LLM's knowledge, improving relevance and accuracy in answers. 2. It provides searchable access to all types of data storage, including database types, text, images, audio, video, webpages, etc. 3. It allows technical experts to guide or limit the AI with defined tools, high-quality data, rules, business logic, and more. This increases accuracy and reduces risk of the system. Large Language Models (LLMs) Part of the generative AI field, large language models (LLMs) are advanced AI systems designed to generate content by predicting the probabilities of sequences within their input data. They excel at understanding context and producing coherent outputs, making them versatile tools for a wide range of applications. However, they also have limitations. LLMs generate responses on probabilities, leaving room for inconsistency or uncertainty, especially when there are multiple potential answers and no high probability for any of the options. These models can process various types of input/output (modalities), but their performance is constrained by the size of their context windows — the amount of information they can consider at once — and the quality of the prompts provided. Note: Each LLM is trained slightly differently to prioritize certain probabilities over others to optimize for certain goals. This is why every LLM may produce different outputs for the same input and why you should evaluate different models and research which ones might be pre-optimized for your needs. There are a variety of reasons that Large Language Models tend to hallucinate (or produce inaccurate, nonsensical answers). A few of those include the following: Searching for answers related to recent or private data that the LLM has not been trained on or has access to.The prompt (input) traverses gaps or limits in the LLMs "knowledge" pathways, getting stuck or not enough next thoughts to generate.The LLM does not have enough context (background information) to guide its answer towards a specific path (too much uncertainty in the input's meaning). How do we improve these weaknesses by providing context to the LLM? Vector Embeddings A vector is a mathematical concept representing a line that has a size (magnitude) and direction. This numeric representation allows us to make calculations and comparisons to explain forces in physics. In the real world, we use vectors for a couple of relatable use cases. Airplane flight paths in 3-dimensional space. If you think about a flight path, there may be landmark features along it, such as buildings, rivers, and airspaces (military, city, or airport restriction areas). Planes also need to take external factors into account, such as wind and storms. Not only do they need a representation of where they are in the air, but they also need to be able to calculate changes to that flight path due to obstacles or real-time airspace restrictions. They do this by creating a numeric representation (vector) of that path and calculating with other vectors for winds, weather areas, and more.Trajectories of rockets in multi-dimensional space. Similar to the airplane example, but outer space deals in multi-dimensional space and more lethal "features" (obstacles) along a path, like black holes, asteroid belts, and planets. Scientists would need to calculate vector routes to avoid passing through planets and avoid gravitational pulls from celestial bodies. We represent the paths by creating numeric representations based on key, defined features that characterize the path (vector). Then, we can use those paths to make calculations and precise adjustments based on external factors. Vectors Applied to Words In 2013, Google applied this mathematical concept to words (word2vec), creating numeric representations of words based on how they functioned within the language and defining characteristics. Word embeddings map words into a continuous vector space where semantically similar words are closer together. For instance, the words "king" and "queen" might have embeddings that are close in this space, reflecting their related meanings around power, leadership, luxurious living, and wealth. This ability allowed humans to represent words for comparing similarity of words or understanding new words from proximity to known words. Broader searches and synonym lists based on "semantic" meaning could be factored into the calculations, which are foundational for many natural language processing tasks. Vectors Applied to Data We took this one step further in the last few years to apply this to any type of data (text, image, video, audio, etc). Vector embeddings are numerical representations of data that capture semantic meaning in a way that makes it easier to compare and analyze. When combined with generative AI (GenAI), embeddings enable semantic searches, which go beyond simple keyword matching. Unlike lexical searches that rely on exact word matches, semantic searches use embeddings to understand the meaning behind the query and retrieve results that are contextually relevant. This makes them particularly powerful for applications like document retrieval, where understanding the intent and context of a query is crucial for delivering accurate and meaningful results. There is a common saying that you can't compare apples and oranges (because they have two different sets of characteristics). However, with a numeric representation, we can actually compare them because we have a common format to represent all sorts of objects and data. Also, a recent article I read compared vectors to a "fingerprint" of the data. Just as a fingerprint is unique to each individual, the vector representation of a piece of data is unique to that specific data point. This uniqueness allows for precise identification and retrieval of information, even in large datasets. Note: Since each LLM is trained slightly differently, the vector embeddings may be different for each model. This means that the same piece of data may have slightly different vector representations with different models (though both will be close together in the vector space). This is important to consider when using multiple LLMs or comparing results across models. Here enter the need and purpose of https://frankzliu.com/blog/a-gentle-introduction-to-vector-databases[vector databases^], which are optimized to store and search these vector representations. But how do vector databases efficiently search vast amounts of these numbers (think every word in every language or millions of text documents)? Similarity Search Similarity search involves finding data records that are most similar to a given query. This is often achieved using techniques like k-Nearest Neighbors (k-NN) or approximate methods like k-ANN for efficiency, where k represents the number of most similar results you want returned (i.e., 7, 42, 100). This might seem overly complex, but let's look at an example to understand the power of these types of searches. Let's think about a library. In a library today, searching for a new book to read would require picking from the nested category structure of organizing books (e.g., fiction/non-fiction -> genre -> author -> title). If I wanted to read a fantasy novel, my current strategy would be to walk to the fiction area, find the fantasy section, and start pulling books off the shelf to see what sparked my interest. Another alternative would be to do a computer search for keywords and hope that the book is tagged with the topics I'm interested in. Vectors would allow us to search for books based on semantics, finding similarities for specific features that are baked into the vector embedding and returning results in the nearby vector space as our search query. To measure similarity, cosine similarity and Euclidean distance are two of the most common metrics used, though there are others as well. Cosine similarity measures the distance between the angles of the vectors. Remember, vectors are lines with a length and direction, so cosine measures the distance between the two lines in degrees. Euclidean distance is the shortest distance from point to point ("as the crow flies" between vector points). In our library example, we could search for specific features like "dragons and magic" or "based in St. Louis, USA." These criteria are much narrower and are more likely to find a smaller result set that is more relevant to what the user is searching for. Note: Vector embeddings differ for each model, and each vector store also optimizes vector similarity search differently. So even the same data and embeddings stored in different vector stores may produce different results from a similarity search. Wrapping Up In this blog post, we explored a few introductory concepts around retrieval-augmented generation (RAG), why it exists, and the problems it solves. We also covered some starting GenAI concepts on large language models (LLMs), vectors and embeddings, and vector similarity search. These pieces build the foundations of more complex AI systems and explain how RAG enhances the capabilities of LLMs by integrating them with external knowledge sources. In another post, we will explore the different layers of RAG, including vector RAG, graph RAG, and agents. Whether you're a developer, data scientist, or simply someone interested in the future of AI, understanding AI technologies and how they operate will empower you to make better decisions on how to use them. Happy coding! Resources Tutorial: Vectors - Math is FunProject: word2vec - GoogleBlog post: Explaining Vector Databases in 3 Levels of Difficulty - Towards Data Science
With the release of PostgreSQL 17, the introduction of incremental backups using the trusted pg_basebackup tool marks a significant leap forward in database backup and restoration processes. Traditionally, database backups often involved taking periodic full backups, which, while comprehensive, are time-consuming and storage-intensive. Incremental backups offer a smarter alternative by capturing and storing only the changes made since the last backup, dramatically reducing both backup size and the time required to create backups. This innovation is further complemented by the new pg_combinebackup tool, which simplifies the process of restoring backups. Enabling administrators to seamlessly combine a full backup with a series of incremental backups into a usable state pg_combinebackup eliminates much of the manual effort involved in restoration. Together, these tools streamline backup management, optimize storage utilization, and accelerate disaster recovery, making them indispensable for modern database environments. Prerequisites for Incremental Backups Before initiating incremental backups, certain configurations are necessary: 1. Enable WAL summarization: Incremental backups rely on WAL (Write-Ahead Logs). Ensure the summarize_wal variable is enabled. SQL postgres=# show summarize_wal; summarize_wal --------------- off (1 row) postgres=# alter system set summarize_wal to on; ALTER SYSTEM postgres=# select pg_reload_conf(); pg_reload_conf ---------------- t (1 row) postgres=# show summarize_wal; summarize_wal --------------- on (1 row) 2. Backup manifest file: The backup_manifest file, generated during full or incremental backups, tracks changes and serves as input for the next incremental backup. 3. Ensure proper configuration: Verify that WAL archiving and sufficient disk space are configured for backups. Performing a Full Backup A full backup is the foundation for incremental backups. Without it, incremental backups cannot be created. 1. Prepare your environment: Perform some operations in your database to simulate activity: SQL postgres=# create table test(id int, name varchar, updated_at timestamptz); CREATE TABLE postgres=# insert into test values (1, 'full backup', now()); INSERT 0 1 2. Execute the full backup: SQL pg_basebackup -D /data/postgresql/full_backup/ -F tar -D: Specifies the backup directory.-F tar: Saves the backup in tar format. 3. Verify the backup: SQL ls -lh /data/postgresql/full_backup/ The directory includes essential files such as backup_manifest, which details the backup and serve as input for incremental backups. Performing Incremental Backups Backups Incremental backups store only changes made since the last backup, reducing backup size and time. 1. First incremental backup: After making changes to the database, create the first incremental backup: SQL pg_basebackup --incremental=/data/postgresql/full_backup/backup_manifest -D /data/postgresql/incr_backup1/ -F tar 2. Second incremental backup: Perform more changes in the database, then run: SQL pg_basebackup --incremental=/data/postgresql/incr_backup1/backup_manifest -D /data/postgresql/incr_backup2/ -F tar 3. Monitor backup sizes: SQL du -sh /data/pgsql/incr_backup1/ /data/postgresql/incr_backup2/ Combining Backups for Restoration PostgreSQL 17 introduces pg_combinebackup to simplify restoration by merging backups into a usable state. What Is pg_combinebackup? Automated process: Combines full and incremental backups into a complete database directory, eliminating manual intervention.Data integrity: Ensures consistency by validating the sequence of backups and checking for missing or corrupted files.Simplified restoration: Speeds up disaster recovery by consolidating the restoration steps. Restoration Process Using pg_combinebackup 1. Prepare the environment: Ensure all backups (full and incremental) are available and stored in the correct sequence. Verify that the backup_manifest files are intact for each backup. 2. Run the Restoration command: The pg_combinebackup tool consolidates backups into a target directory for restoration. Here’s how to use it: 3. Restore backups: SQL pg_combinebackup -o /data/postgresql/restored/ /data/popstgresql/full_backup/ /data/postgresql/incr_backup1/ /data/postgresql/incr_backup2/ Command breakdown: -o /data/postgresql/restored/: Specifies the directory where the restored database will be constructed.Backup Directories: Provide the paths to the full backup and incremental backups in the correct sequence. Each backup directory must include its respective backup_manifest file. 4. Validate the restoration: Once the above command completes. Check the contents of the restored directory: SQL ls -lh /data/postgresql/restored/ Ensure all files and directories are present and match the original database structure. 5. Start PostgreSQL: After restoration, initialize the database. Points to Remember Restore from Backups 1. Full backup first: Always provide backups in sequential order, starting with the full backup. SQL pg_combinebackup /data/postgresql/full_backup/ /data/postgresql/incr_backup1/ /data/postgresql/incr_backup2/ 2. Backup sequence: Always provide backups in chronological order. If backups are out of order, pg_combinebackup will throw an error, such as: SQL pg_combinebackup: error: backup at "/data/postgresql/incr_backup2/" starts at LSN 0/4000028, but expected 0/2000028 3. Error handling: Skipping backups or providing them out of order results in errors: SQL pg_combinebackup: error: backup at "incr_backup2/" starts at LSN 0/6000028, but expected 0/4000028 Key Benefits of Incremental Backups Efficiency: Incremental backups reduce storage requirements and backup time by focusing only on changed data.Reliability: The backup_manifest ensures that every backup is trackable and consistent, reducing the risk of data loss.Streamlined restoration: pg_combinebackup Automates restoration from multiple backups, eliminating manual intervention.Scalability: Ideal for large databases where full backups are resource-intensive. Conclusion PostgreSQL 17’s incremental backup support in pg_basebackup introduces a significant leap forward in backup management. Coupled with this pg_combinebackup, it simplifies complex backup and restoration processes, making PostgreSQL more efficient and user-friendly for modern database environments.
It was not so long ago that I was having a much closer look at how AI is becoming embedded in our everyday developer work. I have watched more intelligent code suggestions, automated testing routines, and those ubiquitous chatbots become a normal part of the everyday toolkit. They are useful, naturally, but at their core, they are still fundamentally reactive, they still wait for you to inquire of them before taking action. What has really blown me away recently is the emergence of agentic AI. It is completely different, it does not just sit around and wait to be told what to do, but instead it takes charge itself. It can decide what should be done, strategize the steps, and even adjust if something unexpected happens. It's sort of like having a colleague who is always planning ahead, as opposed to merely carrying out orders. Curious about the real-world impact of agentic AI, I set up a simple experiment: I showed an AI agent some code with a well-known security vulnerability. Instead of just flagging the issue, the AI took the action. It refactored the code, added error handling, and even left a comment with further steps. There are no step-by-step instructions necessary. The AI simply understood what needed to be done and did it on its own. That is the real promise of agentic AI. It is not another tool you have to monitor, but rather an active partner that knows the bigger picture and covers for what you might miss. In this article, I will go beyond theory and take agentic AI for a spin in a real use case: auto-detecting and fixing security vulnerabilities in your codebase, so issues like SQL injection do not fall through the cracks. An Experiment to Test Agentic AI's Capabilities Below are the steps I took to see if agentic AI would identify the security vulnerability in the code. Here is the sample code with a SQL Injection vulnerability: Python def login(username, password): query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'" return db.execute(query) Set Up Your AI Teammate: Ensure Python 3.12 or higher is installed. Download and install Ollama, as this helps us run everything from your local system.Pull codellama model, a model that understands the code. Install pyautogen and other dependencies pip install pyautogen groq python-dotenv Setup GroqCloud Sign up at GroqCloud Console and create an API key under "API Keys"Create an .env file and add the API key into it: GROQ_CLOUD_API_KEY=your_api_key_here Now, let's define four specialized agents that collaborate like a security team. Each one has its role but collaborate with each other. VulnerabilityScanner: This agent scans code for vulnerabilities such as SQL Injection and XSSRiskPrioritizer: This agent prioritizes vulnerabilities by severity(CVSS scores)CodeFixer: This agent rewrites code to remediate vulnerabilities without breaking functionalityValidator:This agent does the final validation of the fixes For this example, I will be using llama3-70b-8192 model for all agents. In the real world, you would use different models for different agents. Implementation: Python from autogen import AssistantAgent, GroupChat, GroupChatManager import os from dotenv import load_dotenv load_dotenv() # This model configuration will be reused for all agents. groq_cloud_configuration = { "config_list": [{"model": "llama3-70b-8192", "api_key": os.getenv("GROQ_CLOUD_API_KEY"), "base_url": "https://api.groq.com/openai/v1"}] } # Agent 1: Vulnerability Scanner vulnerability_scanner_agent = AssistantAgent(name="VulnerabilityScanner", system_message="Find security vulnerabilities in code", llm_config=groq_cloud_configuration ) # Agent 2: Risk Prioritizer risk_prioritizer_agent = AssistantAgent(name="RiskPrioritizer", system_message="Prioritize vulnerability based on CVSS score", llm_config=groq_cloud_configuration ) # Agent 3: Code Fixer code_fixer_agent = AssistantAgent(name="CodeFixer", system_message="Generate secure code fixes", llm_config=groq_cloud_configuration ) # Agent 4: Validator validator_agent = AssistantAgent(name="Validator", system_message="Test fixes for functionality and security", llm_config=groq_cloud_configuration ) Now, list all your agents in the order that you want them to communicate and initiate group chat: Python # creating group chat object with maximum round as 15 group_chat=GroupChat(agents=agents,messages=[],max_round=15) # Creating GroupChatManager with the same llm config group_chat_manager=GroupChatManager(groupchat=group_chat,llm_config=groq_cloud_config) Test it with the example SQL injection vulnerability mentioned above: Python vulnerable_sql_injection_code = """ def login(username, password): query = f"SELECT * FROM users WHERE username='{username}' AND password='{password}'" return db.execute(query) """ # This will initiate the workflow final_result=vulnerability_scanner_agent.initiate_chat(group_chat_manager,message=f"Review and fix:\n{vulnerable_sql_injection_code}") print(final_result.summary) When you run this multi-agent workflow, you will notice a sequence of long, wordy outputs, each one starts with the label "Next speaker: <agent name>". This is because each agent in the system receives a turn, just as individuals in a conversation do, with each building on the previous agent's work. First, the VulnerabilityScanner agent looks at the code and determines the security vulnerability. Then, the RiskPrioritizer examines how severe the problem is and explains why it matters. Then, the CodeFixer comes along and securely rewrites the code and typically adds more best practices. Finally, the Validator agent tests the fixes, makes sure everything still works, and offers even more recommendations to harden your application. Every "speaker" hands off information to the next, so the agents actually communicate, work together, and iterate on the solution in tandem, which is a lot like a team of experts passing off a case, with each one contributing their expertise. This back-and-forth process is what gives agentic AI its strength because it does not just identify issues, it also explains, resolves, and optimizes your code via a collaborative and transparent process. Conclusion This is only a single demonstration of what is possible with agentic AI and multi-agent workflows. While we experimented it for security flaw detection and fixing, the same process can be used to automate any type of difficult activity in software development and many other areas, ranging from code audit and compliance reporting, to performance optimizing and incident handling. I trust that this information has given you a fair idea of what agentic AI is really like and encourages you to go ahead and experiment with your own multi-agent systems.
Masking data to protect confidentiality has become a mandate more than ever before. As enterprises attempt to mitigate their workloads to multi-tenant cloud environments and data lakes etc., it makes perfect sense to revisit the masking strategies and be prepared for the future. That, too, when compliance regulations have tightened their grip over potential defaulters. That's exactly why entity-based masking is gaining acceptance across industry facets. It moves sensitive data across the landscape without exposing it. This enables organizations to comply with privacy regulations such as the GDPR, CCPA, and HIPPA. In fact, it's an industry of its own, pacing to a value of USD 1.87 billion by 2029 and recording an approximate CAGR of 14%. Apart from securing sensitive data assets throughout the lifecycle management process, entity-based masking strengthens the overall risk management initiatives. What’s even more interesting is entity-based masking’s role in facilitating the development of AI and ML models using datasets. Which Are the Top Entity-Based Masking Platforms? The data masking market is significantly fragmented as many global players have entered the scene. Key names include, but are not limited to, IBM, Mentis, Delphix, Oracle and Informatica. Informatica's data masking follows an entity-centric approach to protecting sensitive data. It effectively discovers, classifies, and masks data across structured and unstructured sources while maintaining referential integrity. That being said, entity-level Micro Database approach continues to be in the spotlight. The platform’s entity-based data masking is a proven, thorough method for safeguarding confidential data. It arranges scattered data from various sources into protected Micro Databases that are individually encrypted for each business entity, such as customers' orders or devices. This entity-focused approach streamlines data protection and ensures the consistency of references, allowing authorized users to access all information linked to a specific entity while hiding sensitive details. A solution called Mentis supports static and dynamic masking for structured and unstructured data, offering numerous built-in masking functions and the flexibility to establish personalized anonymization guidelines. By upholding data usability and maintaining connections between masked entities, it empowers organizations to adhere to privacy regulations while effectively managing analytical and operational tasks. While we are at it, IBM's Optim supports entity-based data masking, enabling organizations to mask data in the context of business entities. IBM’s Optim is a major BFSI sector player, offering dynamic and static masking options. Best Practices in Implementing Entity-Based Data Masking Regardless of the target system’s industry, data scale and other parameters, the following are the standard best practices that every platform should diligently follow. Identify and Classify Sensitive Data Data protection initiatives, including entity-based masking, have to start with discovery—the discovery of all data assets across repositories. By utilizing AI-enabled advanced scanning tools, data professionals can streamline the identification and categorization of PII data sets. This helps further facilitate seamless collaboration among data owners, security teams, and compliance professionals. Such a collaborative approach works because it comprehensively explains the organization’s data landscape. Following this, data professionals can curate effective data masking strategies at the entity level. Ultimately, it helps prioritize sensitive data, thereby optimizing data protection initiatives and implementing security protocols for critical information. Define Clear Masking Policies While there are multiple masking techniques, it is important to do the right mapping with the requirement. This should be done based on the data set’s sensitivity level, compliance requirements, data volume and other parameters. For example, data tokenization is the go-to policy if you want to hide sensitive data with non-sensitive tokens. Likewise, if you want to ensure that only authorized personnel and decryption keys should access the data, Encryption is the method to implement. For less volume and less sensitive but important data, a simplistic technique like substituting real data sets with fictitious data works fine. The point is that data has to be prioritized based on its high-risk exposure. Data assets that are highly vulnerable to misuse will require the most advanced and best resource allocation for adequate protection. Define clear masking policies for optimal results. Organizations can avoid data corruption and maintain dataset integrity by considering data relationships while implementing masking. Maintain Referential Integrity Entity-based masking must ensure consistency and validity across multiple datasets. To achieve this, data professionals should preserve relationships between masked entities, which is essential for maintaining data quality while protecting data confidentiality. How does that help? Organizations are better positioned to prevent data corruption and context manipulation, ensuring end-to-end accuracy and reliability. Preserving relationships is also important because multiple, interconnected entities often complicate the data structures. For example, a customer’s personal information might include their order history, past transactions, payment information, shipping address etc. Now, while masking, organizations must establish a relationship between these data types to maintain usability. In pursuing the same, organizations should implement consistent masking techniques across all related entities, or use platforms that automatically maintain the referential integrity during masking. Monitor and Audit Masked Data We all know the importance of consistently monitoring and auditing masked data to prevent unauthorized access. It is imperative for organizations to proactively analyze access patterns and identify any suspicious activities that may trigger a compliance violation or a security breach. Implementing robust logging and tracking mechanisms allows organizations to record and track data access activities, providing a detailed trail of who accessed the data and when. This ongoing monitoring and evaluation process allows organizations to fine-tune their data masking strategies, address any vulnerabilities, and enhance overall data security measures. More Data on the Go As data volumes grow, real-time masking capabilities and convergence with cutting-edge technologies like homomorphic encryption will be crucial. Entity-based masking will be pivotal in regulatory compliance and mitigating data breach risks. By embracing this approach, organizations can unlock their data's potential while maintaining customer trust and meeting stringent privacy standards in the data-driven future.
May 14, 2025
by
CORE
Infrastructure as Code (IaC) Beyond the Basics
May 16, 2025 by
Endpoint Security Controls: Designing a Secure Endpoint Architecture, Part 2
May 16, 2025
by
CORE
Using Python Libraries in Java
May 16, 2025 by
Designing a Java Connector for Software Integrations
May 15, 2025 by
Using Python Libraries in Java
May 16, 2025 by
The Full-Stack Developer's Blind Spot: Why Data Cleansing Shouldn't Be an Afterthought
May 16, 2025 by
How Can Developers Drive Innovation by Combining IoT and AI?
May 16, 2025 by