Hacker Newsnew | past | comments | ask | show | jobs | submit | dimtion's commentslogin

I'm not sure why people struggle with the fact that an abstraction can be built on top of a non-deterministic and stochastic system. Many such abstractions already exist in the world we live.

Take sending a packet over a noisy, low SNR cell network. A high number of packets may be lost. This doesn't prevent me, as a software developer, from building an abstraction on top of a "mostly-reliable" TCP connection to deliver my website.

There are times when the service doesn't work, particularly when the packet loss rate is too high. I can still incorporate these failures into my mental model of the abstraction (e.g through TIMEOUTs, CONN_ERRs…).

Much of engineering and reliability history revolves around building mathematical models on top of an unpredictable world. We are far from solving this problem with LLMs, but this doesn't prevent me from thinking of LLMs as a new level of abstraction that can edit and transform code.


I'm fine with that. The part that makes it not really an abstraction is, you still deliver code in the end. It'd be different if your deliverable were prompt+conversation, and the code were merely an intermediate build artifact. Usually people throw away the convo. Some have tried making markdown files the deliverable instead, so far that doesn't really work.

It makes even less sense when people compare an LLM to a compiler. Imagine making a pull request that's just adding a binary because you threw the source code away.


The whole field of reproducible builds is only a field because compilers also have had trouble historically of producing binary artifacts with guaranteed provenance and binary compatibility even when built from the same source codes.

If I assign a bug fix ticket to a human developer on my team, I won't be able to precisely replicate how they go about solving the bug but for many bugs I can at least be assured that the bug will get solved, and that I understand the basic approach the assigned dev would use to troubleshoot and resolve the ticket.

This is an organizational abstraction but it's an abstraction just the same, leaky as it is.


> The whole field of reproducible builds is only a field because compilers also have had trouble

No, this is not comparable. The reason reproducible builds are tricky is not because compilers are inherently prone to randomness, it's because binaries often bake-in things like timestamps and the exact pathnames of the system used to produce the build. People need to stop comparing LLMs to compilers, it's an embarrassingly poor analogy.


> The reason reproducible builds are tricky is not because compilers are inherently prone to randomness

And neither are LLMs. Having their output employ randomness by default is a choice, not a requirement, just like things like embedding timestamps into builds is a choice that can be unwound if you want the build to be reproducible.

> People need to stop comparing LLMs to compilers, it's an embarrassingly poor analogy.

They are certainly different things, but if you are going to criticize LLMs it would be better if you understood them.


> Having their output employ randomness by default is a choice, not a requirement

This is not really meaningfully true. E.g. batching, heterogeneous inference HW, and even differences in model versions can make a difference in what result you get, and these are hard to solve.


But again, these are all things that are also true of build systems.

GCC 16.1 vs. 15.2 will get you differences. GNU ld vs. gold vs. mold vs. lld will get you differences. Whether you do or do not employ LTO or other whole-program optimization vs. whether you do gets you differences.

Have you never debugged a race condition that worked on your machine but didn't work in prod, based only on how things ended up compiled in the final binary?

I'm not saying these are identical but there's a lot more similarity than you all seem to understand. And we've made compilers work well enough that a lot of you believe that they give very routine, very deterministic outputs as part of broader build systems even though nothing could be further from the truth, even today.


Are you arguing that the output of an LLM isn’t random?


It is random if you select it to be (temperature != 0, etc.).

It is not random if you don't use random sampling in its output generation.

It the whole thing were actually stochastic then prompt caching would be impossible because having a cache of what the previous tokens transformed into to speed up future generation would be invalidated by the missing random state.

Look at llama.cpp, you can see what samplers are adjustable and if you use samplers that employ randomness you can see what settings disable the random sampling. Or you can employ randomness but fix the seed to get reproducible results.


Yes, it can still be random with temperature set to 0. It'll only be the same if you run it on exactly the same hardware every single time.


An LLM is a set of structured matrix multiplies and function applications. The only potentially non-deterministic step is selecting the next token from the final output and that can be done deterministically.


Matrix multiplication on GPUs is non-deterministic. As are things like cumsum()

