Author: Richard Seroter

  • Make Any Catalog-Driven App More Personalized to Your Users: How I used Generative AI Coding Tools to Improve a Go App With Gemini.

    Make Any Catalog-Driven App More Personalized to Your Users: How I used Generative AI Coding Tools to Improve a Go App With Gemini.

    How many chatbots do we really need? While chatbots are a terrific example app for generative AI use cases, I’ve been thinking about how developers may roll generative AI into existing “boring” apps and make them better.

    As I finished all my Christmas shopping—much of it online—I thought about all the digital storefronts and how they provide recommended items based on my buying patterns, but serve up the same static item descriptions, regardless of who I am. We see the same situation with real estate listings, online restaurant menus, travel packages, or most any catalog of items! What if generative AI could create a personalized story for each item instead? Wouldn’t that create such a different shopping experience?

    Maybe this is actually a terrible idea, but during the Christmas break, I wanted to code an app from scratch using nothing but Google Cloud’s Duet AI while trying out our terrific Gemini LLM, and this seemed like a fun use case.

    The final app (and codebase)

    The app shows three types of catalogs and offers two different personas with different interests. Everything here is written in Go and uses local files for “databases” so that it’s completely self-contained. And all the images are AI-generated from Google’s Imagen2 model.

    When the user clicks on a particular catalog entry, the go to a “details” page where the generic product summary from the overview page is sent along with a description of the user’s preferences to the Google Gemini model to get a personalized, AI-powered product summary.

    That’s all there is to it, but I think it demonstrates the idea.

    How it works

    Let’s look at what we’ve got here. Here’s the basic flow of the AI-augmented catalog request.

    How did I build the app itself (GitHub repo here)? My goal was to only use LLM-based guidance either within the IDE using Duet AI in Google Cloud, or burst out to Bard where needed. No internet searches, no docs allowed.

    I started at the very beginning with a basic prompt.

    What are the CLI commands to create a new Go project locally?

    The answer offered the correct steps for getting the project rolling.

    The next commands are where AI assistance made a huge difference for me. With this series of natural language prompts in the Duet AI chat within VS Code, I got the foundation of this app set up in about five minutes. This would have easily taken me 5 or 10x longer if I did it manually.

    Give me a main.go file that responds to a GET request by reading records from a local JSON file called property.json and passes the results to an existing html/template named home.html. The record should be defined in a struct with fields for ID, Name, Description, and ImageUrl.
    Create an html/template for my Go app that uses Bootstrap for styling, and loops through records. For each loop, create a box with a thin border, an image at the top, and text below that. The first piece of text is "title" and is a header. Below that is a short description of the item. Ensure that there's room for four boxes in a single row.
    Give me an example data.json that works with this struct
    Add a second function to the class that responds to HTML requests for details for a given record. Accept a record id in the querystring and retrieve just that record from the array before sending to a different html/template

    With these few prompts, I had 75% of my app completed. Wild! I took this baseline, and extended it. The final result has folders for data, personas, images, a couple HTML files, and a single main.go file.

    Let’s look at the main.go file, and I’ll highlight a handful of noteworthy bits.

    package main
    
    import (
    	"context"
    	"encoding/json"
    	"fmt"
    	"html/template"
    	"log"
    	"net/http"
    	"os"
    	"strconv"
    
    	"github.com/google/generative-ai-go/genai"
    	"google.golang.org/api/option"
    )
    
    // Define a struct to hold the data from your JSON file
    type Record struct {
    	ID          int
    	Name        string
    	Description string
    	ImageURL    string
    }
    
    type UserPref struct {
    	Name        string
    	Preferences string
    }
    
    func main() {
    
    	// Parse the HTML templates
    	tmpl := template.Must(template.ParseFiles("home.html", "details.html"))
    
    	//return the home page
    	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    
    		var recordType string
    		var recordDataFile string
    		var personId string
    
    		//if a post-back from a change in record type or persona
    		if r.Method == "POST" {
    			// Handle POST request:
    			err := r.ParseForm()
    			if err != nil {
    				http.Error(w, "Error parsing form data", http.StatusInternalServerError)
    				return
    			}
    
    			// Extract values from POST data
    			recordType = r.FormValue("recordtype")
    			recordDataFile = "data/" + recordType + ".json"
    			personId = r.FormValue("person")
    
    		} else {
    			// Handle GET request (or other methods):
    			// Load default values
    			recordType = "property"
    			recordDataFile = "data/property.json"
    			personId = "person1" // Or any other default person
    		}
    
    		// Parse the JSON file
    		data, err := os.ReadFile(recordDataFile)
    		if err != nil {
    			fmt.Println("Error reading JSON file:", err)
    			return
    		}
    
    		var records []Record
    		err = json.Unmarshal(data, &records)
    		if err != nil {
    			fmt.Println("Error unmarshaling JSON:", err)
    			return
    		}
    
    		// Execute the template and send the results to the browser
    		err = tmpl.ExecuteTemplate(w, "home.html", struct {
    			RecordType string
    			Records    []Record
    			Person     string
    		}{
    			RecordType: recordType,
    			Records:    records,
    			Person:     personId,
    		})
    		if err != nil {
    			fmt.Println("Error executing template:", err)
    		}
    	})
    
    	//returns the details page using AI assistance
    	http.HandleFunc("/details", func(w http.ResponseWriter, r *http.Request) {
    
    		id, err := strconv.Atoi(r.URL.Query().Get("id"))
    		if err != nil {
    			fmt.Println("Error parsing ID:", err)
    			// Handle the error appropriately (e.g., redirect to error page)
    			return
    		}
    
    		// Extract values from querystring data
    		recordType := r.URL.Query().Get("recordtype")
    		recordDataFile := "data/" + recordType + ".json"
    
    		//declare recordtype map and extract selected entry
    		typeMap := make(map[string]string)
    		typeMap["property"] = "Create an improved home listing description that's seven sentences long and oriented towards a a person with these preferences:"
    		typeMap["store"] = "Create an updated paragraph-long summary of this store item that's colored by these preferences:"
    		typeMap["restaurant"] = "Create a two sentence summary for this menu item that factors in one or two of these preferences:"
    		//get the preamble for the chosen record type
    		aiPremble := typeMap[recordType]
    
    		// Parse the JSON file
    		data, err := os.ReadFile(recordDataFile)
    		if err != nil {
    			fmt.Println("Error reading JSON file:", err)
    			return
    		}
    
    		var records []Record
    		err = json.Unmarshal(data, &records)
    		if err != nil {
    			fmt.Println("Error unmarshaling JSON:", err)
    			return
    		}
    
    		// Find the record with the matching ID
    		var record Record
    		for _, rec := range records {
    			if rec.ID == id { // Assuming your struct has an "ID" field
    				record = rec
    				break
    			}
    		}
    
    		if record.ID == 0 { // Record not found
    			// Handle the error appropriately (e.g., redirect to error page)
    			return
    		}
    
    		//get a reference to the persona
    		person := "personas/" + (r.URL.Query().Get("person") + ".json")
    
    		//retrieve preference data from file name matching person variable value
    		preferenceData, err := os.ReadFile(person)
    		if err != nil {
    			fmt.Println("Error reading JSON file:", err)
    			return
    		}
    		//unmarshal the preferenceData response into an UserPref struct
    		var userpref UserPref
    		err = json.Unmarshal(preferenceData, &userpref)
    		if err != nil {
    			fmt.Println("Error unmarshaling JSON:", err)
    			return
    		}
    
    		//improve the message using Gemini
    		ctx := context.Background()
    		// Access your API key as an environment variable (see "Set up your API key" above)
    		client, err := genai.NewClient(ctx, option.WithAPIKey(os.Getenv("GEMINI_API_KEY")))
    		if err != nil {
    			log.Fatal(err)
    		}
    		defer client.Close()
    
    		// For text-only input, use the gemini-pro model
    		model := client.GenerativeModel("gemini-pro")
    		resp, err := model.GenerateContent(ctx, genai.Text(aiPremble+" "+userpref.Preferences+". "+record.Description))
    		if err != nil {
    			log.Fatal(err)
    		}
    
    		//parse the response from Gemini
    		bs, _ := json.Marshal(resp.Candidates[0].Content.Parts[0])
    		record.Description = string(bs)
    
    		//execute the template, and pass in the record
    		err = tmpl.ExecuteTemplate(w, "details.html", record)
    		if err != nil {
    			fmt.Println("Error executing template:", err)
    		}
    	})
    
    	fmt.Println("Server listening on port 8080")
    	fs := http.FileServer(http.Dir("./images"))
    	http.Handle("/images/", http.StripPrefix("/images/", fs))
    	http.ListenAndServe(":8080", nil)
    }
    

    I do not write great Go code, but it compiles, which is good enough for me!

    On line 13, see that I refer to the Go package for interacting with the Gemini model. All you need is an API key, and we have a generous free tier.

    On line 53, notice that I’m loading the data file based on the type of record picked on the HTML template.

    On line 79, I’m executing the HTML template and sending the type of record (e.g. property, restaurant, store), the records themselves, and the persona.

    On lines 108-113, I’m storing a map of prompt values to use for each type of record. These aren’t terrific, and could be written better to get smarter results, but it’ll do.

    Notice on line 147 that I’m grabbing the user preferences we use for customization.

    On line 163, I create a Gemini client so that I can interact with the LLM.

    On line 171, see that I’m generating AI content based on the record-specific preamble, the record details, and the user preference data.

    On line 177, notice that I’m extracting the payload from Gemini’s response.

    Finally, on line 181 I’m executing the “details” template and passing in the AI-augmented record.

    None of this is rocket science, and you can check out the whole project on GitHub.

    What an “enterprise” version might look like

    What I have here is a local example app. How would I make this more production grade?

    • Store catalog images in an object storage service. All my product images shouldn’t be local, of course. They belong in something like Google Cloud Storage.
    • Add catalog items and user preferences to a database. Likewise, JSON files aren’t a great database. The various items should all be in a relational database.
    • Write better prompts for the LLM. My prompts into Gemini are meh. You can run this yourself and see that I get some silly responses, like personalizing the message for a pillow by mentioning sporting events. In reality, I’d write smarter prompts that ensured the responding personalized item summary was entirely relevant.
    • Use Vertex AI APIs for accessing Gemini. Google AI Studio is terrific. For production scenarios, I’d use the Gemini models hosted in full-fledged MLOps platform like Vertex AI.
    • Run app in a proper cloud service. If I were really building this app, I’d host it in something like Google Cloud Run, or maybe GKE if it was part of a more complex set of components.
    • Explore whether pre-generating AI-augmented results and caching them would be more performant. It’s probably not realistic to call LLM endpoints on each “details” page. Maybe I’d pre-warm certain responses, or come up with other ways to not do everything on the fly.

    This exercise helped me see the value of AI-assisted developer tooling firsthand. And, it feels like there’s something useful about LLM summarization being applied to a variety of “boring” app scenarios. What do you think?

  • Daily Reading List – January 3, 2024 (#231)

    Are folks showing back up at your workplace? Today felt like a “real” workday after yesterday’s quiet start. I still haven’t gotten all the way through my holiday backlog of items to read, and you’re seeing some of those below.

    [blog] Gemini Function Calling. LLMs don’t have all the answers. Shocking, I know. But that’s why this “function calling” technique is pretty cool. Devs give external functions or APIs to the model, and it can return those to the caller when it doesn’t have the answer.

    [blog] The Power of Visiontypes. Just seeing what’s possible can spark all sorts of ideas for where to go next. Marty looks at prototypes of product vision, and where the real work begins.

    [article] Developer Productivity in 2024: New Metrics, More GenAI. This is a good look at the discussion about “developer productivity” that fired up last year, and what 2024 may hold.

    [blog] Visualize and Inspect Workflows Executions. It seems that we all clamor for higher order software abstractions, but then complain when those abstractions are too opaque to know what’s going on inside. Workflow engines can be opaque, and I’m glad we’re now showing you more of what’s happening.

    [article] Introduction to the Node.js reference architecture: Wrapping up. This long-running series of posts from Red Hat wraps up. Take a look if you’re building Node apps.

    [article] AI vendors promised indemnification against lawsuits. The details are messy. We’re in new territory here, and Tom explains why vendor promises don’t necessarily protect you.

    [article] InfoQ Cloud and DevOps Trends 2023. Good panel discussion here (with transcript) featuring folks who know this industry.

    [blog] My 2024 technical writing trends and predictions. Lots of AI considerations here, which apply to many additional professions besides tech writing.

    [article] 2024 Predictions by JavaScript Frontend Framework Maintainers. What’s coming up for the biggest frontend JavaScript frameworks? This post highlights upcoming features.

    ##

    Want to get this update sent to you every day? Subscribe to my RSS feed or subscribe via email below:

  • Daily Reading List – January 2, 2024 (#230)

    Happy New Year! It’s good to be back after taking a week+ off for Christmas. I cleared out the first part of my holiday reading backlog below, and you’ll find some useful pieces to start off the year.

    [blog] Getting Started with Gemini AI API via Google Cloud Code Application Templates. This IDE extension offers a lot of useful things, including the ability to get a pre-baked template for trying out the Gemini LLM.

    [docs] Go REST Guide. The Standard Library. This is from JetBrains, and offers a very comprehensive look at three ways to build REST-based services in Go.

    [blog] Cloud CISO Perspectives: Our 2024 Cybersecurity Forecast report. Check out some well-informed opinions about what 2024 holds for security teams.

    [blog] Why LinkedIn chose gRPC+Protobuf over REST+JSON: Q&A with Karthik Ramgopal and Min Chen. It’s not hard to build REST-based services (see above), but I’ve definitely seen a few folks switch to gRPC.

    [blog] Amazon’s Silent Sacking. Yikes. No place is perfect, and we’ve got our own issues. But there do seem to be some fundamental items that need a reset at Amazon.

    [blog] The Life and Death of Open Source Companies. Interesting perspective, and it definitely feels like the tide has turned on how companies that create open products will protect their investment. Somewhat related.

    [blog] LLM Model Serving on Autopilot. Serve up those open LLMs on Kubernetes if you want to. GKE Autopilot makes it easier. GKE actually does a lot for those doing AI/ML.

    [article] Year in Review: Platform Engineering Still Run By Spreadsheet. Platform engineering will be popular in 2024. I worry that folks will over-engineer solutions, and build bloated platforms run by too-large teams. But, prove me wrong!

    [article] Generative AI: In 2023, GenAI Tools Became Table Stakes, While other generative AI use cases mature, it’s clear that AI-assisted tooling is a legit aid to devs.

    [article] MySQL Introduces Javascript Support in Preview. Write stored procs and functions for MySQL using JavaScript? Sure, why not.

    ##

    Want to get this update sent to you every day? Subscribe to my RSS feed or subscribe via email below:

  • 2023 in Review: Reading and Writing Highlights

    I had a great year. Not because of any one particular event. But I enjoyed some terrific time with family, had fun at work, learned a ton of new things, traveled to interesting places, developed some good habits, and gave away more than I spent. Who knows what 2024 holds, but I’m glad 2023 happened.

    While I read a pile of books and wrote more than I have in years, I also felt like I did fewer things overall. For example, this was the first time in over a decade that I didn’t create any new Pluralsight courses, and I’m likely done with that season of life. I’ve been trying to do fewer things, better. Let’s take a look at some of the items I wrote this year, and the best books that I read.

    Things I Wrote (or Said)

    One of the main things I wrote this year was 229 editions of my daily reading list! I started the year aiming to share each day, and mostly achieved that.

    The most fun “speaking” I got to do this year was at Google events. The Cloud Next ’23 dev keynote is a career highlight for me.

    I also had the pleasure of delivering the Cloud update at Google I/O.

    Other content I was proud of:

    The Modernization Imperative: Shifting left is for suckers. Shift down instead. I send out a weekly internal newsletter and we occasionally take some of these and make them into blog posts. This one actually took off a bit as the “shift down” metaphor resonated with folks.

    The Modernization Imperative (TMI): The beauty in boring. Here’s another one of those, and I liked the point of embracing the right mix of novel and stable tech.

    Richard Seroter on Balancing Business and Technology Strategies. The fine folks at Semaphore had me on their podcast, and we talked about a lot of things.

    The Role of DevRel at Google with Richard Seroter. This was another fun chat with Corey Quinn, and I’m glad I got to give props to our amazing developer relations team.

    Richard Seroter on Google Cloud Next ’23, Tech Newsletters and VMware. The Software Defined Talk folks had me back on, and we covered a spicy set of topics.

    Would generative AI have made me a better software architect? Probably. Generative AI isn’t a fad, although the hype is off the charts. Lots of people will benefit from it, including architects.

    An AI-assisted cloud? It’s a thing now, and here are six ways it’s already made my cloud experience better. We’re going to see a lot about how generative AI helps devs, and this is what initially stood out to me.

    I don’t enjoy these 7 software development activities. Thanks to generative AI, I might not have to do them anymore. There’s a lot of toil in software development, and generative AI may eliminate a lot of it.

    There’s a new cloud-based integration platform available. Here are eight things I like (and two I don’t) about Google Cloud Application Integration. I’ve been testing out technologies for years, and it makes me happy to keep doing it. This was a fun look at Google’s new iPaaS.

    Build event handlers and scale them across regions, all with serverless cloud services? Let’s try it. I’m always a fan of trying out end-to-end scenarios. Here’s one that covered a few different components.

    Things I Read

    I finished 47 books this year, across the usual wide range of topics. A clear theme this year was “leadership” and I learned a lot.

    Do Hard Things: Why We Get Resilience Wrong and the Surprising Science of Real Toughness by Steve Magness. It “toughness” about being calloused and fearing nothing? This book says we have it wrong. It’s about making choices under discomfort while embracing reality, listening to our bodies, proactively responding, and transcending discomfort. Good read!

    The Last Folk Hero: The Life and Myth of Bo Jackson by Jeff Pearlman. Bo was a freakish athlete who I grew up watching. He had a short “prime” period, as playing both sports simultaneously was grueling, but we’re better off for having seen him play.

    Scaling People: Tactics for Management and Company Building by Claire Hughes Johnson. If you’re building a team, scaling a team, or doing this for a whole company, this book is invaluable. I appreciated the frameworks and tips shared across a wide range of leadership dimensions.

    Genghis: Birth of an Empire by Conn Iggulden. I read more historical fiction this year than ever, and boy, I really loved these two. This, and book 2 (Genghis: Lords of the Bow) were an absolutely engrossing look at what the early life of Genghis Khan was probably like, and how Mongolians lived at this time.

    The Catalyst: How to Change Anyone’s Mind by Jonah Berger. This book offered an outstanding reframing of persuasion. Instead of pushing people to change their minds, you become a catalyst and remove roadblocks. Very actionable stuff here.

    Kydd: A Novel (Kydd Sea Adventures Book 1) by Julian Stockwin. More historical fiction! I also loved these stories about a man yanked into service at sea in the late 1700s. Great storytelling, and a compelling look at life aboard a ship at this time. I also read three more besides this one, including Artemis, Seaflower, and Mutiny.

    MOVE: The 4-question Go-to-Market Framework by Sangram Vajre and Bryan Brown. My day job involved more focus on a full set of go-to-market strategies, and I wanted to gain more knowledge. This book offered a useful lens on the activities of the GTM process.

    The Dark Hours by Michael Connelly. I’m a sucker for just about anything from Connelly. Harry Bosch is a legendary character at this point, and I’m becoming just as big a fan of Renée Ballard. I also read Desert Star, which featured these two.

    Leading Leaders: How to Manage Smart, Talented, Rich, and Powerful People by Jeswald W. Salacuse. I’m in the enviable position of leading a team of senior folks and I want to be better at it. This book offered good guidance on strategic conversations, org integration, coaching, motivation, and more.

    Loved: How to Rethink Marketing for Tech Products by Martina Lauchengco. The best companies do product marketing differently than others. The author does a terrific job looking at listening, positioning, and astutely applying GTM strategies.

    Prayer: Experiencing Awe and Intimacy with God by Timothy Keller. Keller passed away this year, but left a giant legacy. I enjoyed this book about the why, when, and how of a fruitful prayer life.

    Ghost Soldiers: The Epic Account of World War II’s Greatest Rescue Mission by Hampton Sides. I’ve become somewhat obsessed with learning about the Pacific theater of WWII, and this story was phenomenal. The courage and resilience of the POWs in the Philippines, and those who rescued them, is remarkable.

    Pompeii: A Novel by Robert Harris. I visited Pompeii this Summer with my son, and then wanted to learn more about this ancient city. This historical fiction about an aquarius in the days leading up to the eruption of Mount Vesuvius was a real page-turner.

    The Terminal List by Jack Carr. Thrilling read—I also read the next two books, True Believer and Savage Son—with good pacing and a hero I was rooting for.

    Failure Is Not an Option: Mission Control from Mercury to Apollo 13 and Beyond by Gene Kranz. Definitely one of my favorite books of the year. This was such a good story about the space program, aiming high, and pursuing excellence. We’ve lost some of this, and I hope we get it back.

    Certain to Win: The Strategy of John Boyd, Applied to Business by Chet Richards. Agility and using your time advantage? That’s what good strategy does. I really enjoyed the historical lessons and applicable advice on creating a strategy that lets you play on your terms.

    Called to Lead: 26 Leadership Lessons from the Life of the Apostle Paul by John MacArthur. Talk about leadership without any traditional “power”! The lessons in this book show how good leadership is much more about influence earned through trust and character.

    Truman by David McCullough. This is a big biography of one of the 20th century’s most consequential presidents. He came into a remarkably difficult situation after FDR’s death, and faced many hard decisions. I appreciated the details about Truman’s early years and what led him from humble beginnings to the highest office in the land.

    Mismatch: How Inclusion Shapes Design by Kat Holmes. One of my goals this year was to learn more about accessibility, and this book seemed like a good fit. This was a book about making intentional choices about inclusion (or exclusion) and the biases that limit who can participate. Very good read.

    With the Old Breed by E.B. Sledge. I think this was the best book I read in 2023. I came across it after watching the miniseries The Pacific. Published over 40 years ago, this book is a visceral look at what war is like, and the toll it took on our men in WWII. It was an emotional and powerful read.

    Babe: The Legend Comes to Life by Robert Creamer. The greatest baseball player ever? Statistically, it’s hard to argue. The Babe ushered in the home run era, and lived larger than life in Boston and New York. A tragic tale at times, but you get the sense that Ruth enjoyed the life he had.

    Social Justice Fallacies by Thomas Sowell. Not a long book, but Sowell continues to be one of America’s great pragmatic thinkers. Are statistical disparities in representation and economic outcomes due to discrimination by dominant majorities? In this fact-filled book, Sowell explores this idea, and whether distant surrogates creating policies for justice are creating more harm than good.

    Why We Love Baseball: A History in 50 Moments by Joe Posnanski. Ask baseball fans for the “50 most magical moments” and you’ll get all sorts of different answers. But I love Joe’s look at what stood out to him, and it reminded me of why this game still captivates me.

    Wiring the Winning Organization by Gene Kim and Steve J. Spear. I recently wrote up a full book review, but pick up this book if you’re a leader or someone who influences how work gets done.

    Marketing for Product-Led Growth by Steve LaChance. PLG is a powerful tool for product companies, and this was probably the most “highlighted” book on my Kindle this year. It’s full of advice on how to re-think the customer journey.

    Hugger Mugger by Robert Parker. I read a few more Spencer books from Parker this year. It’s my guilty pleasure, and I usually finish them in a couple of days. This was the last one I read in 2023, and the gumshoe hasn’t lost a step.

    The War That Doesn’t Say Its Name: The Unending Conflict in the Congo by Jason K. Stearns. I have a friend in Africa, and I realized I knew very little about what happens on the continent. This was a good book on the complex conditions that has made war in the Congo a fact of life.

    The Servant: A Simple Story About the True Essence of Leadership by James C. Hunter. This story about a set of people at a leadership retreat resonated a lot with me. What does real leadership look like? It looks like love. Not the feeling, but the behavior. Patience, kindness, humility, selflessness, respectfulness, forgiveness, honesty, commitment. May we all lead this way in 2024.

    Thanks for sticking with me for another year, and let’s find some excuses to engage in the year ahead.

  • Daily Reading List – December 21, 2023 (#229)

    That’s a wrap on 2023 for me. After today, I’m on leave until January 2nd and am taking a break from blogging and such. Thanks for sticking with me in 2023, and I plan on keeping this “daily reading list” going in 2024. I received some good feedback that folks find this useful, and I’ve enjoyed doing it. See you in the new year!

    [blog] Three pillars of generative AI adoption in 2024, from Google Cloud’s CTO. We’ve all survived the “massive hype” stage of generative AI. So far. Will explains where folks should focus their adoption strategy in 2024.

    [blog] The Top 7 Marketing Metrics for a QBR or Board Meeting. Very good post which I wish I had when I was in Marketing. But now, it applies to what I’m doing with Developer Relations as well.

    [blog] Best practices for consuming public Docker Hub content. There are tons of great images up on the Docker Hub, but you’re accepting risk when using public repositories. This post offers a few ways to reduce your risk.

    [blog] 5 Tips for Building Resilient Architecture. This is a great set of anchor ideas for building systems that can withstand problems.

    [blog] Google recognized as a Leader and positioned furthest in vision among all vendors evaluated in the 2023 Gartner Magic Quadrant for Cloud Database Management Systems. When I think back a few years, many folks (including Gartner) would say (somewhat dismissively) that you’d pick Google Cloud if you really cared about modernization, data, and AI. In 2023, that seems like exactly what every single company should care about.

    [blog] Using Image Streaming with DockerHub. This is a powerful way to start up BIG containers quickly. Seconds instead of minutes. But does it work outside of Google’s own registries? I didn’t know about this pattern. Pretty cool.

    [blog] VueFire is now stable. Web developers who like building with Vue will be happy to see that the cleaner integrations with Firebase are now ready to use.

    ##

    Want to get this update sent to you every day? Subscribe to my RSS feed or subscribe via email below:

  • Daily Reading List – December 20, 2023 (#228)

    Light reading day as I wrapped up work meetings, wrote a blog post, and spent some time building a generative AI app, using AI-assisted tooling. Fun stuff.

    [blog] If software development were a race, AI wins every time. Good post that looks at a study this firm conducted, and where generative AI assistance helped developers.

    [blog] All Architects Must Deliver Business Outcomes. Do we segment “architects” too finely at times? Probably. Every architect should be a “business architect” if that means delivering something the organization as a whole cares about.

    [blog] Future of the Cloud: 10 Trends Shaping 2024 and Beyond. I don’t think anything here will surprise you, but the Pulumi folks pointed out some valid things to pay attention to.

    [blog] Introducing automated credential discovery to help secure your cloud environment. I’ve certainly built demos where I temporarily used environment variables (or hard coded variables!) to store secrets. This new Google Cloud tool helps find and notify you when that happens.

    [blog] Inference Race To The Bottom – Make It Up On Volume? Lots of folks are delivering quality LLMs, which means price pressure.

    [blog] CNCF Cloud Native FinOps + Cloud Financial Management Microsurvey. People spend a lot of their cloud budget on Kubernetes. Why? Human factors like over provisioning, lack of accountability, and poor planning. Use fully managed Kubernetes wherever possible.

    ##

    Want to get this update sent to you every day? Subscribe to my RSS feed or subscribe via email below:

  • Is “Wiring the Winning Organization” a book for you? Read my five takeaways and decide for yourself.

    Are you still reading technology books? Or do you get your short-form insights from blogs and long-form perspectives from YouTube videos? While I buy fewer books about specific technologies—the landscape changes so fast!—I still regularly pick up tech and business books that explore a particular topic in depth. So when Gene Kim reached out to me in October about reading and reviewing his upcoming book, it was an easy “yes.”

    You know Gene, right? Wrote the Phoenix Project? Unicorn Project? DevOps Handbook? I’ve always enjoyed his writing style and his way of using analogies and storytelling to make complex topics feel more approachable. Gene’s new book, written with Steven J Spear, is called Wiring the Winning Organization. This book isn’t for everyone, and that’s ok. Here were my five major takeaways after reading this book, and hopefully this helps you decide if you should pick up a copy.

    The book could have been a 2-page paper, but I’m glad it wasn’t. The running joke with most business-focused books is that they contain a single good idea that somehow bloats to three hundred pages. Honestly, this book could have been delivered as a long online article. The idea is fairly straightforward: great organizational performance is tied to creating conditions for folks to do their best work, and this is done by creating efficient “social circuitry” that uses three key practices for solving problems. To be sure, Gene’s already published some articles containing bits from the book on topics like layers of work, social circuitry, and what “slowification” means. He could have stopped there. But this topic feels new to me, and it benefitted from the myriad case studies the authors used to make their case. Was it repetitive at times? Sure. But I think that was needed and it helped establish the framework.

    I wouldn’t have liked this book fifteen years ago. Books like the Phoenix Project are for anyone. It doesn’t matter if you’re an architect, program lead, developer, sysadmin, or whatever, there’s something for you. And, it reads like a novel, so even if you don’t want to “learn” anything, it’s still entertaining. Wiring the Winning Organization is different. There are no heroes and villains. It’s more “study guide” than “beach read.” The book is specifically for those leading teams or those in horizontal roles (e.g. architects, security teams) that impact how cross-team work gets done. If I had started reading this when I was an individual contributor, I wouldn’t have liked it. Today, as a manager, it was compelling to me.

    I have a new vocabulary to use. Every industry, company, and person has words or phrases of their own. And in tech, we’re particularly awful about over-using or mis-using terms so that they no longer mean anything. I’m looking at you, “DevOps”, “cloud”, and now “observability.” But I hope that a lot of folks read this book and start using a few of its terms. Social circuitry is a great one. The authors use this to refer to the “wiring” of a team and how knowledge and ideas flow. I’ve used this term a dozen times at work in the past month. The triplet of practices called out in the book—amplification (where are the problems) which results in slowificaion (create space for problem solving) and simplification (make problems themselves easier to solve)—should become common as well. The book introduced a handful of other phrasings that may catch on as well. That’s the hallmark of an impactful book.

    A business strategy without a corresponding change in social circuitry is likely flawed. Early in the book, the authors make the point that we’ve been trained to think that competitive advantage comes from creating an unfair playing field resulting from superior understanding of Porter’s five forces. Or from having a better map of the territory than anyone else. Those things are important, but the book reinforces that you need leaders who “wire” the organization for success. Having the right people, the right tools, and a differentiated strategy may not be enough to win if the circuitry is off. What this tells me is that if companies announce big strategic pivots without a thoughtful change in org structure and circuitry, it’s unlikely to succeed.

    Good management is deliberate. My biggest mistake (of many) in the early years of my management career was undervaluing the “management” aspect. Management isn’t a promotion for a job well done as an individual contributor; it’s a new job with entirely different responsibilities. Good managers activate their team, and constantly assess the environment for roadblocks. This book reminded me to think about how to create better amplification channels for my team so that we hear about problems sooner. It reminded me to embrace slowification and define space for thinking and experimentation outside of the regular operating channels. And it reminded me to ruthlessly pursue simplification and make it easier for my team to solve problems. The most important thing managers do is create conditions for great work!

    I enjoyed the book. It changed some of my thinking and impacted how I work. If you grab a copy let me know!

  • Daily Reading List – December 19, 2023 (#227)

    As I complete tasks in front of me, I’m hoping to have some cycles on Wednesday or Thursday to experiment with new tech and build something. That feeling of seeing an app compile and start up is still a rush!

    [blog] VideoPoet: A large language model for zero-shot video generation. AI-driven video generation is wild. Especially using just a single LLM. Check out this post for some pretty amazing example videos. And skim through the standalone site for the project.

    [blog] Ray on Vertex AI: Let’s get it started. Plenty of folks run frameworks like Ray on VMs or Kubernetes clusters. But if you want to run and scale AI and Python apps without worrying about infrastructure, this is a post worth reading.

    [blog] Are the Big 4 about to get their lunch eaten by GenAI? Is generative “just another technology tool” or a disruptor the world’s biggest IT consulting firms? Probably the latter.

    [blog] More than 10k scientific papers were retracted in 2023. Even the “experts” make mistakes, and a healthy disregard for “consensus” is probably not a terrible thing.

    [docs] Build hybrid and multicloud architectures using Google Cloud. What passes as “guidance” about hybrid and multicloud strategy in our industry is honestly pretty weak. You see some generic tips, but very little that’s actionable. This new three-part series in our docs is 140 pages of the best content I’ve seen on the topic.

    [article] Practical Magic: Improving Productivity and Happiness for Software Development Teams. The LinkedIn Engineering team open sourced their framework for understanding developers and their needs. Good resource!

    [blog] Migrating from Cassandra to Bigtable at Latin America’s largest streaming service. A lift-and-shift migration to the cloud(s)—and maybe swapping a self-managed version of an infrastructure component for a managed version—is probably the safest bet. It’s also the least satisfying for most as they wonder why the performance, scale, and cost don’t match up with their expectations. This is a good story of a replatforming that paid off.

    [blog] Product Predictions 2024. Spicy wisdom and opinions from Marty in this post. Product management might be in the “trough of disillusionment” right now for many leaders, but strong product leadership has never been more important.

    [blog] Democratizing access to AI-enabled coding with Colab. There aren’t many places with more monthly active devs than Colab. Now those 10+ million folks have access to even more AI assistance.

    ##

    Want to get this update sent to you every day? Subscribe to my RSS feed or subscribe via email below:

  • Daily Reading List – December 18, 2023 (#226)

    I suspect that our bodies know when we’re “ready” to get sick. Last Friday, I had completed nearly all my big tasks for the year. So naturally, on Saturday I had 102.5 degree fever and slept for 10 hours. Feeling a bit better today, but I’m glad it’s going to be a quiet week!

    [blog] Cross-cloud materialized views in BigQuery Omni enable multi-cloud analytics at scale. Here’s some unique new capabilities in Google Cloud that makes it easier to do cross-cloud analytics.

    [blog] Using Gemini models from Go. Simple demo, but it shows how straightforward it is to consume the Gemini model from your Go code.

    [blog] What User Interface Framework Should You Choose for .NET Desktop Applications? Goodness, there are way too many choices for .NET devs building desktop apps.

    [blog] Cloud CISO Perspectives: How the AI megatrend can help manage threats, reduce toil, and scale talent. Here’s the latest links on security topics, plus some opinions on AI as a “megatrend” for security teams.

    [blog] Let Code Speak for Itself. I’m not a “no comments” guy; even well-written code can benefit from a little extra context. But this short post reminds us not to abuse comments.

    [article] Mentoring software engineers or engineering leaders. All of us could use mentorship, and many of us have something to offer as mentors ourselves. Maybe lean into both of those in 2024?

    [docs] About custom targets. I read through these docs related to new functionality in Google Cloud Deploy. This continuously deployment tool just added “custom targets” which lets you use sophisticated CD capabilities for a variety of destinations. Initial samples include Terraform, GitOps, and Vertex AI.

    [article] Web Development in 2023: JavaScript Still Rules, AI Emerges. Plenty of trends to look at for 2023, but here are a handful for web development.

    [blog] Advancements in machine learning for machine learning. Using machine learning to improve machine learning? At some point there’s a problem, but it seems suitable for certain scenarios like this.

    ##

    Want to get this update sent to you every day? Subscribe to my RSS feed or subscribe via email below:

  • Daily Reading List – December 15, 2023 (#225)

    It’s the end of an exciting week at work, and if today is any indication, people are starting to wind down for the year. I’m ok with that. The content keeps coming though, and I read some great items today. See below!

    [article] Using Traffic Modeling to Load-Balance Netflix Traffic at Global Scale. Don’t skip this just because you don’t have Netflix-sized routing demands; there’s useful advice here for anyone thinking about resilience and performance.

    [article] Why hasn’t LinkedIn moved to Azure? Sometimes, a move just isn’t necessary. Not all of Google runs on Google Cloud, nor does every Microsoft business run on Azure. If you’re already unbelievable at infrastructure and software in your current place, stay put. Snarkier take here.

    [docs] Migrate from service account keys. These keys offer an easy way to access cloud services, but can also open you up to security risks. This is a good guide for those planning to migrate to an alternative.

    [blog] The Thoughtful HIPPO. Excessive local empowerment is a trap! I think most of us appreciate leadership that sets direction and priority that helps us strategize accordingly.

    [blog] Build apps faster with new Duet AI in Google Cloud training content. Releasing the new product itself is only a small part of the story. I’m glad that we also shipped seven training courses for this new AI assistant. Try them out!

    [article] Enterprise cloud aspirations hindered by buyer’s remorse. Don’t treat the cloud like someone else’s data center. Use it as an accelerator of technology improvement.

    [blog] Open sourcing tools for Google Cloud performance and resource optimization. I like this. Here are some tools for getting bin packing recommendations, install benchmarking tools in Kubernetes, and more.

    [article] When it comes to generative AI in the enterprise, CIOs are taking it slow. Very well may be true, but every survey is a trailing indicator. The landscape is changing too fast, and we’re focused on having all the right offerings for whenever the customer is ready to go.

    ##

    Want to get this update sent to you every day? Subscribe to my RSS feed or subscribe via email below: