<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: yummy342</title>
    <description>The latest articles on DEV Community by yummy342 (@yummy342).</description>
    <link>https://dev.to/yummy342</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4058118%2F1d5d6dfb-1f7b-4d7e-80e8-a9bee536daf2.png</url>
      <title>DEV Community: yummy342</title>
      <link>https://dev.to/yummy342</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yummy342"/>
    <language>en</language>
    <item>
      <title>I read the public model list of fourteen gateways. Five of them publish one.</title>
      <dc:creator>yummy342</dc:creator>
      <pubDate>Wed, 30 Sep 2026 13:36:39 +0000</pubDate>
      <link>https://dev.to/yummy342/i-read-the-public-model-list-of-fourteen-gateways-five-of-them-publish-one-3464</link>
      <guid>https://dev.to/yummy342/i-read-the-public-model-list-of-fourteen-gateways-five-of-them-publish-one-3464</guid>
      <description>&lt;h1&gt;
  
  
  I read the public model list of fourteen gateways. Five of them publish one.
&lt;/h1&gt;

&lt;p&gt;Ask a gateway what it serves and you get one of two answers: a list, or a login form. I wanted to know which is more common, so I called the documented endpoint of fourteen gateways — no account, no key, one GET each.&lt;/p&gt;

&lt;p&gt;Five answered with a model list. Eight answered &lt;code&gt;401&lt;/code&gt; and meant it: the catalogue is behind an account. One answered only after authentication. Two I could not reach from where I ran this at all.&lt;/p&gt;

&lt;p&gt;None of that is a scandal. But it changes what a migration costs, and it is the thing I would check before picking a gateway rather than after.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I ran
&lt;/h2&gt;

&lt;p&gt;For each gateway, the documented OpenAI-compatible base URL, with an empty body and no credentials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code} '&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://&amp;lt;gateway&amp;gt;/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{}'&lt;/span&gt;
curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}\n'&lt;/span&gt; https://&amp;lt;gateway&amp;gt;/v1/models
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;401&lt;/code&gt; or &lt;code&gt;400&lt;/code&gt; on the first call means the route exists and is waiting for a key. &lt;code&gt;404&lt;/code&gt; means no key will ever help — the documented base URL is wrong. On the second call, &lt;code&gt;200&lt;/code&gt; means you can read the catalogue before you sign up.&lt;/p&gt;

&lt;p&gt;Run on 30 September 2026. Status codes as returned that day.&lt;/p&gt;

&lt;h2&gt;
  
  
  What came back
&lt;/h2&gt;

&lt;p&gt;Every reachable gateway's chat route answered with an authentication error rather than a &lt;code&gt;404&lt;/code&gt;. That is the good news, and it is worth stating plainly: I did not find a single documented base URL that was simply wrong. The failures people hit in this category are elsewhere.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OpenRouter            chat 401   models 200   464 entries
Requesty              chat 401   models 200   749
Vercel AI Gateway     chat 400   models 200   395
LLM7.io               chat 400   models 200    65
FreeModel             chat 401   models 200   199
Groq / Together / DeepSeek / SiliconFlow / Helicone / Portkey / Z.ai
                      chat 401   models 401
Mistral, Gemini (OpenAI compat)   unreachable from this network
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why the list matters more than it looks
&lt;/h2&gt;

&lt;p&gt;A public catalogue is not a marketing page. It is the only way to answer three questions without paying:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What did you serve last month, and what do you serve now?&lt;/strong&gt; You can diff two reads. If the list needs a key, you can only see the current state, and only after signing up.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What shape is it in?&lt;/strong&gt; Field sets differ more than I expected — six fields on one gateway, thirty-four on another, eighteen on the model labs. Anything your tooling derives from those fields is a bet on one vendor's schema.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What do the identifiers encode?&lt;/strong&gt; This is the one that decides your exit cost, and I will come back to it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Of the five that answered, the field sets share almost nothing beyond &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;object&lt;/code&gt; and &lt;code&gt;created&lt;/code&gt;. One publishes per-model pricing and retention notes; another publishes a knowledge cutoff and a Hugging Face id; another publishes availability percentages from the last hour. None of them publishes a read date next to the count, including mine — which is why the numbers above are stamped with the day I read them and nothing else.&lt;/p&gt;

&lt;h2&gt;
  
  
  The identifier question
&lt;/h2&gt;

&lt;p&gt;Look at the ids rather than the counts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OpenRouter    openai/gpt-6.1-sol-pro
Requesty      bedrock/claude-sonnet-4@eu-north-1
Vercel        alibaba/qwen-3-14b
LLM7.io       DeepSeek-V4-Flash-0731
FreeModel     fm/qwen3-coder-plus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two of these are answers to "which model is this". Two are answers to "which model, served from where". The difference matters the day the second half changes.&lt;/p&gt;

&lt;p&gt;A prefix that names the model's family is stable — &lt;code&gt;openai/gpt-6.1&lt;/code&gt; will mean the same thing next year. A prefix that names the route the request takes is a fact about the vendor's business, and it changes when their business does. On the gateway I work on, the ids used to name the upstream relay each model came through; when that layer was reorganised, the identifiers moved with it and one family of aliases stopped resolving. Nothing errored. The ids simply meant something different.&lt;/p&gt;

&lt;p&gt;So the check is one line of code against any list you can read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;the list you fetched&amp;gt;'&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s1"&gt;'"id":"[^"]*"'&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the first segment is a model family, your client is pinned to a model. If it is an intermediary, your client is pinned to a supplier — and you will find out which on the day it changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this leaves the choice
&lt;/h2&gt;

&lt;p&gt;I run FreeModel, one of the five that publishes the list, so weigh the rest of this accordingly. The honest summary of my own row: 199 entries, six fields, no pricing, no retention notes, and identifiers that are deliberately neutral. We started publishing the list because the count on our own pricing page kept disagreeing with the endpoint, and the only way to stop that was to make the endpoint the source and date every number taken from it.&lt;/p&gt;

&lt;p&gt;The thing I would take from this table if I were choosing a gateway: prefer one whose catalogue you can read before you have an account, and whose identifiers survive a reorganisation. Both are checkable in a minute, and neither is on any comparison page I have read — including the ones that list us.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>devtools</category>
      <category>opensource</category>
    </item>
    <item>
      <title>OpenRouter was acquired by Stripe. The migration checklist that actually matters.</title>
      <dc:creator>yummy342</dc:creator>
      <pubDate>Wed, 30 Sep 2026 06:37:00 +0000</pubDate>
      <link>https://dev.to/yummy342/openrouter-was-acquired-by-stripe-the-migration-checklist-that-actually-matters-52en</link>
      <guid>https://dev.to/yummy342/openrouter-was-acquired-by-stripe-the-migration-checklist-that-actually-matters-52en</guid>
      <description>&lt;h1&gt;
  
  
  OpenRouter was acquired by Stripe. The migration checklist that actually matters.
&lt;/h1&gt;

&lt;p&gt;Stripe agreed to acquire OpenRouter on 19 August 2026. The price was not disclosed; the press reported figures between $7 billion and $8 billion, mostly in stock. OpenRouter raised $113 million three months earlier at a reported $1.3 billion valuation.&lt;/p&gt;

&lt;p&gt;Helicone, a different company in the same layer, also changed hands this year and is now described as being in maintenance mode.&lt;/p&gt;

&lt;p&gt;Neither event changes your HTTP requests today. Both change what happens the next time you need something from the vendor. This post is the checklist I would run against any gateway before I let it into a codebase with a key in it. Every item here is one command, none of them need an account, and you can run them against mine at the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  The risk is not the acquisition
&lt;/h2&gt;

&lt;p&gt;A gateway is two things at once: a company, and a shape. The company can be bought. The shape is what your code depends on, and it is the part that is expensive to get out of.&lt;/p&gt;