https://docs.pytorch.org/docs/2.11/generated/torch.use_deter...

This comes down to map reduce and floating point's lack of associativity. You see the same thing with OpenMP on CPUs.

People are constantly claiming determinism in LLMs that is just not there.


Even if it were reproducible, realistically most people are using some service like Claude that makes no guarantee that the model or hardware didn't change. Which is fine, it doesn't need reproducibility.

This is interesting though, I didn't know PyTorch had a debug mode for reproducibility.


Even with this debug mode, a different batch size can give different results for the same input - e.g. your tensor multiplies might use different blocking, hence different associativity.

I posted that to show that at a bare minimum, there is some pretty extreme nondeterminism (though probably mild in effect) in even the most pedestrian GPU inference, unless you go to the extreme of using the debug mode and taking the potential performance hit.


well just run all inference on the cpu, single threaded /s


random isnt the right term.

ill conditioned or unstable is better

a small change in the input can create a large difference in the output.


> And neither are LLMs.

This is not my claim, you're veering wildly off course here. I'm merely responding to the common, tiresome and, to be frank, stupid analogy of LLMs to compilers.


It's an abstraction for you, not the rest of that developer's team, who have to reproduce the same solution even after said developer has "won the lottery", so-to-speak.

inb4: "Don't worry, just use GPT to make the docs"


If you throw away the code then yeah, but I've never seen anyone do this.


but even if it didn't it still provided a binary that is mathematically proven (assuming no compiler bugs, which if found are fully fixable, unlike LLMs) to correspond to the code you wrote.


This is a great point. We’re very much in a transitional phase on this, but I personally do see signs in my own work with agents that we are heading toward the main deliverable being a readme/docs.

The code is still important, but I could see it becoming something that humans rarely engage with.


Besides deeply unpredictable factors (like signal transmission), most users of higher-level abstractions do so without certainty about how the translation will be executed. For example, one of the main selling points of C when I was growing up was that you could write code independent of architecture, and leave the architecture-specific translation to assembly to the compiler!

Abstractions often embrace nondeterministic translation because lower level details are unknown at time of expression -- which is the moivation for many LLM queries.


Grocery stores are a level of abstraction. Exchange money, get food. If your whole life you had grown food, it might feel a bit strange.

Occasionally the low level details leak through ie: this egg came from this farm, theres a shipping issue so onions are more expensive or whatever.

I think llm assisted coding is going to work something like this.


but you either exchange money and get the food you want, always. Or it's out of stock, so you don't get the food but you keep your money, guaranteed.

It's not a good analogy. With an LLM you might ask for a pea, be parted with your money, and be given a watermelon.


So LLMs are more like InstaCart or DoorDash.


> We are far from solving this problem with LLMs, but this doesn't prevent me from thinking of LLMs as a new level of abstraction that can edit and transform code.

That's more anthropomorphism than an abstraction. An LLM talks like a person because it was trained to predict continuations of human speech. That does not make it a person, or a system with intent, responsibility or any other human attribute. They are what they are: text prediction engines.

Perhaps your input to the LLM is "make all the test cases pass", and so it predicts it better do something to make the test cases pass, and does so by deleting the test cases. I guess in the "abstract" sense it did what you asked.

Or, how about the case in the news from a few days ago where an agentic system deleted all the vendor's customer's data, and last 3 months of backups, despite having been EXPLICITLY "told" not to do any such thing. Should we consider "completely fuck the customer" as an "abstraction" of "never delete any data"?


People are really really weird about the non-determinism thing. Got someone very adamant that Prompt API shouldn't be a web standard because the output isn't deterministic and according to them that means we can't allow prompts.

Such strong correlation between narrow specific demands on how things have to be & posting, in general. I'd really like to see open mindedness & exploratory views be more frequent and have better standing, in general.

I do tend to think this is different than a level of abstraction. But it feels like it's trying to hit hard, on a pretty weird narrow point.


that would make sense if ai said "fail. i dont know" . Its active deception is what makes it difficult.


There’s a big difference between a packet being dropped and a packet’s meaning being changed along the way. The latter is better analogised to what LLMs do between receiving inputs and outputs.


This is about the reverse: a non-deterministic/stochastic system built using reliable abstractions.

Also, the problem of "did we receive the, and is it correct" is vastly trivial compared to "did we get correct LLM output".

The problem in networking is making the reliable transfer perform well under many conditions, and scale.

Getting consistently reliable output of LLMs isn't solved, so we can't talk about it scaling to even one instance.


> I'm not sure why people struggle with the fact that an abstraction can be built on top of a non-deterministic and stochastic system. Many such abstractions already exist in the world we live.

It depends on what's the abstraction.

Using LLM for coding is 'abstracting' the developer, adding extra layer that can produce code. But it's not abstraction layer of the code itself.


Machine itself is built on top of non deterministic world.

While your code is executing asteroid from space may hit it and halt execution.


The kicker is when you delegate some work to another team member and discover that humans are also non-deterministic.


We can mitigate a lot of the problems with humans being non-deterministic by establishing trust and consequences

There are no consequences for a bad output from an LLM and idk about you but I don't trust them


Is "Mostly-reliable" TCP connection a real thing? A TCP connection is either reliable or not working at all. That is what a proper abstraction should be like.


If people can figure out how to write RFCs about IP over carrier pigeons for April Fools, they can figure out how to conceive of LLMs as a layer of abstraction beneath a protocol as well.


You need to be able to define exactly what it's abstracting.

ex: std::shared_ptr is abstracting over raw pointers, and does refcounting. It is abstracting something but you can actually know exactly what that thing is. An LLM is an abstraction over the space of all possible computer programs. If an abstraction doesn't constrain you in some way, it's not an abstraction.


A transmission error has a strictly contained, predictable blast radius. If a packet drops, the system knows exactly how to handle it: it throws a timeout, drops a connection, or asks for a retry. The worst-case scenario is known.

A reasoning error has an infinite, unpredictable blast radius. When an LLM hallucinates, it doesn't fail safely but it writes perfectly compiling code that does the wrong thing. That "wrong thing" might just render a button incorrectly, or it might silently delete your production database, or open a security backdoor.

You can build reliable abstractions over failures that are predictable and contained. You cannot abstract away unpredictable destruction.


> A reasoning error has an infinite, unpredictable blast radius.

Says who? It’s quite easy to limit the blast radius of a reasoning error.


In 2024, a Chevy dealership deployed an AI chatbot that confidently agreed to sell a customer a 2024 Chevy Tahoe for $1. It executed a catastrophic business failure simply because it didn't know the logic was wrong.

Sure, you can patch that specific case with guardrails, but how many unpredictable edge cases are you going to cover? It only takes a user with a bit of ingenuity to circumvent them. There are already several examples of AI agents getting stuck in infinite loops, burning through massive API bills while achieving absolutely nothing.

You can contain a system failure, but you cannot contain a logic failure if the system doesn't know the logic is wrong.


This would be more convincing if a single car had been exchanged for $1.

It didn't happen. Seems the bug was "contained".

Sort of undermines your point re "catastrophic business failure" don't you think?


You literally can contain a logic failure. If I execute logic on my computer that’s not connected to the internet it can’t get out of the box. Done. Contained


> but how many unpredictable edge cases are you going to cover?

This is the wrong question. The correct question is what specific subsets of cases do you allow, similar to any security question


How so?

Suppose you had:

Math() Add() Subtract()

Program() Math(“calculate rate”)

This is intentionally written vaguely. How do you limit that these implementations ensure Program() runs and does the right thing when there is no guarantee Math() or its components are correct?

Normally you could use a typed programming language, unit tests, etc, but if LLM is the ultimate abstraction programs will be written line above. At some point traditional software engineering principles will need to apply.


Very few people are even beginning to understand the constraints of these systems, and none of them have yet been elevated to high enough positions of prominence to rise above the noise of all the hype. Give us some time man, jeez


A transmission error does not have a strictly contained blast radius.

A bad packet could tell a flying probe to fire all thrusters on and deplete its fuel in 15 minutes.

