897 karma · joined August 26, 2022
LLMs can't produce intellectual rigour. They get fine details wrong every time. So indeed using ChatGPT for doing your reasoning for you produces inferior results. By normalising non-rigorous yet correct sounding answers, we drive down the expectations.
To take a concrete example, if you tell a student to implement memcpy with chatgpt, and it will just give an answer which uses uint64 copying. The student has not thought from first principles (copy byte by byte? Improve performance? How to handle alignment?). This lack of insight in return to immediate gratification will bite later.
It's maybe not problem for non-STEM fields where this kind of rigor and insight is not required to excel. But in STEM fields, we write programs and prove theorems for insight. And that insight and the process of obtaining it is gone with AI.
Beside the obvious "deep work", its the ability to be bored, and shut down time.
> I read it, but like most self-help books - I felt like it could've been 1/4 the size. The book could've been 10-20 pages.
Have to agree. It can be summarized.
Invariant blog post mentions this:
> Conclusion: Agents require extensive, highly-contextual guardrailing and security solutions
> As one of our core missions at Invariant, we absolutely cannot stress enough how important it is to rely on extensive guardrailing with AI models and their actions. We come to this conclusion repeatedly, as part of our research and engineering work on agentic systems. The MCP ecosystem is no exception to this rule. Security must be implemented end-to-end, including not only the tool descriptions but also the data that is being passed to and from the AI model.
B. Version the tool descriptions so that they can be pinned and do not change (same way we do for libraries and APIs).
C. Maybe in future, LLMs can implement some sort of "instruction namespacing" - where the developer would be able to say any instruction in this prompt is only applicable when doing X, Y, Z.
The disadvantage is that it's not easily embeddable in your own programs - so programs use JSONPath / Go templates often.
There is a gitlab CI feature `include`, but you pretty much have to write shell scripts inside YAML, losing on whole developer experience (shellcheck etc..). I would recommend this way only if you can't factor your code into a CLI in proper language.
That said, if you absolutely need to use shell script for reasons, keep it all in single script, define logging functions including debug logs, rigorously check every constraint and variable, use shellcheck, factor the code well into functions - I should sometimes write a blog post about it.
* pull
* push
* checkout / switch
* commit (ofcourse)
* merge
But I will end up needing
* log / log --stat
* stash
* diff
* show / show --stat
* blame
* revert
* cherry-pick
* reset
* git grep (can be replaced with rg / grep -rn)
I can't imagine not having these commands now.
If you use something frequently you should know it in-depth. It applies to tools (git, VSCode), frameworks (Spring, Django, whatever), infra (kubernetes, docker). otherwise you're missing out.
But in gui applications and servers, you will need to catch and report the error in some intermediate boundary, not exit the application. That's where go falls short.
Try micronaut once. It does DI and even ORM mapping (with micronaut data jdbc) at compile time and avoids most reflection.
If you're running one team with all services trusting each other, you don't have problems solved by these things. Whenever you introduce a CNCF component outside core kubernetes, invest time in understanding it and why it does what it does. Nothing is "deploy and forget" and will need to be regularly checked and upgraded, and when issues come up you need some architecture-level of the component to troubleshoot because so many moving parts are there.
So if I can get away writing my own cronjob in 1000 lines rather than installing something from GitHub with a helm chart, I will go with the former option.
(Helm is crap though, but you often won't have much choice).
``` a = append(a, elem) ```
If you assign it to anything else, `a` might still remain with the older slice memory which will cause worse problems than equality comparison.
So the kind of code you wrote is hardly ever written in production.
The advantage of having this is avoiding one more heap allocation for slice, which is a good tradeoff if you ask me.
I used a certain tool which had its own config format, and it's "cloudnative" operator implemented CRDs of which multiple can exist and they would update the config file in some mounted volume. Such thing is a hell to debug. Why can't we just store the config file in configmap/ secret and listen to changes?
(If we had a better templating solution than helm, I think quite a few operators wouldn't need to exist.)