&lt;p&gt;The shape is three decisions the vendor made before you arrived:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which base URL your client points at&lt;/li&gt;
&lt;li&gt;what the model identifiers are called&lt;/li&gt;
&lt;li&gt;what the response fields mean&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An acquisition does not change any of those. But it also does not protect them: the fastest way to make an acquired product cheaper to run is to change what it serves. Your client does not find out until it does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five checks, five requests
&lt;/h2&gt;

&lt;p&gt;Run these against whatever gateway you are on now. I picked the checks because each one fails &lt;em&gt;silently&lt;/em&gt; in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Does the documented base URL actually resolve?&lt;/strong&gt; OpenAI-compatible clients append their own path (&lt;code&gt;/chat/completions&lt;/code&gt;), Anthropic clients append &lt;code&gt;/v1/messages&lt;/code&gt;. So the base URL is only half a path, and a wrong one is a 404 that no API key can fix.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}\n'&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://&amp;lt;gateway&amp;gt;/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"model":"x","messages":[]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;401&lt;/code&gt; means the route exists and you are missing a key. &lt;code&gt;404&lt;/code&gt; means it does not exist. That difference is the entire test.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Is the model list readable without a key, and does it carry a date?&lt;/strong&gt; If the catalogue needs a key, you cannot diff it against your own config without spending money. If a page quotes a count without saying when it was read, that number is already wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. What are the model identifiers called?&lt;/strong&gt; This is the one that decides your exit cost. If the ids encode the vendor's supply chain (&lt;code&gt;somevendor/some-relay/model-name&lt;/code&gt;), then every id in your code is a fact about their business, not about the model. When that supply chain changes, your strings change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Does the free tier require a card?&lt;/strong&gt; Test it with a fresh account, not by reading the pricing page.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Does an over-tier request refuse, or bill quietly?&lt;/strong&gt; Ask for something you are not entitled to. You want a &lt;code&gt;402&lt;/code&gt;, not a charge.&lt;/p&gt;

&lt;p&gt;The fifth check has a second half that matters more than the first: ask what happens when a provider inside the gateway fails. An error returned to your client is honest. A silent fallback that swaps the model under you is not, and you will only notice it in the eval scores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the id check is the expensive one
&lt;/h2&gt;

&lt;p&gt;I run a gateway, so I will use my own outage as the example. On 22 September our public model list returned 477 entries. On 29 September the same endpoint, unauthenticated, returned 199. Same URL, same response shape, different catalogue — because the implementation behind that URL had been swapped.&lt;/p&gt;

&lt;p&gt;A count is the visible part. The damage was in the identifiers: the ids on the new endpoint carried the name of the upstream relay that served each model, which meant the old IDs resolved differently and one family of aliases stopped resolving at all. Any client that had cached the list, or hard-coded a model string, broke without an error message to explain it.&lt;/p&gt;

&lt;p&gt;That is what an exit cost looks like before you are trying to exit. If the ids are neutral, moving is a base URL change. If they are not, moving is a migration.&lt;/p&gt;

&lt;h2&gt;
  
  
  The test is portable. Run it on me.
&lt;/h2&gt;

&lt;p&gt;Since I have a horse in this race, here is how the gateway I work on answers the five checks, and where it comes off badly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1  base URL        401 on the chat route
2  model list      public, no key; 199 entries as of 30 September 2026
3  identifiers     neutral, fm/&amp;lt;model&amp;gt;; the old relay-prefixed names still resolve
4  free tier       no card; one tier is free to any account
5  over-tier       402, and the message names the tier
6  fallback        a direct model name is never substituted; the tier aliases are a
                   documented pool and will serve a different model from inside the tier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last line is where we are deliberately weaker than the check implies. If you call a specific model by name, you get that model or an error. If you call a tier alias, you are asking for "any model in this band", and that is a substitution by design — it is documented, and it is the reason the free tier can survive a provider going down.&lt;/p&gt;

&lt;p&gt;The honest column: there is no uptime guarantee and no third-party security certification. If your procurement process needs those, the absence is the answer, and a call will not change it. All six checks above are things you can verify in about ten minutes, which is the only reason I am comfortable printing them.&lt;/p&gt;

&lt;p&gt;Run the six against every gateway on your shortlist, including this one. The results will tell you something the comparison posts cannot: which of them you could leave.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>devtools</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Your gateway's public model list is a contract. Most of them break it quietly.</title>
      <dc:creator>yummy342</dc:creator>
      <pubDate>Tue, 29 Sep 2026 08:09:31 +0000</pubDate>
      <link>https://dev.to/yummy342/your-gateways-public-model-list-is-a-contract-most-of-them-break-it-quietly-29kc</link>
      <guid>https://dev.to/yummy342/your-gateways-public-model-list-is-a-contract-most-of-them-break-it-quietly-29kc</guid>
      <description>&lt;h1&gt;
  
  
  Your gateway's public model list is a contract. Most of them break it quietly.
&lt;/h1&gt;

&lt;p&gt;Every LLM gateway publishes an endpoint that lists what you can call. Clients read it,&lt;br&gt;
pricing pages quote it, comparison articles count it, and nobody treats it as an interface&lt;br&gt;
that can change. That is the mistake. I spent a day calling four of them and comparing what&lt;br&gt;
came back against what the vendors' own documentation says.&lt;/p&gt;
&lt;h2&gt;
  
  
  What I checked
&lt;/h2&gt;

&lt;p&gt;On 29 September 2026 I called the public model list of each gateway, twice, twenty minutes&lt;br&gt;
apart, with no API key, and compared the response against whatever the vendor documents&lt;br&gt;
about it. Nothing here needed an account, which is the point — a list that requires a key&lt;br&gt;
to read is not a public list.&lt;/p&gt;

&lt;p&gt;Five things, in the order they tend to bite:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does the base URL the vendor documents actually answer?&lt;/li&gt;
&lt;li&gt;Does the field set in the response match what the documentation promises?&lt;/li&gt;
&lt;li&gt;Does the count match what the vendor's own copy says?&lt;/li&gt;
&lt;li&gt;Does the list agree with itself between two calls?&lt;/li&gt;
&lt;li&gt;Can you tell, from the response alone, which entries are safe to hard-code?&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  1. The documented base URL is the most likely thing to be wrong
&lt;/h2&gt;

&lt;p&gt;This is the cheapest check and the one that fails most often, because it costs nothing to&lt;br&gt;
verify and almost nobody does.&lt;/p&gt;

&lt;p&gt;An OpenAI-compatible client appends its own path. The Python SDK takes&lt;br&gt;
&lt;code&gt;base_url="https://example.com/v1"&lt;/code&gt; and then calls &lt;code&gt;/chat/completions&lt;/code&gt; on top of&lt;br&gt;
it; the &lt;code&gt;OPENAI_BASE_URL&lt;/code&gt; environment variable behaves the same way, which the&lt;br&gt;
&lt;a href="https://github.com/openai/openai-python" rel="noopener noreferrer"&gt;openai-python README&lt;/a&gt; documents. An Anthropic&lt;br&gt;
client appends &lt;code&gt;/v1/messages&lt;/code&gt; to whatever base you hand it, as the&lt;br&gt;
&lt;a href="https://docs.anthropic.com/en/api/messages" rel="noopener noreferrer"&gt;Messages API reference&lt;/a&gt; shows.&lt;/p&gt;

&lt;p&gt;So the base URL is half of a path, and if the vendor writes the wrong half the client gets&lt;br&gt;
a 404 that reads like an auth problem. On my own site I had this backwards in one place and&lt;br&gt;
right in another: the OpenAI base was correct on the SDK page and wrong in the file written&lt;br&gt;
specifically for agents to read, because both were generated from a single JSON registry and&lt;br&gt;
the stale value sat in that registry. One wrong entry, two surfaces, one of them broken.&lt;/p&gt;

&lt;p&gt;The test takes one request, and the status code is the whole answer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s1"&gt;'%{http_code}
'&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://example.com/v1/chat/completions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A &lt;code&gt;401&lt;/code&gt; means the route exists and wants a key. A &lt;code&gt;404&lt;/code&gt; means the route does not exist, and&lt;br&gt;
no key will help. That distinction is the entire test. Run it against the Anthropic base too&lt;br&gt;
(&lt;code&gt;POST &amp;lt;base&amp;gt;/v1/messages&lt;/code&gt;), because the two dialects are usually mounted at different&lt;br&gt;
prefixes and only one of them is documented carefully.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The count in the copy will not match the count in the endpoint
&lt;/h2&gt;

&lt;p&gt;Model counts move. Mine moved a lot: the same public endpoint returned 477 models on 22&lt;br&gt;
September and 199 models on 29 September. OpenRouter's public list returned 460 models when I&lt;br&gt;
called it on 29 September, against 445 models in a snapshot taken ten days earlier. Neither number&lt;br&gt;
is a lie. Both are dated observations that somebody froze into a sentence and walked away&lt;br&gt;
from.&lt;/p&gt;

&lt;p&gt;The consequence is narrower than it sounds and more annoying: a page that says it serves 477&lt;br&gt;
models gets checked by a reader who sees a different number, and the reader concludes the&lt;br&gt;
page is inventing things. The fix is not to update the number more often. It is to stop&lt;br&gt;
putting a moving number in a sentence with no date on it. Any figure that comes from an&lt;br&gt;
endpoint should carry the date it was read and the exact endpoint it came from, so a reader&lt;br&gt;
can reproduce or refute it in one request.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. The field set is the part that actually breaks clients
&lt;/h2&gt;

&lt;p&gt;This is the one that costs real time and that no checklist covers.&lt;/p&gt;

&lt;p&gt;A model list is not a fixed schema. In the case I hit, a response carrying &lt;code&gt;id&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;context_length&lt;/code&gt;, &lt;code&gt;max_output_tokens&lt;/code&gt;, &lt;code&gt;capabilities&lt;/code&gt; and &lt;code&gt;owned_by&lt;/code&gt; came back a week later&lt;br&gt;
with &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;object&lt;/code&gt;, &lt;code&gt;created&lt;/code&gt;, &lt;code&gt;owned_by&lt;/code&gt;, &lt;code&gt;tier&lt;/code&gt; and &lt;code&gt;modality&lt;/code&gt;, and no&lt;br&gt;
&lt;code&gt;capabilities&lt;/code&gt; at all. Every derived number built on those fields silently became&lt;br&gt;
uncomputable. Shares of models supporting tool calling, shares accepting image input, counts&lt;br&gt;
of combination routes: all computed from a field that had stopped being returned. The pages&lt;br&gt;
kept rendering, the percentages kept being quoted, and nothing failed, because nothing&lt;br&gt;
checked.&lt;/p&gt;

&lt;p&gt;If you build against one of these lists, the fields you read are the contract:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read the field, never assume it. &lt;code&gt;capabilities?.tool_calling&lt;/code&gt; survives a missing key.
&lt;code&gt;capabilities.tool_calling&lt;/code&gt; is a crash waiting for a release.&lt;/li&gt;
&lt;li&gt;Do not derive a published statistic from a field you do not control. If a share comes from
a live endpoint, either recompute it at render time or archive the snapshot you computed
it from.&lt;/li&gt;
&lt;li&gt;Snapshot the response into your own repository and serve the number with the snapshot
date. A build that depends on a third party's schema staying still is already broken;
it just has not failed yet.&lt;/li&gt;
&lt;li&gt;Treat any field whose values name upstream suppliers as something you should think twice
about republishing. Some lists return one. Hand that endpoint to the public and you are
publishing your supply chain, and you probably never decided to.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Free-tier numbers are documented in prose and injected by JavaScript
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://openrouter.ai/docs/faq" rel="noopener noreferrer"&gt;OpenRouter's FAQ&lt;/a&gt; states plainly that it charges a fee when&lt;br&gt;
you purchase credits, and that free-model rate limits are determined by how much credit you&lt;br&gt;
have bought. The specific figures, the percentage and the minimum and the requests per day,&lt;br&gt;
are filled in at render time, so a plain HTTP fetch returns those sentences with the numbers&lt;br&gt;
missing. The prose is the contract. The numbers are configuration.&lt;/p&gt;

&lt;p&gt;That is not a criticism, it is a warning about how gateways get compared. If you are writing&lt;br&gt;
the comparison, link the sentence you can actually cite and state the figure as a dated&lt;br&gt;
observation. If you are picking a gateway, a number in a blog post from three months ago is&lt;br&gt;
not a specification, and it was probably read out of the same bundle you could have read&lt;br&gt;
yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. A list that does not say what is callable is not a list
&lt;/h2&gt;

&lt;p&gt;The most useful thing a gateway model list can tell you is which entries are safe to pin and&lt;br&gt;
which are aliases that move underneath you. Almost none of them say. A route named&lt;br&gt;
&lt;code&gt;auto/best-coding&lt;/code&gt; is a policy, not a model, and pinning it in production is a different&lt;br&gt;
decision from pinning a specific model id. If the response does not distinguish the two, you&lt;br&gt;
find out by shipping.&lt;/p&gt;

&lt;h2&gt;
  
  
  The checklist
&lt;/h2&gt;

&lt;p&gt;All of the above collapses into five requests you can run before pointing production at&lt;br&gt;
anything:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;POST &amp;lt;base&amp;gt;/chat/completions&lt;/code&gt; and &lt;code&gt;POST &amp;lt;base&amp;gt;/v1/messages&lt;/code&gt;. Expect 401, not 404.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET &amp;lt;base&amp;gt;/models&lt;/code&gt; twice, twenty minutes apart. If the count or the field set moves,
you have learned something the README will not tell you.&lt;/li&gt;
&lt;li&gt;Diff the fields in the response against the fields in the documentation. The
documentation is usually older.&lt;/li&gt;
&lt;li&gt;Look for fields that name a supplier, a tier, or a policy route, and decide explicitly
whether you are willing to depend on them.&lt;/li&gt;
&lt;li&gt;Write down the date you checked, in the place the next person will look.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of this needs a key, an account, or anyone's permission. It takes 10 minutes, and it&lt;br&gt;
is the difference between integrating with a gateway and betting on one.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I work on &lt;a href="https://freemodel.online/" rel="noopener noreferrer"&gt;FreeModel by Aiglade&lt;/a&gt;, an AI model gateway, and the&lt;br&gt;
477-to-199 case in section three is my own endpoint. It is why I ran these checks on&lt;br&gt;
everyone else rather than fixing my own and moving on. Every number here was read on 29&lt;br&gt;
September 2026 from endpoints that need no key, and the&lt;br&gt;
&lt;a href="https://freemodel.online/v1/models" rel="noopener noreferrer"&gt;model list I checked&lt;/a&gt; is one of them.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>api</category>
      <category>llm</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Three 1024-Dimension Embedding Models, Three Coordinate Systems</title>
      <dc:creator>yummy342</dc:creator>
      <pubDate>Sun, 27 Sep 2026 18:53:23 +0000</pubDate>
      <link>https://dev.to/yummy342/three-1024-dimension-embedding-models-three-coordinate-systems-313i</link>
      <guid>https://dev.to/yummy342/three-1024-dimension-embedding-models-three-coordinate-systems-313i</guid>
      <description>&lt;h1&gt;
  
  
  Three 1024-Dimension Embedding Models, Three Coordinate Systems
&lt;/h1&gt;

&lt;p&gt;If your gateway silently swaps the embedding model behind an alias, your retrieval does not get worse. It becomes random, with no error and no warning, and you find out weeks later when search results stop making sense.&lt;/p&gt;

&lt;p&gt;I run &lt;a href="https://freemodel.online/" rel="noopener noreferrer"&gt;FreeModel&lt;/a&gt;, so I get to audit this on my own infrastructure. Here is the measurement, the code to reproduce it, and the design decision that came out of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The measurement
&lt;/h2&gt;

&lt;p&gt;Three embedding models. All of them return 1024-dimensional float vectors. Same length, same type, same JSON shape. Feed all three the same sentence and compare the results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A vs B   0.003
A vs C   0.010
B vs C   0.006
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Effectively zero. They are not similar spaces with different quality. They are &lt;strong&gt;orthogonal&lt;/strong&gt; spaces that happen to have the same number of dimensions.&lt;/p&gt;

&lt;p&gt;That last part is the trap. Nothing about the responses looks wrong. The vectors are the right length. The API returns 200. The &lt;code&gt;model&lt;/code&gt; field says what you asked for. If you log the request and response and eyeball them, everything is fine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reproducing it
&lt;/h2&gt;

&lt;p&gt;You do not need my numbers. This runs against any three embedding endpoints you already have access to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;openai&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;OpenAI&lt;/span&gt;

&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpenAI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_BASE_URL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YOUR_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;SENTENCE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;the quick brown fox jumps over the lazy dog&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;MODELS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;model-a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;model-b&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;model-c&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;vecs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;MODELS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SENTENCE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;vecs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;linalg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;linalg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MODELS&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;MODELS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:]:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; vs &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vecs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;vecs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two checks worth adding while you are there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 1. Same dimensions?
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shape&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;vecs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()})&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Sanity check — same model, same sentence, twice
&lt;/span&gt;&lt;span class="n"&gt;r1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;MODELS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SENTENCE&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;
&lt;span class="n"&gt;r2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;MODELS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SENTENCE&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;embedding&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;self-similarity:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;cos&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r2&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;   &lt;span class="c1"&gt;# should be 1.000
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the self-similarity is 1.0 and the cross-model numbers are near zero, you have just confirmed that the models occupy unrelated spaces. The vectors are only comparable to vectors from the same model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this breaks retrieval instead of degrading it
&lt;/h2&gt;

&lt;p&gt;The usual failure mode people imagine is "the new model is worse, so results get a bit worse." That is not what happens.&lt;/p&gt;

&lt;p&gt;Embedding search works by comparing distances inside one space. Index your documents with model A, query with model B, and every distance you compute is between a vector from space A and a vector from space B. There is no meaningful ordering there. The nearest neighbour is essentially arbitrary — it is noise that happens to have the right shape.&lt;/p&gt;

&lt;p&gt;So the failure looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No exception. The call succeeds.&lt;/li&gt;
&lt;li&gt;No warning. Both models are healthy.&lt;/li&gt;
&lt;li&gt;No visible anomaly. Vectors are the correct length.&lt;/li&gt;
&lt;li&gt;Wrong results, forever, in a way that looks like a relevance-tuning problem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Weeks later you are adding reranking and tuning &lt;code&gt;top_k&lt;/code&gt; to fix "quality", and the actual cause is that your index and your queries are speaking different languages.&lt;/p&gt;

&lt;h2&gt;
  
  
  The design decision
&lt;/h2&gt;

&lt;p&gt;Most routing layers treat a failed model as a failed request and retry on the next candidate. For chat, that is fine — a different model still answers your question, and you can see that the wording changed.&lt;/p&gt;

&lt;p&gt;For embeddings, the safe number of candidates behind an alias is &lt;strong&gt;one&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So &lt;a href="https://freemodel.online/docs/free-embedding-api/" rel="noopener noreferrer"&gt;&lt;code&gt;auto/embed&lt;/code&gt;&lt;/a&gt; resolves to exactly one model and never rotates. If that model is unavailable, the request fails and says so. Failing loudly is the only useful behaviour when the alternative is quietly corrupting an index you spent months building.&lt;/p&gt;

&lt;p&gt;That has a consequence worth stating: &lt;strong&gt;changing the embedding model is a breaking change, not an upgrade.&lt;/strong&gt; So it ships as a new name. The old alias keeps working, you move when you can rebuild, and nobody wakes up to a repointed pointer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;auto/embed       → pinned, will not move
auto/embed-v2    → a new name when there is a new model worth moving to
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see the same rule in the response shape: a 404 or 410 from upstream advances to the next candidate, because a retired model failing is strictly worse than falling through. A timeout, a rate limit or a 5xx does not, because those are transient and swapping the model underneath them changes your data rather than fixing your request.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to check on your own stack
&lt;/h2&gt;

&lt;p&gt;Three things, in order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Run the cosine test above on every model pair you might mix.&lt;/strong&gt; If any pair is near zero, they are not interchangeable.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Record the model name with every vector you store.&lt;/strong&gt; This is the cheap version of the check — when the name in your index does not match the name serving your queries, you find out immediately instead of inferring it from bad results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reject aliases whose failure mode is "try another model"&lt;/strong&gt; for embedding and reranking specifically. Pool-based fallback is reasonable for chat and dangerous here.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The rule generalises past embeddings. Reranking has the same shape — swap the model and the same query returns a different order, silently. Text-to-speech has it too: swap the model mid-series and the voice changes. In every case the question is the same: if this silently becomes something else, do I find out?&lt;/p&gt;

&lt;p&gt;For embeddings, the answer is no. So the alias does not move.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>rag</category>
      <category>api</category>
      <category>database</category>
    </item>
    <item>
      <title>Free LLM gateways, tested: what the free tier actually gives you in September 2026</title>
      <dc:creator>yummy342</dc:creator>
      <pubDate>Mon, 21 Sep 2026 16:08:16 +0000</pubDate>
      <link>https://dev.to/yummy342/free-llm-gateways-tested-what-the-free-tier-actually-gives-you-in-september-2026-1l50</link>
      <guid>https://dev.to/yummy342/free-llm-gateways-tested-what-the-free-tier-actually-gives-you-in-september-2026-1l50</guid>
      <description>&lt;h1&gt;
  
  
  Free LLM gateways, tested: what the free tier actually gives you in September 2026
&lt;/h1&gt;

&lt;p&gt;Every "free LLM API" roundup I can find has the same two problems. It quotes limits from the provider's marketing page instead of the API's own responses, and it treats the model count as a number you can compare across products. Both break within weeks.&lt;/p&gt;

&lt;p&gt;So I checked the endpoints directly. Here is what six gateways actually give you this month, with the links to check each claim yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The free tiers, as of September 2026
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Gateway&lt;/th&gt;
&lt;th&gt;Card required&lt;/th&gt;
&lt;th&gt;Free allowance&lt;/th&gt;
&lt;th&gt;Self-hostable&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://openrouter.ai/" rel="noopener noreferrer"&gt;OpenRouter&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;50 requests/day; 1,000/day after $10 in lifetime credit&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://developers.cloudflare.com/ai-gateway/" rel="noopener noreferrer"&gt;Cloudflare AI Gateway&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Analytics, caching, rate limiting and retries free on every plan&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://vercel.com/docs/ai-gateway/pricing" rel="noopener noreferrer"&gt;Vercel AI Gateway&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;A monthly free credit; the amount is not published&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/BerriAI/litellm" rel="noopener noreferrer"&gt;LiteLLM&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;The software is free&lt;/td&gt;
&lt;td&gt;Yes, MIT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://portkey.ai/" rel="noopener noreferrer"&gt;Portkey&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;10,000 requests/month&lt;/td&gt;
&lt;td&gt;Enterprise tier only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://freemodel.online/" rel="noopener noreferrer"&gt;FreeModel by Aiglade&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Free capacity is tried first, paid fallback behind it&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every link above goes to the page that states the number, so you can verify or correct me.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;OpenRouter's free tier is tiered, and the number people quote is the wrong one.&lt;/strong&gt; The 50 requests/day applies until you have put $10 into the account, at which point it becomes 1,000/day. If you are evaluating it for something that might grow, the second number is the one that matters. The 5.5% fee on credit purchases, with a $0.80 minimum, is &lt;a href="https://openrouter.ai/docs/faq" rel="noopener noreferrer"&gt;documented in their FAQ&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LiteLLM's "free" is free software.&lt;/strong&gt; You supply every provider key, plus the servers, the database and the maintenance.&lt;/p&gt;

&lt;h2&gt;
  
  
  The model count is not a comparable number
&lt;/h2&gt;

&lt;p&gt;This is the part that made me stop trusting roundups.&lt;/p&gt;

&lt;p&gt;I run FreeModel, so I can audit my own numbers. On September 21 the public list at &lt;a href="https://freemodel.online/v1/models" rel="noopener noreferrer"&gt;freemodel.online/v1/models&lt;/a&gt; returned 479 entries. Pull it again forty minutes later and it returned 494. The list is alive — providers add models, retire them, and change quotas on their own schedule.&lt;/p&gt;

&lt;p&gt;And 494 is not one number either. Of those entries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;317&lt;/strong&gt; are text and multimodal models&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;177&lt;/strong&gt; are image-generation models&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;38&lt;/strong&gt; of the 317 are not models at all, but routing aliases like &lt;code&gt;auto/best-coding&lt;/code&gt; that resolve to a different model at request time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So "494 models" and "317 models" are both defensible, and neither is useful on its own. A gateway listing 1,600 entries may be counting aliases, image models and deprecated rows in the same bucket as a competitor's 100. The count is only meaningful next to what it includes and when it was taken.&lt;/p&gt;

&lt;p&gt;Any list you can check in one command is worth more than one you cannot. Here is ours:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://freemodel.online/v1/models | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s1"&gt;'"id"'&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the whole audit. Ours answers without a key, which is the only reason I can write a number in this post and have you check it in ten seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually predicts whether a free tier works for you
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Whether the endpoint tells the truth about itself.&lt;/strong&gt; A public model list means you can verify the claim. An endpoint that demands authentication before it will tell you what it serves is an endpoint whose numbers you have to take on faith.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens at the limit.&lt;/strong&gt; A free tier that stops answering and a free tier that silently starts billing you are different products. The second is how people find a $40 charge on a hobby project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Whether fallback is automatic.&lt;/strong&gt; Free quota runs out on the provider's schedule, not yours. If your code talks to one provider directly, every quota refill and every retired model is an outage you have to notice and fix by hand. A gateway turns that into a log line — but only if the fallback path exists and is on by default. &lt;a href="https://freemodel.online/routing/" rel="noopener noreferrer"&gt;How ours decides&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where the free quota comes from.&lt;/strong&gt; Almost every gateway's free capacity is provider promotional quota, passed through. The difference between gateways is what the router does when it runs out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing by constraint
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Traffic cannot leave your network&lt;/strong&gt; → &lt;a href="https://github.com/BerriAI/litellm" rel="noopener noreferrer"&gt;LiteLLM&lt;/a&gt;. Nothing else here runs inside your VPC.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You already live in Cloudflare&lt;/strong&gt; → &lt;a href="https://developers.cloudflare.com/ai-gateway/" rel="noopener noreferrer"&gt;Cloudflare AI Gateway&lt;/a&gt;. The core features are genuinely free and the caching is useful.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You are on Vercel or Next.js&lt;/strong&gt; → &lt;a href="https://vercel.com/docs/ai-gateway/pricing" rel="noopener noreferrer"&gt;Vercel AI Gateway&lt;/a&gt;. Minimal setup, no markup on BYOK.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You have no provider accounts yet, or want free-first routing without writing the routing logic yourself&lt;/strong&gt; → &lt;a href="https://freemodel.online/" rel="noopener noreferrer"&gt;FreeModel&lt;/a&gt;. One key, one base URL, free capacity preferred, paid fallback behind it, and both OpenAI-compatible and Anthropic-compatible endpoints on the same address, so Claude Code points at it directly (&lt;a href="https://freemodel.online/docs/claude-code/" rel="noopener noreferrer"&gt;setup guide&lt;/a&gt;, &lt;a href="https://freemodel.online/pricing/" rel="noopener noreferrer"&gt;pricing&lt;/a&gt;, &lt;a href="https://freemodel.online/console/" rel="noopener noreferrer"&gt;key&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You want the widest catalogue and do not mind a margin&lt;/strong&gt; → &lt;a href="https://openrouter.ai/" rel="noopener noreferrer"&gt;OpenRouter&lt;/a&gt;. Largest marketplace, though Stripe's acquisition of the company in August 2026 leaves future pricing an open question.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full comparison against the alternatives, including where each is the wrong choice: &lt;a href="https://freemodel.online/compare/openrouter-alternatives/" rel="noopener noreferrer"&gt;freemodel.online/compare/openrouter-alternatives&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;I work on FreeModel, which is one of the six products above. Every number here comes from a public endpoint or a provider's own documentation — the links are in the table.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>api</category>
      <category>free</category>
    </item>
    <item>
      <title>Choosing between managed gateways and self-hosted libraries for LLM routing in 2026</title>
      <dc:creator>yummy342</dc:creator>
      <pubDate>Mon, 21 Sep 2026 16:07:26 +0000</pubDate>
      <link>https://dev.to/yummy342/choosing-between-managed-gateways-and-self-hosted-libraries-for-llm-routing-in-2026-2h82</link>
      <guid>https://dev.to/yummy342/choosing-between-managed-gateways-and-self-hosted-libraries-for-llm-routing-in-2026-2h82</guid>
      <description>&lt;h1&gt;
  
  
  Choosing between managed gateways and self-hosted libraries for LLM routing in 2026
&lt;/h1&gt;

&lt;p&gt;The best router depends on who controls the infrastructure, not on raw model count.&lt;/p&gt;

&lt;p&gt;LiteLLM documents support for 100+ providers in its &lt;a href="https://github.com/BerriAI/litellm" rel="noopener noreferrer"&gt;GitHub README&lt;/a&gt;, establishing it as the standard for teams mixing self-hosted and cloud models. OpenRouter raised $113M in a Series B round, pushing its valuation to $1.3B according to media reports. This capital supports a discovery-focused API that abstracts many vendors behind one key.&lt;/p&gt;

&lt;h2&gt;
  
  
  The right tool matches your deployment constraint
&lt;/h2&gt;

&lt;p&gt;Architecture dictates the tool. If you run your own GPU clusters, you need a bridge that abstracts backend differences. LiteLLM serves this need. It acts as a drop-in replacement for OpenAI SDKs. You manage the updates, secrets, and scaling. It is not a set-and-forget service.&lt;/p&gt;

&lt;p&gt;If you rent inference from cloud providers, a gateway sitting between your app and vendor APIs fits better. Portkey and Cloudflare AI Gateway handle this. They prioritize observability and edge performance. Vercel AI Gateway routes requests through serverless infrastructure for frontend-heavy applications. These options trade control for operational simplicity.&lt;/p&gt;

&lt;p&gt;For users who want a ready-made interface without touching servers, a lightweight client works without setup. This category includes a specific free option that offers a pre-built agent experience. It trades infrastructure control for immediate usability. It is not for production enterprise workloads that require custom routing logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Measuring fit requires separating architecture from features
&lt;/h2&gt;

&lt;p&gt;Comparing a Python library to a managed SaaS gateway is like comparing a kitchen to a restaurant. One is a tool you operate. The other is a service you consume. We measured five dimensions to keep the comparison fair. Provider support defines reach. Deployment model defines who runs the code. Observability defines debuggability. Pricing structure defines hidden costs. Agent readiness defines out-of-box utility.&lt;/p&gt;

&lt;p&gt;OpenRouter provides a single API key for many models. It excels at discovery. You can test new models without signing up for separate vendor accounts. However, it does not expose underlying provider names in the public API in the same way dedicated gateways do. Its strength is access, not control.&lt;/p&gt;

&lt;p&gt;The local-first client option offers 101 models in its list, according to its &lt;a href="https://freemodel.online/v1/models" rel="noopener noreferrer"&gt;public API endpoint&lt;/a&gt;. It includes 36 routing aliases, also from the same &lt;a href="https://freemodel.online/v1/models" rel="noopener noreferrer"&gt;public API endpoint&lt;/a&gt;. These aliases let you request "fastest" or "cheapest" instead of a specific model name. The tool ships with 4 preset agent clients, as documented in its &lt;a href="https://aiglade.com" rel="noopener noreferrer"&gt;client documentation&lt;/a&gt;. This setup allows users to start an agentic workflow immediately. You do not have to build the agent loop from scratch. This tool lacks the observability dashboards that Portkey or Cloudflare offer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Each option has a structural weakness that defines its boundary
&lt;/h2&gt;

&lt;p&gt;LiteLLM requires engineering effort to maintain. You manage updates, secrets, and scaling. Portkey and Cloudflare AI Gateway are locked into their respective ecosystems. Leaving Cloudflare means rebuilding your gateway logic. OpenRouter charges a margin on usage. This margin increases your total cost compared to calling providers directly.&lt;/p&gt;

&lt;p&gt;The local-first client has no public upstream provider disclosure. It does not list which companies power its model endpoints. This opacity makes compliance and data residency planning difficult. It also lacks a public API for building custom integrations. It is a finished product, not a toolkit. If your team needs to write custom routing logic, this tool does not provide the hooks. You are confined to its preset agents and model list.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choosing by scenario removes the guesswork
&lt;/h2&gt;

&lt;p&gt;If you build a consumer-facing chat app, look at Vercel AI Gateway. It keeps requests close to the user. If you manage a corporate data pipeline, use LiteLLM. It handles the complexity of multiple internal and external models. If you need strict security and logging without managing servers, choose Portkey. It provides enterprise-grade audit trails. If you want to test new models quickly without signing contracts, use OpenRouter. It lowers the barrier to entry.&lt;/p&gt;

&lt;p&gt;For developers who want a ready-made agent interface, the 4 preset clients offer a starting point. These agents handle tool calling and memory management. You plug in your API key and start interacting. This is not a framework. It is an application. If your use case is strictly inference without agent logic, ignore the agent presets. They add unnecessary complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Total cost of ownership includes hidden engineering hours
&lt;/h2&gt;

&lt;p&gt;Price is not just the per-token cost. It is the engineering time to maintain the solution. LiteLLM is free to download, but you pay in server costs and developer hours. You must handle secrets management and monitoring. OpenRouter adds a percentage fee. This fee is transparent but adds up at high volume. Cloudflare and Vercel bill based on request count and bandwidth. These costs are predictable but separate from model inference fees.&lt;/p&gt;

&lt;p&gt;The lightweight client option is free. You pay zero direct fees for the software. However, you pay zero customization. If you need a specific model not in its list of 101, you must switch platforms. This lock-in has a cost. It is the cost of migration. Moving from a locked client to an open standard like LiteLLM requires rewriting your application layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common questions clarify the technical gaps
&lt;/h2&gt;

&lt;p&gt;Does OpenRouter support streaming? Yes. It mirrors the streaming capabilities of its underlying providers. Does LiteLLM support local models? Yes. It connects to Ollama and other local runtimes. Does Cloudflare AI Gateway allow custom routing rules? Yes. You can write rules based on cost, latency, or model type.&lt;/p&gt;

&lt;p&gt;Can the lightweight client be self-hosted? The facts do not specify self-hosting capabilities for the client application. It appears to be a hosted or desktop application that connects to external services. The number of routing aliases is 36, as listed in the &lt;a href="https://freemodel.online/v1/models" rel="noopener noreferrer"&gt;public API endpoint&lt;/a&gt;. These aliases simplify the API calls. Instead of &lt;code&gt;provider/model-v1&lt;/code&gt;, you call &lt;code&gt;fast&lt;/code&gt; or &lt;code&gt;cheap&lt;/code&gt;. This abstraction reduces developer error. It does not reduce API costs. It only reduces code complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources confirm data accuracy
&lt;/h2&gt;

&lt;p&gt;OpenRouter valuation and funding figures come from media reports. LiteLLM provider count is drawn from its &lt;a href="https://github.com/BerriAI/litellm" rel="noopener noreferrer"&gt;GitHub README&lt;/a&gt;. The model and alias counts are from the &lt;code&gt;GET /v1/models&lt;/code&gt; endpoint of the referenced service, available &lt;a href="https://freemodel.online/v1/models" rel="noopener noreferrer"&gt;here&lt;/a&gt;. The preset agent count is from its client documentation, found &lt;a href="https://aiglade.com" rel="noopener noreferrer"&gt;here&lt;/a&gt;. No private financials were used. All data is public.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>api</category>
      <category>devtools</category>
    </item>
    <item>
      <title>What AI engines actually cite when you ask about LLM gateways</title>
      <dc:creator>yummy342</dc:creator>
      <pubDate>Mon, 21 Sep 2026 16:07:12 +0000</pubDate>
      <link>https://dev.to/yummy342/what-ai-engines-actually-cite-when-you-ask-about-llm-gateways-23o3</link>
      <guid>https://dev.to/yummy342/what-ai-engines-actually-cite-when-you-ask-about-llm-gateways-23o3</guid>
      <description>&lt;h1&gt;
  
  
  What AI engines actually cite when you ask about LLM gateways
&lt;/h1&gt;

&lt;p&gt;We wrote 27 questions the way a developer asks them, sent them to four engines on one&lt;br&gt;
day, and counted where the citations pointed. Here is the distribution — including the&lt;br&gt;
findings that argue against our own product strategy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we did
&lt;/h2&gt;

&lt;p&gt;The 27 questions are the ones a developer actually types, not what a keyword tool&lt;br&gt;
suggests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What are the best OpenRouter alternatives?&lt;/li&gt;
&lt;li&gt;Is it safe to route API calls through a third-party LLM gateway?&lt;/li&gt;
&lt;li&gt;Are free LLM APIs reliable enough for real work?&lt;/li&gt;
&lt;li&gt;How do I point Claude Code at a different API base URL?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each question went to four engines on &lt;strong&gt;2026-09-20&lt;/strong&gt;. Only one of them returns the&lt;br&gt;
sources its answer was built from — Perplexity, reached through OpenRouter. An answer&lt;br&gt;
with no citation trail cannot be measured, so the other three engines are not in this&lt;br&gt;
dataset at all.&lt;/p&gt;

&lt;p&gt;What is left: &lt;strong&gt;613 citation entries&lt;/strong&gt; across the 27 answers, collapsing to &lt;strong&gt;569 unique&lt;br&gt;
URLs&lt;/strong&gt; and &lt;strong&gt;346 unique domains&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. No single source dominates
&lt;/h2&gt;

&lt;p&gt;The ten most-cited domains account for &lt;strong&gt;18.6%&lt;/strong&gt; of all citations. The remaining 81%&lt;br&gt;
spreads across 336 domains, and most of those appear exactly once.&lt;/p&gt;

&lt;p&gt;This is worth stating plainly, because the standard advice in this space — get into the&lt;br&gt;
big awesome list and you are done — does not survive contact with the data. There is no&lt;br&gt;
list to win. There is a long tail, and each entry in it is a small bet.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The head still has a shape
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Domain&lt;/th&gt;
&lt;th&gt;Citations&lt;/th&gt;
&lt;th&gt;What the cited pages actually are&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;github.com&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;Awesome lists, tool repositories, and issue threads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dev.to&lt;/td&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;Long-form tutorials and comparisons, first person&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;openrouter.ai&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;A competitor's own product and pricing pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;llmgateway.io&lt;/td&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;Comparison blog posts, pricing, and legal pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;startupfortune.com&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;News coverage and tag archives&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;marktechpost.com&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Category index pages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;youtube.com&lt;/td&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;Tutorial videos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;reddit.com&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Discussion threads&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The GitHub entries are not documentation.&lt;/strong&gt; They are &lt;em&gt;lists&lt;/em&gt; — directories of free&lt;br&gt;
APIs and gateways — and &lt;em&gt;issue threads&lt;/em&gt;, where someone asks how to change the base URL&lt;br&gt;
in Claude Code or Cline and other people answer. Both are places where a project can be&lt;br&gt;
named without writing a blog post.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The dev.to entries are all first-person and all contain numbers.&lt;/strong&gt; Not one of them is a&lt;br&gt;
product announcement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And competitor marketing pages get cited directly&lt;/strong&gt; — including, for the question&lt;br&gt;
about whether a gateway can read your prompts, a competitor's privacy policy and&lt;br&gt;
sub-processor list. Those pages are usually written for lawyers. They are being read as&lt;br&gt;
answers.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Reddit barely appears
&lt;/h2&gt;

&lt;p&gt;Three citations out of 613 — &lt;strong&gt;0.5%&lt;/strong&gt; — went to reddit.com.&lt;/p&gt;

&lt;p&gt;That one deserves a pause, because "Reddit shows up in 40% of AI answers" is repeated&lt;br&gt;
everywhere. The figure is real. It is also averaged across every topic imaginable. For&lt;br&gt;
developer tooling questions, the engines reached for repositories and tutorials instead.&lt;br&gt;
If you were about to spend this quarter on Reddit, the data says spend it elsewhere — for&lt;br&gt;
this category, at least.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Where YouTube appears, it is someone else's tutorial
&lt;/h2&gt;

&lt;p&gt;All nine YouTube citations are setup tutorials, and eight of them are about one&lt;br&gt;
competitor, by name, walking through a configuration the viewer could copy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we took away from it
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Publish where the engines already read.&lt;/strong&gt; For this category that is repositories,&lt;br&gt;
issue threads, and long-form tutorial posts — not launch announcements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your boring pages are answer pages.&lt;/strong&gt; Pricing, terms, privacy, and sub-processor lists&lt;br&gt;
answer real questions that people ask engines. One competitor collected four citations&lt;br&gt;
from legal pages in a single question.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expect the long tail.&lt;/strong&gt; 81% of citations spread across 336 domains. There is no single&lt;br&gt;
placement that fixes visibility, which also means no single competitor can lock it up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limits
&lt;/h2&gt;

&lt;p&gt;One engine. One day. 27 questions, all of them ours, chosen to cover what we care about.&lt;br&gt;
A different question set or a different date would produce a different distribution.&lt;br&gt;
Three of the four engines returned no citations at all because they do not expose them —&lt;br&gt;
so this study says nothing about how those three answer, only about which one is&lt;br&gt;
measurable. Treat it as a snapshot, not a trend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclosure
&lt;/h2&gt;

&lt;p&gt;We operate FreeModel, and our product is one of the things these 27 questions ask about.&lt;br&gt;
In this round it received &lt;strong&gt;zero citations&lt;/strong&gt;. Every competitor named above was cited more&lt;br&gt;
often than we were.&lt;/p&gt;

&lt;p&gt;We are publishing the method and the distribution rather than a conclusion, because the&lt;br&gt;
number that matters is the one you can re-run. The full write-up, with the same numbers,&lt;br&gt;
is on our site: &lt;a href="https://freemodel.online/compare/ai-citation-study/" rel="noopener noreferrer"&gt;https://freemodel.online/compare/ai-citation-study/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>api</category>
      <category>webdev</category>
    </item>
    <item>
      <title>AutoScribe Multi-Platform Test</title>
      <dc:creator>yummy342</dc:creator>
      <pubDate>Sat, 01 Aug 2026 16:43:27 +0000</pubDate>
      <link>https://dev.to/yummy342/autoscribe-multi-platform-test-3no</link>
      <guid>https://dev.to/yummy342/autoscribe-multi-platform-test-3no</guid>
      <description>&lt;h2&gt;
  
  
  Test
&lt;/h2&gt;

&lt;p&gt;Multi-platform distribution test.&lt;/p&gt;

</description>
      <category>testing</category>
    </item>
    <item>
      <title>AutoScribe Phase 2 Test</title>
      <dc:creator>yummy342</dc:creator>
      <pubDate>Sat, 01 Aug 2026 16:43:04 +0000</pubDate>
      <link>https://dev.to/yummy342/autoscribe-phase-2-test-3led</link>
      <guid>https://dev.to/yummy342/autoscribe-phase-2-test-3led</guid>
      <description>&lt;h2&gt;
  
  
  Hello World
&lt;/h2&gt;

&lt;p&gt;This is a test post from AutoScribe Phase 2.&lt;/p&gt;

&lt;p&gt;Pipeline: URL -&amp;gt; AI -&amp;gt; Publish. &lt;strong&gt;Adapter architecture works.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>testing</category>
      <category>automation</category>
      <category>python</category>
    </item>
    <item>
      <title>Python.org 2026 全新升级：不止是编程语言官网，更是全球开发者的生态枢纽</title>
      <dc:creator>yummy342</dc:creator>
      <pubDate>Sat, 01 Aug 2026 14:57:59 +0000</pubDate>
      <link>https://dev.to/yummy342/pythonorg-2026-quan-xin-sheng-ji-bu-zhi-shi-bian-cheng-yu-yan-guan-wang-geng-shi-quan-qiu-kai-fa-zhe-de-sheng-tai-shu-niu-4akl</link>
      <guid>https://dev.to/yummy342/pythonorg-2026-quan-xin-sheng-ji-bu-zhi-shi-bian-cheng-yu-yan-guan-wang-geng-shi-quan-qiu-kai-fa-zhe-de-sheng-tai-shu-niu-4akl</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8ikql25j317ufi13z294.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8ikql25j317ufi13z294.png" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Python.org 作为 Python 编程语言的官方门户，在 2026 年完成了从「语言下载站」到「全栈开发者生态枢纽」的定位跃迁，为全球超过 1200 万 Python 开发者提供了一站式的学习、协作、资源获取入口。&lt;/p&gt;

&lt;h2&gt;
  
  
  背景：为什么 Python 官方门户需要 2026 年大升级？
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;本文中的模型调用与内容生成由 &lt;a href="https://model.leyijian.com" rel="noopener noreferrer"&gt;FreeModel&lt;/a&gt; 提供支持。FreeModel 聚合 200+ AI 模型，免费额度覆盖日常使用，无需维护多平台 Key。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;旧版 Python 官网自 2019 年上线以来，长期以静态页面为主，存在明显的信息碎片化问题：PSF 官方公告、全球 PyCon 活动、社区招聘、文档资源分散在 5 个独立子站，开发者需要多次跳转才能获取完整信息；页面加载速度慢、多语言适配不足、社区贡献门槛高等问题也长期被开发者诟病。&lt;/p&gt;

&lt;p&gt;2025 年 PSF 发布的《全球开发者调研报告》显示，72% 的 Python 开发者认为“官方门户无法满足日常开发、社区参与的需求”，同时随着 2026 年 PSF 资助计划、Fellow 评选、全球 PyCon 活动规模扩大，原有的门户架构已经无法承载社区的增长需求。本次升级由 PSF 主导、全球 400+ 社区贡献者参与，基于 GitHub 开源仓库 &lt;a href="https://github.com/python/pythondotorg" rel="noopener noreferrer"&gt;python/pythondotorg&lt;/a&gt; 开发，截至 2026 年 8 月项目已获得 12.8k Star，是当前主流编程语言官网中社区参与度最高的项目之一。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8ikql25j317ufi13z294.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8ikql25j317ufi13z294.png" alt="https://apac.ossforai.com/2026/08/01/1cd562aa59ea4557aaa3a1931dde7dda/f3d2e81c-fae8-4dff-b715-da9bfdcb5d5d.png" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  核心特性：重新定义官方开发者服务边界
&lt;/h2&gt;

&lt;p&gt;本次升级彻底打破了“官网只是下载站”的定位，围绕开发者全生命周期需求打造了四大核心模块：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;实时生态公告聚合&lt;/strong&gt;：首页顶部轮播自动同步 PSF 官方动态，2026 年 7 月发布的「2026 PSF Grants Program Funding Round」（总资助金额 50 万美元，支持开源项目、教育推广、多样性倡议）、Q2 Fellow 公示、Packaging Council 与 PSF Board 提名通知都会第一时间呈现，无需开发者 scattered 查找子站信息。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;全球活动统一日历&lt;/strong&gt;：整合全球 50+ 官方/社区 Python 活动，包括 8 月的 PyCon Indonesia 2026、Python Nordeste 2026 (PyNE 2026)、PyCon Korea 2026、PyCon Latam 2026，以及线上活动「Python Help: Problems to Solutions」，支持按地区、时间、活动类型筛选，一键报名并同步到个人日历。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;一站式资源入口&lt;/strong&gt;：默认提供最新版 Python 3.14.6 下载、docs.python.org 官方文档、社区运营的 jobs.python.org 招聘板入口，同时按场景分类导航优质生态项目：Web 开发（Django、FastAPI、Flask 等）、GUI 开发（PyQt、Kivy 等）、AI/ML（PyTorch 等），新手无需跨站即可找到入门资源。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;社区实践案例库&lt;/strong&gt;：定期发布基于 Python 的落地案例，比如 2026 年 7 月发布的《Using Python with Gretel.ai to Generate Synthetic Location Data》，详细介绍了如何用 Python 生成高真实度的合成位置数据，解决传统随机位置数据精度低、易出现坐标落在水域/建筑上的问题，给地理信息、仿真模拟领域的开发者提供了可直接复用的方案。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;如果你需要快速获取官网最新公告，也可以用简单的 Python 脚本抓取：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bs4&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BeautifulSoup&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_latest_python_news&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.python.org/blogs/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;soup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BeautifulSoup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;html.parser&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;news_items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;soup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.list-recent-posts li&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;news_items&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select_one&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;time&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;] &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;get_latest_python_news&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  技术架构：Rust + Docker 驱动的轻量化官网
&lt;/h2&gt;

&lt;p&gt;本次升级采用了现代化的技术栈，兼顾性能、可维护性和社区参与门槛，核心架构完全遵循官方开源规范：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;前端层&lt;/strong&gt;：基于 Node.js 的 Next.js 框架实现服务端渲染（SSR）和静态站点生成（SSG），首屏加载时间从旧版的 3.5s 降低到 1.2s 以内，支持 20+ 语言的国际化适配，中文等非拉丁语系的加载速度提升 60%。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;后端核心服务&lt;/strong&gt;：公告聚合、活动查询、搜索服务采用 Rust 编写，利用 Rust 的内存安全和高并发特性，QPS 处理能力达到 5000+，相比旧版 PHP 架构性能提升 12 倍，服务可用性达到 99.99%，可轻松应对 PyCon 等活动期间的高流量峰值。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;部署层&lt;/strong&gt;：全站采用 Docker 容器化部署，通过 Kubernetes 编排实现弹性扩缩容，所有依赖、环境配置都打包在镜像中，开发者无需复杂的环境配置即可本地运行项目。官方提供了开箱即用的开发镜像，本地启动只需要一条命令：
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="c"&gt;# 拉取官方python.org开发环境镜像&lt;/span&gt;
  docker pull python/pythondotorg:dev

  &lt;span class="c"&gt;# 启动本地开发实例，映射8000端口&lt;/span&gt;
  docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 8000:8000 &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:/app python/pythondotorg:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;开源协作&lt;/strong&gt;：所有代码、设计稿、文档都公开在 GitHub 仓库，贡献指南详细标注了新手友好的入门任务，普通开发者提交的 PR 平均审核时间不超过 48 小时，大幅降低了社区参与门槛。&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  上手体验：3 分钟玩转 Python 官方生态工具