What makes a transmission error controlled is all the protection mechanisms on top of it. An LLM cannot delete a production database unless you give it access to do it.

My hot take is that many people are naturally more comfortable with deterministic systems that have clearly analyzable outcomes. Software engineering has historically primarily been oriented around deterministic systems and it has attracted that type of thinker.

But many of us, myself included, prefer chaotic systems where you can’t fully nail down every cause and effect. The challenge of building a prediction model on top of chaos is exhilarating. I really don’t find many people like me in SWE as in, say, the graphics design department.

To me, that’s the underlying threat here — LLMs are rewriting a field that has previously self selected a certain type of person and this, quite understandably, rubs them the wrong way.


Yes, but when all it takes to avoid this chaos is hiring someone with at least 5 or 10 years of experience for a reasonable wage, this entire perspective looks insane.

It's... just... not that hard to write code nor does it cost that much. There are millions of us working silently at places that aren't "big tech". We all shrugged our shoulders, took a sip of coffee, and went back to our Teams meetings where the only LLM usage is still just Copilot.


I don't need to be able to write proofs about my maths using logic and determinism. If the answer comes out in a way that I like then it has to be correct!


This is vapid condescension.

The comment you replied to made no statements about math or proofs. They made a statement about working in systems of non determinism effectively. Your statement seems to imply that this is dumb, as if working in a world of full determinism is an option.


Thank you for "vapid condescension".

I've wanted a term for this for decades!


when you do have the option of determinism, but intentionally eschew it in favour of a strictly inferior nondeterministic tool, then yes, it is kinda dumb.


What deterministic option are you referring to here? Humans certainly are not deterministic in how they interpret instructions and write code. If I asked you to implement a feature and a month later asked you to implement the exact same feature, you likely wouldn’t do it the same way again. Two different people certainly wouldn’t.


When you cling to determinism and call a clearly useful and powerful tool “strictly inferior” I would say this misses the point.


strictly inferior != bad. It's relative. One tool will still give the output i intended long after I'm dead and decomposed, with the other might not at the very next time i run it.


This is sorta how I've felt working the past ~7 years.

Simple example, we've been striving for 90% unit test coverage and thorough code review when there's 0% integration test coverage. I blame the metrics only looking at unit tests, but also many people think unit tests should come first. I would prioritize integration. There are some small pieces that need to work reliably, but if your system relies so hard on all of them working right, it's a bad system. That, and too many things will work in pieces but not overall.

Broadly I'm gonna assume that the team will later hire solid SWEs who don't necessarily know how our stuff works, and aren't going to read 100 docs about it. If this is a backend+DB combo, get your DB right and there won't be too many wrong ways to code against it in the future, get it wrong and it becomes a black hole for SWE-time. Or if someone on their first day can't run a system locally for debugging, no matter how elegant the code is, don't count on that system getting fixed quickly during an outage.


Insightful.

Feels like this maps to the J/P of Myers Briggs


I mean if your talking about packets, your already one abstraction over the real data Transmission, in wich is noisy. So bits can randomly flip, noise could be interpreted as bits, and bits could get lost. A much larger blast radius


> Mythos is “far ahead of any other AI model in cyber capabilities.”

Yet not far ahead enough to prevent the data leak.


Both those questions are answered clearly in the readme:

> compared to avante > I think it's fairly similar. However, magenta.nvim is written in typescript and uses the sdks to implement streaming, which I think makes it more stable. I think the main advantage is the architecture is very clean so it should be easy to extend the functionality. Between typescript, sdks and the architecture, I think my velocity is pretty high. I haven't used avante in a while so I'm not sure how close I got feature-wise, but it should be fairly close, and only after a couple of weeks of development time.

And:

> Another thing that's probably glaringly missing is model selection and customization of keymappings, etc...


thank you - missed that section at the bottom on my phone


Without knowing exactly how createNewGroup and addFileToGroup are implemented it is hard to tell, but it looks like the code snippet has a bug where the last group created is never pushed to groups variable.

I'm surprised this "senior developer AI reviewer" did not caught this bug...


With huge blobs of binary model weights, dynamic linking is cool again.


