惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
The GitHub Blog
The GitHub Blog
T
Threatpost
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
博客园 - Franky
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Apple Machine Learning Research
Apple Machine Learning Research
酷 壳 – CoolShell
酷 壳 – CoolShell
M
MIT News - Artificial intelligence
小众软件
小众软件
Hugging Face - Blog
Hugging Face - Blog
云风的 BLOG
云风的 BLOG
S
Security Affairs
P
Proofpoint News Feed
L
LINUX DO - 最新话题
宝玉的分享
宝玉的分享
S
Security @ Cisco Blogs
H
Hacker News: Front Page
Security Archives - TechRepublic
Security Archives - TechRepublic
Vercel News
Vercel News
Engineering at Meta
Engineering at Meta
Know Your Adversary
Know Your Adversary
Y
Y Combinator Blog
美团技术团队
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
月光博客
月光博客
量子位
博客园_首页
The Last Watchdog
The Last Watchdog
D
DataBreaches.Net
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Privacy International News Feed
The Register - Security
The Register - Security
Schneier on Security
Schneier on Security
H
Help Net Security
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
V
Visual Studio Blog
Google DeepMind News
Google DeepMind News
F
Full Disclosure
C
Cyber Attacks, Cyber Crime and Cyber Security
MyScale Blog
MyScale Blog
aimingoo的专栏
aimingoo的专栏
S
Schneier on Security
L
Lohrmann on Cybersecurity
S
Secure Thoughts
Stack Overflow Blog
Stack Overflow Blog
Cloudbric
Cloudbric
Microsoft Security Blog
Microsoft Security Blog

Pierce Freeman

A browser for agents | Pierce Freeman The grey market of podcast appearances The way I travel | Pierce Freeman Fixing slow AWS uploads | Pierce Freeman Local tools should still use vaults We solved scratch content first Starting a podcast in 2025 Being late but still being early Automating our home video imports Adding my parents to tailscale A deep dive on agent sandboxes My simple home podcast studio We need centralized infrastructure | Pierce Freeman Coercing agents to follow conventions using AST validation My unified theory of social selling My personal backup strategy | Pierce Freeman July updates to the homelab How the KV Cache works httpx is the right way to do web requests in Python Reputation is becoming everything | Pierce Freeman Building a (kind of) invisible mac app Updated knowledge in language models Making an ascii animation | Pierce Freeman How speculative decoding works | Pierce Freeman Under the hood of Claude Code Doing things because they're easy, not hard Speeding up sideeffects with JIT in mountaineer Firehot for hot reloading in Python Misadventures in Python hot reloading How text diffusion works | Pierce Freeman The tenacity of modern LLMs The ergonomics of rails | Pierce Freeman How language servers work | Pierce Freeman Just add eggs | Pierce Freeman Unfortunately SEO still matters | Pierce Freeman The futility of human-only web requirements Setting up Input Leap | Pierce Freeman Checking in on Waymo | Pierce Freeman The react revolution | Pierce Freeman Speeding up many small transfers to a unifi nas Quick notes on swift libraries AI engineering is a different animal San Francisco | Pierce Freeman Debugging a mountaineer rendering segfault Local network config on macOS Building our home network | Pierce Freeman Introducing Envelope.dev | Pierce Freeman Legacy code and AI copilots Typehinting from day-zero | Pierce Freeman Generating database migrations with acyclic graphs Lofoten | Pierce Freeman Mountaineer v0.1: Webapps in Python and React Constraining LLM Outputs | Pierce Freeman Passthrough above all | Pierce Freeman Accuracy in kudos | Pierce Freeman How quick we are to adapt The curious case of LM repetition Costa Rica | Pierce Freeman Debugging chrome extensions with system-level logging Speeding up runpod | Pierce Freeman Inline footnotes with html templates Parsing Common Crawl in a day for $60 An era of rich CLI All or nothing with remote work The Next 10 Years | Pierce Freeman Adding wheels to flash-attention | Pierce Freeman LLMs as interdisciplinary agents | Pierce Freeman New Zealand | Pierce Freeman Representations in autoregressive models | Pierce Freeman Let's talk about Siri | Pierce Freeman Minimum viable public infrastructure | Pierce Freeman Reasoning vs. Memorization in LLMs Automatically migrate enums in alembic Greater sequence lengths will set us free On learning to ski | Pierce Freeman Dolomites | Pierce Freeman Using grpc with node and typescript Opportunity years | Pierce Freeman Buzzword peaks and valleys | Pierce Freeman Buenos Aires | Pierce Freeman Network routing interaction on MacOS Independent work: November recap | Pierce Freeman Debugging slow pytorch training performance The provenance of copy and paste Debugging tips for neural network training Patagonia | Pierce Freeman Santiago | Pierce Freeman My 2022 digital travel kit AWS vs GCP - GPU Availability V2 Independent work: October recap | Pierce Freeman Planning Patagonia | Pierce Freeman Relationship modeling | Pierce Freeman The power of status updates A new chapter | Pierce Freeman Give my library a coffee shop AWS vs GCP - GPU Availability V1 Switzerland | Pierce Freeman Headfull browsers beat headless | Pierce Freeman Webcrawling tradeoffs | Pierce Freeman Copenhagen | Pierce Freeman
Language servers for AI | Pierce Freeman
2025-09-25 · via Pierce Freeman