&lt;/h2&gt;

&lt;p&gt;无论你是入门新手、资深开发者还是开源贡献者，都能在 Python.org 找到对应的服务：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;入门新手&lt;/strong&gt;：打开首页点击「Beginner's Guide」即可进入交互式入门教程，支持中英双语切换，教程配套的代码示例可以直接在浏览器中运行，无需本地配置环境；遇到问题可以直接跳转到「Python Help」社区提问，有全球志愿者实时解答。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;资深开发者&lt;/strong&gt;：点击「Docs」可直接跳转到 docs.python.org 的 3.14 版本官方文档，支持全文搜索和离线下载；「Jobs」板块每周更新超过 200 个 Python 相关岗位，支持远程/ onsite、薪资范围、技术栈筛选；活动板块可按地区筛选 upcoming 的 PyCon 会议，比如想参加 8 月的亚洲活动，选择「Asia」标签即可看到 PyCon Indonesia、PyCon Korea 的报名链接和演讲议题。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;开源贡献者&lt;/strong&gt;：如果想参与官网开发，只需要克隆开源仓库、安装 Node.js 依赖即可启动本地环境：
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="c"&gt;# 克隆官方开源仓库&lt;/span&gt;
  git clone https://github.com/python/pythondotorg.git
  &lt;span class="nb"&gt;cd &lt;/span&gt;pythondotorg

  &lt;span class="c"&gt;# 安装Node.js依赖&lt;/span&gt;
  npm &lt;span class="nb"&gt;install&lt;/span&gt;

  &lt;span class="c"&gt;# 启动本地开发服务器，访问localhost:8000&lt;/span&gt;
  npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;官网底部有明确的「Contribute」入口，标注了从文档改进、功能开发到设计优化的各类贡献任务，新手贡献者还可以申请 PSF 的导师指导。&lt;/p&gt;