Dynamic linking has always been cool for writing plugins.

It is kind of ironic that languages that praise so much for going back to early linking models, have to resort for much heavier OS IPC for similar capabilities.


Which languages?

IIUC Go and Rust resort to OS IPC based plugin system mainly because they refused to have a stable ABI.

On the other hand, at $DAYJOB we have a query engine written in C++ (which itself uses mostly static linking [1]) loading mostly static linked UDFs and ... it works.

[1] Without glibc, but with libstdc++ / libgcc etc.


Doesn’t rust’s static linking also have to do with the strategy of aggressive minimization? Iirc for instance every concrete instantiation of a dynamic type will have its own compiled binary, so it would basically be impossible for a dynamic library to do this since it wouldn’t know how it would be used, at least not without some major limitations or performance tradeoffs


Well if it loads code dynamically, it is no longer static linking.

Also it isn't as if there is a stable ABI for C and C++ either, unless everything is compiled with the same compiler, or using Windows like dynamic libraries, or something like COM to work around the ABI limitations.


Which Apple has put some pretty large effort in the last few years to improve in iOS


Hosting some services on a vps provides far better availability of data, than doing it at home. Especially when you need it the most. For example when you are moving to a new home, and need to save documents, or you are abroad, need a document and there is a power outage at home.

Even if you have to trust a 3rd party with your data, (1) you can minimize the privacy risk with encryption and (2) usually VPS/cloud providers have different privacy guaranties than free Google drive...


Or, businesses could do like they do in Europe: set the same price after taxes in every state.


It is interesting because SMART being "niche jargon term" is very dependent of the audience. Nowhere the author needs to assume that the post will be posted on HN where the audience is probably larger than the originally intended one.

In many places NixOS is a niche jargon term.

Also, in the first paragraph of the article there is a direct link to smartd that has a clear explanation for what smart is, no need to Google.


It is called the Brussels Effect[0]

Put simply, given how large the EU market is, and how strong its regulation is, it is cheaper for companies to comply, even outside of the market.

[0]: https://en.wikipedia.org/wiki/Brussels_effect


This explains why they comply to the EU regulations even in the USA, but not why they don't try to lobby more in the EU to avoid those regulations in the first place.


One reason is that there are more hands in the cookie jar in the EU. Less so in the US.


Given your last sentence incidental complexity can be created and destroyed (and is more difficult to destroy than create).

The quote would probably be more accurate as:

> "ESSENTIAL Complexity can neither be created nor destroyed, only moved somewhere else."


Essential complexity can also be created and destroyed, though sometimes it happens earlier in the design process. Picking the problem you choose to solve is how you control essential complexity.


Essential complexity is inherent to the problem you have. The solutiom is layered between product design, technical design and implementation. What is essential complexity for a layer can be accidental for the layer above.


That just makes it a tautology. It basically says “essential complexity exists”.


It's often a matter of framing. When you abstract, refactor or move complexity it should serve to make the rest of the system/application easier to understand or for those adding features into the application(s) to be more productive as a whole. If it doesn't do one of those things, you probably shouldn't do it.

It's one thing to shift complexity to a different group/team, such as managing microservice infrastructure and orchestration that can specialize in that aspect of many applications/systems. It's very different to create those abstractions and separations when the same people will be doing the work on both sides, as this adds cognitive overhead to the existing team(s). Especially if you aren't in a scenario where your application performance overhead is in eminent danger of suffering as a whole.


It's a frame of mind.

Often a developer will see something big or complex and see it as a problem.

But they should consider whether this matches the size/scope of the problem being solved


> But they should consider whether this matches the size/scope of the problem being solved

In professional software development projects, specially legacy projects, often times the complexity is not justified by the problem. There is always technical debt piling up, and eventually it starts getting in the way.


> often times the complexity is not justified by the problem.

Often times means not always -- what would you say some projects are doing right so that their complexity is justified by the problem?


Maybe but it still useful to know that essential complexity exists and to identify it in your project.


Yes :)

That is the more precise adaptation of Kelsers Law.

Obviously you can always add also superfluous complexity :)


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: