Skip to content

Initial agent skills blog post

40dc4a6
Select commit
Loading
Failed to load commit list.
Draft

WIP: How To Train Your Agent blog post #361

Initial agent skills blog post
40dc4a6
Select commit
Loading
Failed to load commit list.
reviewfn / succeeded May 13, 2026 in 1m 23s

AI Code Review Results

AI Pull Request Overview

Disclaimer: This review was generated by automated AI and may contain errors. Do not trust its outputs without human verification.

Summary

  • New blog post introducing OpenFaaS Agent Skills and the openfaas-function-dev skill.
  • Three end-to-end examples are presented: a Node.js AES-decrypt function, a Python Hacker News monitor, and a Go geo-enrichment function.
  • The post is marked WIP in the PR title; some editorial rough edges may still be present.
  • The Go handler (enrich-telemetry) has a subtle logic error where a partial database-open failure causes all subsequent invocations to return 500, even though the successfully-opened database could still serve partial enrichment.
  • The Python handler's search_hn uses a 24-hour lookback window while the cron runs every 15 minutes; this is not wrong due to deduplication, but the inconsistency is unexplained and may confuse readers.
  • The Node.js handler reloads the master key from disk on every invocation; for a tutorial function this is acceptable, but the post does not acknowledge the per-request file I/O.
  • Images are present and referenced correctly.

Approval rating (1-10)

6/10. The content is well-structured and the examples are practical, but the Go handler contains a real correctness issue that readers may copy verbatim.

Summary per file

Summary per file
File path Summary
_posts/2026-05-12-how-to-train-your-agent-to-write-functions.md New blog post with three worked AI agent examples; contains a logic error in the Go snippet.
images/2026-05-how-to-train-your-agent/background.png Hero background image.
images/2026-05-how-to-train-your-agent/discord-hn-serverless-monitor.png Screenshot of Discord output from the HN monitor example.
images/2026-05-how-to-train-your-agent/dragon-training.png Illustrative image used in the introduction.

Overall Assessment

The post is well-written and the three examples cover a useful range of complexity. The framing — that agent skills give models the right context to avoid common OpenFaaS mistakes — is clear and the narrative follows through on that claim. The main concern is the Go handler snippet, which contains a correctness issue readers will likely replicate. The Python example has a minor inconsistency worth clarifying. Both are fixable in-place before publication.

Detailed Review

Detailed Review

Go handler — partial DB open leaves the function permanently degraded

handler.go lines 529–545 (the initDBs function):

cityDB, err = geoip2.Open(filepath.Join(dir, "GeoLite2-City.mmdb"))
if err != nil {
    initErr = err
    log.Printf("ERROR opening GeoLite2-City.mmdb: %v", err)
    return
}
asnDB, err = geoip2.Open(filepath.Join(dir, "GeoLite2-ASN.mmdb"))
if err != nil {
    initErr = err
    log.Printf("ERROR opening GeoLite2-ASN.mmdb: %v", err)
}

If cityDB opens successfully but asnDB fails, initErr is set while cityDB is valid and open. The Handle function then gates on initErr != nil and returns 500 for every subsequent request, permanently, because sync.Once will not retry. The function is fully broken even though city-level enrichment would work fine.

Since both databases are embedded in the image at build time, the failure scenario is uncommon in production, but the code will mislead readers about how to handle partial initialisation. The fix is either to treat the two databases as independent (check cityDB != nil / asnDB != nil per lookup, which the rest of the code already does) and not use a single initErr, or to keep initErr but set it only when the function is completely unable to serve any lookups.

Python handler — search window vs. cron interval mismatch is unexplained

handler.py line 410:

hits += search_hn(query="serverless", tags=tags, num_hours=24)

The function is scheduled every 15 minutes but searches the last 24 hours on every invocation. This is safe because the database deduplicates hits, but the first invocation will attempt to post up to ~100 items (50 per story/comment page) that accumulated over the previous day. The post does not mention this and readers following along may be surprised by a burst of Discord notifications on first deploy. A brief callout that the wide window is intentional and that deduplication absorbs the overlap would prevent confusion.

Node.js handler — master key is read from disk on every invocation

handler.js lines 142–149 (loadMasterKey): the key is read and validated synchronously on each request. For a tutorial this is low-stakes, but the post presents the handler as production-quality. If the post is meant to model best practice, a note acknowledging the per-request I/O (or caching the key at module load) would be consistent with the care taken elsewhere in the handler.

Editorial — WIP title

The PR title is "WIP: How To Train Your Agent blog post". The post reads as substantially complete; if there are specific sections still in progress, flagging them explicitly (e.g. with a TODO comment in the draft or a checklist item in the PR description) would help reviewers know what to focus on.

AI agent details.

Agent processing time: 1m8.812s
Environment preparation time: 5.351s
Total time from webhook: 1m29.235s