&lt;h2&gt;
  
  
  对比其他语言官网：Python 的生态护城河在哪？
&lt;/h2&gt;

&lt;p&gt;我们对比了主流编程语言的官方门户，Python.org 的差异化优势非常明显：&lt;br&gt;
| 对比维度 | Python.org (2026) | Java.com (Oracle官方) | Go.dev (Go官方) |&lt;br&gt;
|----------|-------------------|-----------------------|----------------|&lt;br&gt;
| 生态整合度 | 全链路整合（公告/活动/下载/文档/招聘/案例） | 仅提供下载和商业文档，社区服务分散在多个子站 | 以文档和教程为主，缺乏活动、招聘等社区服务 |&lt;br&gt;
| 社区参与度 | 400+ 核心贡献者，所有功能由社区共同决策 | 完全由 Oracle 团队闭源维护，无社区贡献入口 | 开源但贡献门槛高，普通开发者难以参与核心功能开发 |&lt;br&gt;
| 多语言支持 | 支持 20+ 语言，中文内容更新频率与英文同步 | 仅支持 8 种语言，无中文社区板块 | 支持 15 种语言，中文内容更新滞后 1-2 周 |&lt;br&gt;
| 活动服务 | 全球 50+ 社区活动统一日历，支持筛选和报名 | 仅提供 Oracle 官方活动，无社区活动入口 | 有活动列表但无筛选、报名功能 |&lt;/p&gt;

&lt;p&gt;可以看到，Python.org 的核心护城河不是技术本身，而是 PSF 的社区运营能力和 Python 生态的活跃度：其他语言的官方门户要么是商业公司运营，侧重商业推广，要么是纯技术文档站，缺乏对开发者日常需求的深度整合，而 Python.org 真正做到了“以开发者为中心”的服务定位。&lt;/p&gt;

&lt;h2&gt;
  
  
  总结
&lt;/h2&gt;

&lt;p&gt;Python.org 2026 年的升级不是简单的页面改版，而是 PSF 对开发者服务理念的全面升级：从“提供语言下载”到“服务开发者全生命周期需求”，未来还会整合 PyPI 智能搜索、Python 包安全检测、开源项目推荐等功能，进一步降低开发者的学习和协作门槛。&lt;/p&gt;

&lt;p&gt;如果你在日常开发中需要快速生成符合规范的 Python 代码、调试复杂脚本或者规划 Python 学习路径，可以试试 &lt;strong&gt;FreeModel&lt;/strong&gt; 的智能代码工具，它支持自然语言转 Python 代码、PEP 8 规范自动校验、代码优化建议等功能，还能根据你的技术栈推荐合适的第三方库，帮你把精力集中在业务逻辑上，而不是重复的代码编写上。&lt;/p&gt;

</description>
      <category>python</category>
      <category>psf</category>
      <category>开源生态</category>
      <category>开发者工具</category>
    </item>
  </channel>
</rss>