Human beings are still undoubtedly the main consumers of language servers.1 They're integrated into pretty much every IDE on the planet and provide the syntax highlighting that makes thousands of LOC a whole lot more readable.

But if I had to put money on it, I'd bet their accelerating capabilities will be motivated more by automatic calling from LLMs versus manual calling by us.

Static analysis

For the sake of simplicity here, I'm defining language servers as broadly as possible. This includes the basic semantic parsing and also logical mapping of functionality. A non-exhaustive list of things that language servers can validate:

  • Is this grammar compatible with the language syntax
  • Is this function actually defined in this scope
  • Does this attribute access actually exist in the underlying instance object

Language extensions like TypeScript or type annotations in Python help provide more context to our language servers, when checking for type validity or access patterns. Compiled languages typically enforce more strict typing anyway so the overlap of compilation toolchains and static analysis is a bit more obvious.

Zero-shotting in a complex project

LLMs are very strong in generating code that's grammatically valid; ie. can compile or execute without any syntax errors. They struggle more when it comes to long term external dependencies: some class has function A or parameter B & you need to call that same function over in file C. Let's make this a bit more concrete:

from store_enums import ApartmentType

class Apartment:
    type: ApartmentType
    floor: int
    sq_ft: int
def collect_rent():
    # to implement by an LLM, depending on size of the apartment
    ...

If you were to write this, you probably already have an approach in mind after reading that simple stub. Consider the type of apartments that we have to support, price the square foot accordingly, and multiply it by the square feet of the actual apartment.

If we're trying to automate that logical flow, our goal would be for the LLM to understand what we need to do and:

  • Search for the store object
  • Identify there are different types of apartments
  • Read the values of ApartmentType so we can switch on them in the implementation
  • Access the ApartmentType by relative import

This should be readily solvable by modern agents at a small scale. But the more classes you have, the more you're going to fill your context. And the more code you ask the model to write that depends on the outputs of other code, the opportunity for even small access errors to snowball into code that doesn't even run.

Some of that limitation can be blamed on the search/RAG systems we use to surface code. Whenever you have a feature to implement, the LLM has to re-familiarize itself with the content of your codebase. They either search a string literal and grep through your codebase, or they provide some semantic description of what they're looking for. It's the ultimate guess-and-check of trying to find the needle in the haystack.2 Sometimes it fully misses the context, in which case you have no hope that the predicted code is going to correctly reference some out of scope object properties.

People have long hoped that increasing the context length will solve this problem. The idea here is to put all your code in the context and let the model figure out what to do next. We've already seen a meaningful improvement in the context length that modern models can support: most of the frontier labs host options that can parse 1M-2M tokens. However, thus far we do typically see diminishing performance when we stuff the context length with irrelevant information to the task at hand.3

Agent correction loops

