Hello, I'm Shrijith Venkatramana. I'm building git-lrc, an AI code reviewer that runs on every commit. Star Us to help devs discover the project. Do give it a try and share your feedback for improving the product.
Large Language Models have made it surprisingly easy to generate text.
Building a reliable AI application, however, is a completely different problem.
Once you move beyond a simple "send prompt, get response" demo, you quickly encounter real-world concerns:
- Prompt management
- Structured outputs
- Multi-step workflows
- Tool calling
- Observability
- Evaluation
- Model switching
- Production debugging
Many teams end up creating custom frameworks around OpenAI, Anthropic, Gemini, or local models just to manage these concerns.
This is where Genkit comes in.
Originally developed by Google, Genkit provides a framework for building AI-powered applications with a focus on workflows, tooling, observability, evaluation, and production readiness.
While most examples online focus on Node.js, Genkit now has growing support for Go, making it an interesting option for backend engineers who want AI capabilities without introducing an entirely separate application stack.
In this article we'll build practical examples and explore how Genkit helps structure real-world AI systems.
Why Genkit Exists
Most AI applications evolve like this:
Phase 1:
response := callLLM(prompt)
Everything seems simple.
Phase 2:
You need:
- Retry logic
- Prompt versioning
- JSON outputs
- Tool integrations
- Tracing
- Metrics
- Human review workflows
Now your codebase starts accumulating AI-specific infrastructure.
Genkit attempts to provide these building blocks from day one.
Think of it as:
"Spring Boot for AI workflows" rather than "an LLM SDK."
Installing Genkit for Go
Create a new project:
mkdir genkit-demo
cd genkit-demo
go mod init github.com/example/genkit-demo
Install Genkit:
go get github.com/firebase/genkit/go/ai
Depending on your provider, you'll also install provider plugins.
For Gemini:
go get github.com/firebase/genkit/go/plugins/googleai
Your First AI Call
Let's start with a simple generation.
package main
import (
"context"
"fmt"
"github.com/firebase/genkit/go/ai"
"github.com/firebase/genkit/go/genkit"
"github.com/firebase/genkit/go/plugins/googleai"
)
func main() {
ctx := context.Background()
g, err := genkit.Init(ctx,
genkit.WithPlugins(
&googleai.GoogleAI{
APIKey: "YOUR_API_KEY",
},
),
)
if err != nil {
panic(err)
}
resp, err := g.Generate(ctx, ai.GenerateRequest{
Model: "googleai/gemini-2.5-flash",
Prompt: "Explain vector databases in one paragraph.",
})
if err != nil {
panic(err)
}
fmt.Println(resp.Text())
}
This resembles a normal LLM call, but Genkit's value becomes more apparent when applications grow beyond this stage.
Structured Outputs: Stop Parsing AI Text
One of the most common mistakes in AI systems is asking models to return text and then parsing it manually.
Instead of:
Name: John
Score: 87
Risk: Medium
Use schemas.
Imagine a customer-support ticket classifier.
type TicketClassification struct {
Category string `json:"category"`
Priority string `json:"priority"`
Summary string `json:"summary"`
}
Prompt:
Classify this support ticket.
Return JSON matching the schema.
Now downstream services can safely consume the result.
Real-world uses:
- Lead qualification
- Risk analysis
- Invoice extraction
- Customer support routing
- Contract review
Structured outputs dramatically reduce prompt fragility.
Building Multi-Step AI Workflows
Most production AI systems involve multiple steps.
Example:
Customer email arrives.
Workflow:
- Summarize email
- Detect sentiment
- Extract action items
- Generate response draft
- Send for human review
Without a framework:
Controller
├─ LLM Call #1
├─ LLM Call #2
├─ LLM Call #3
└─ LLM Call #4
Logic becomes difficult to maintain.
With Genkit, you can model the workflow as a flow.
summaryFlow := genkit.DefineFlow(
g,
"summarizeCustomerEmail",
func(ctx context.Context, email string) (string, error) {
result, err := g.Generate(ctx, ai.GenerateRequest{
Model: "googleai/gemini-2.5-flash",
Prompt: "Summarize:\n\n" + email,
})
if err != nil {
return "", err
}
return result.Text(), nil
},
)
Flows become reusable application components rather than scattered LLM calls.
Tool Calling: Let the Model Use Your Systems
A common misconception is that AI models should know everything.
In reality:
Models should reason.
Systems should provide facts.
Imagine an order-tracking assistant.
Instead of teaching the model about orders:
Order #78291
Status: Shipped
Carrier: FedEx
ETA: Tomorrow
Expose a tool.
func GetOrderStatus(orderID string) string {
return "Shipped"
}
The model decides:
I need order information.
Call tool.
Read result.
Answer user.
This pattern enables:
- Database lookups
- CRM access
- Internal APIs
- Inventory systems
- Knowledge bases
Many enterprise AI systems are essentially:
LLM + Tools
rather than
LLM + More Prompting
Observability: The Feature Most Teams Discover Too Late
Suppose users report:
"The AI gave a terrible answer."
Without tracing, you're blind.
Questions immediately arise:
- Which prompt was used?
- Which model answered?
- What context was supplied?
- Which tool calls executed?
- How much did it cost?
Genkit includes observability capabilities that make debugging AI workflows significantly easier.
Traditional debugging:
Error at line 87
AI debugging:
Prompt
→ Context
→ Tool Calls
→ Model Output
→ Final Result
This is often the difference between a manageable production system and weeks of confusion.
Real Example: AI-Powered Incident Summaries
Imagine you're running a platform team.
Every incident generates:
- Slack messages
- Alerts
- Logs
- Jira tickets
Engineers spend time creating incident reports.
A Genkit workflow could:
- Collect incident data
- Summarize timeline
- Identify root cause indicators
- Draft postmortem
- Suggest follow-up actions
Pseudo-flow:
Alerts
↓
Summarization
↓
Root Cause Analysis
↓
Draft Postmortem
↓
Engineer Review
This is exactly the type of repeatable, multi-step process where Genkit shines.
Model Portability Matters More Than Most Teams Expect
Early-stage teams often assume they'll stay with one model forever.
Reality:
- Pricing changes
- New models appear
- Performance shifts
- Compliance requirements emerge
Today's choice:
Gemini
Six months later:
Anthropic
Twelve months later:
Local model
Frameworks that separate application logic from model providers reduce migration pain.
Genkit encourages this separation.
Your workflow logic remains relatively stable while models evolve underneath.
Common Mistakes When Adopting Genkit
1. Treating It Like Another SDK
Genkit is most valuable when you embrace workflows, tools, schemas, and evaluation.
Using it only for text generation leaves much of its value unused.
2. Over-Automating
Not every process should become autonomous.
Many successful systems use:
AI → Human Review → Action
rather than
AI → Action
3. Ignoring Evaluations
A workflow that works today may degrade after:
- Prompt changes
- Model upgrades
- Data changes
Evaluation should be treated as seriously as unit testing.
Final Thoughts
The AI ecosystem currently has no shortage of model providers.
What many teams actually need is better infrastructure around those models.
Genkit addresses a practical gap between simple API calls and production-grade AI systems. It provides a structured way to build workflows, integrate tools, monitor behavior, and evolve applications as models change.
For Go developers, that's particularly valuable because it allows AI capabilities to live inside existing backend services rather than forcing a separate JavaScript stack.
The interesting question is no longer:
"Which model should I use?"
It's increasingly:
"How do I build a system that can survive five generations of models?"
Frameworks like Genkit are one possible answer.
If you were building an AI-powered product today, which capability would you invest in first:
better models, better prompts, better tools, or better workflows?
And more importantly, which of those do you think will still be a competitive advantage three years from now?
*AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.
git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.*
Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use.
HexmosTech
/
git-lrc
Free, Micro AI Code Reviews That Run on Commit
| 🇩🇰 Dansk | 🇪🇸 Español | 🇮🇷 Farsi | 🇫🇮 Suomi | 🇯🇵 日本語 | 🇳🇴 Norsk | 🇵🇹 Português | 🇷🇺 Русский | 🇦🇱 Shqip | 🇨🇳 中文 |
git-lrc
Free, Micro AI Code Reviews That Run on Commit
AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.
git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.
See It In Action
See git-lrc catch serious security issues such as leaked credentials, expensive cloud operations, and sensitive material in log statements
git-lrc-intro-60s.mp4
Why
- 🤖 AI agents silently break things. Code removed. Logic changed. Edge cases gone. You won't notice until production.
- 🔍 Catch it before it ships. AI-powered inline comments show you exactly what changed and what looks wrong.
- 🔁 Build a…
Top comments (0)