I find that agents work best when you're able to give them some deterministic validators. This pretty closely follows the RL paradigm that they were trained on in the first place; they loop over multiple tool calls, then periodically call some test function to act as the evaluator / reward function. We have already optimized the weights to support this workflow. It seems reasonable to mirror that pattern more closely at inference time as well.

What makes a good validator? Something that's (A) deterministic, so the model can optimize against the same benchmark criteria. And (B) fast, so you spend the majority of your time generating tokens. Token generation will almost always be your primary latency bottleneck. There's not much there we have control over other than using a smaller model or getting an ASIC chip online. So might as well make the rest of the out-of-band tool calls as fast as possible.

Unit tests that you've written are the golden baseline for agent correction loops. If you know exactly the criteria you want to test against, and you add enough guard rails as part of the LLM generation4, it can usually work long enough to find something that passes tests. But it's usually pretty painful to write tests before you actually have logic stubbed out, no matter what TDD advocates say. It also takes a lot of unit tests to fully cover all code paths and edge cases. It's certainly easier to let an agent do a lot of this heavy lifting for you.

But then we're left with a conundrum: can you tell an agent to write good one-shot tests even if you don't have faith they can write good one-shot code? They feel like a similar level of complexity to me.

Static analysis is by definition a more general solution. You can run it on your codebase before you have a single line written. It provides a baseline that your code is internally consistent. It might not do what you intend it to do but it's almost guaranteed to avoid raising exceptions at runtime. It's also so fast you can run it on every file modification without having to make a decision on whether this is the right time to spend X minutes waiting for unit tests.

I kick off almost all my agent tasks with the forced requirements that before they yield back to me, they run static analysis & our existing unit tests. In the worse case, this is still useful even when the logic wasn't correct since it provides you a reasonable code quality baseline to pick up again. In the best case, I've seen a few situations where the language server flags some errors with external function calls and guides the LLM to pull that file back into its context cache. This then let it fix other parts of the code to be compatible with the actual definition.

Code conventions in language servers

eslint used to have a ton of different flavors for the linting syntax that people use. At this point I feel like most people have given up on the style wars, so long as everyone within a project is just using the same standard. I wouldn't be surprised if we see a resurgence of some of this opinionated design when it comes to broader codebase conventions.

LLMs are exposed to all of the code that's online with all manner of competing conventions. Error handling (proactive vs. reactive), web requests (sync vs. async), design patterns (factory vs. dependency injection), etc. We expect our model to intuit the design patterns we use in an existing project, or choose some reasonable ones when it gets started on a new project. That's putting a lot of pressure on the model.

But if we can enforce these conventions deterministically, instead of just hoping to the probabilistic gods, why wouldn't we? You can create a language server that verifies:

  • all web requests happen with async
  • errors are always thrown and caught in a main handler instead of being handled in the function itself
  • functions can only instantiate some classes via dependency injection instead of a direct allocation

Not all coding conventions can be expressed with AST validators. Perhaps not even most. But I could see this pretty easily becoming an extension of language servers especially for the most egregious of style violations.

We'll see how this side of the ecosystem develops. It would certainly be a departure from the scope of conventional language servers. But you could have said the same thing for expanding language server capabilities to validate function arguments over basic code highlighting. In the meantime, I have a proof of concept that shows some of the power of using agents to write these style guide parsers. Maybe that will soon even come to a language server near you.

  1. This being in any dispute in 2025 was not on my 2020 bingo card. ↩

  2. I suspect this is part of the reason why beginners are so impressed by LLMs and "pros" are not; the pros have much more complicated codebases that they need to work around. The beginners can one shot something that works very quickly while LLMs still have everything in context. ↩

  3. I'm optimistic that with enough training and RL execution for long horizon tasks we'll be able to overcome some of this bias. But the question of information density is a tricky fundamental challenge to overcome; humans certainly aren't able to keep that same amount of context in our heads concurrently either, so we can't look to us capabilities as a useful baseline. ↩

  4. You want to avoid the model "cheating", like silencing errors in try/catch loops or reading the test function so you just return the expected I/O outputs. I still see this happen occasionally on SOTA models. ↩