深度解析 simonw/llm 项目——12.2k Star、63 个版本迭代、50+ 插件生态,如何成为终端 AI 工具的事实标准。
项目概览
LLM 是由 Django 联合创始人、知名开源开发者 Simon Willison 创建的命令行工具和 Python 库,用于统一访问 OpenAI、Anthropic Claude、Google Gemini、Meta Llama 等数十种大语言模型。它不仅支持远程 API 调用,还支持通过插件在本地运行模型。
关键数据:
| 指标 | 数值 |
|---|---|
| GitHub Stars | 12,200+ |
| 最新版本 | 0.31(2026-04-24) |
| 累计发布版本 | 63 |
| 官方+社区插件 | 50+ |
| 支持模型数量 | 100+(含插件) |
| 代码语言 | Python 99.8% |
| 许可证 | Apache 2.0 |
核心设计理念
Unix 哲学在 AI 时代的回归
LLM 的设计根植于 Unix 哲学——做一件事并做好。它将"与语言模型交互"这个行为,抽象为一条可以在终端执行的命令:
llm"Ten fun names for a pet pelican"这行代码的背后是一个精心设计的统一抽象层。用户无需关心底层是 GPT-4o 还是 Claude 4 Opus,无需记忆不同的 API 签名和认证方式,只需要知道模型的名称。
微内核 + 插件架构
LLM 采用了类似操作系统微内核的设计——核心只负责命令行解析、密钥管理、SQLite 日志和插件加载,所有模型的具体实现都通过插件完成:
┌─────────────────────────────────────┐ │ LLM Core │ │ ┌──────────┐ ┌──────────────────┐ │ │ │ CLI 解析 │ │ 密钥管理 │ │ │ └──────────┘ └──────────────────┘ │ │ ┌──────────┐ ┌──────────────────┐ │ │ │SQLite 日志│ │ 插件加载器 │ │ │ └──────────┘ └──────────────────┘ │ └─────────────┬───────────────────────┘ │ ┌─────────┼─────────┐ ▼ ▼ ▼ ┌────────┐┌────────┐┌────────┐ │llm- ││llm- ││llm- │ │openai ││anthropic││ollama │ └────────┘└────────┘└────────┘这种架构带来了三个关键优势:
- 核心精简:基础安装只包含 OpenAI 模型支持,不引入不必要的依赖
- 按需扩展:需要 Claude?
llm install llm-anthropic。需要本地模型?llm install llm-ollama - 社区驱动:任何人都可以编写插件来支持新的模型提供商
安装与快速上手
安装
支持多种安装方式,覆盖不同用户偏好:
# pippipinstallllm# Homebrew(macOS/Linux)brewinstallllm# pipx(隔离环境安装)pipxinstallllm# uv(Rust 实现的快速包管理器)uv toolinstallllm30 秒上手
# 1. 设置 OpenAI API Keyllm keyssetopenai# 粘贴你的 API Key# 2. 执行一个提示词(默认使用 gpt-4o-mini)llm"Ten fun names for a pet pelican"# 3. 从图像中提取文本llm"extract text"-ascanned-document.jpg# 4. 用系统提示分析代码catmyfile.py|llm-s"Explain this code"# 5. 启动交互式聊天llm chat-mgpt-4.1接入其他模型
# Google Geminillminstallllm-gemini llm keyssetgemini llm-mgemini-2.0-flash'Tell me fun facts about Mountain View'# Anthropic Claudellminstallllm-anthropic llm keyssetanthropic llm-mclaude-4-opus'Impress me with wild facts about turnips'# 本地模型(Ollama)llminstallllm-ollama ollama pull llama3.2:latest llm-mllama3.2:latest'What is the capital of France?'核心功能深度解析
1. 提示词执行与管道
LLM 最基础的能力是在命令行执行提示词,但它远不止于此。它天然适配 Unix 管道:
# 将文件内容作为提示词输入catREADME.md|llm-s"Summarize this in 3 bullet points"# 提取代码块llm-x'Python function to reverse a string'# -x 参数自动提取响应中第一个 fenced code block# 继续上一次对话llm-c"Now do it in JavaScript"# 使用模糊搜索指定模型(不需要记完整 ID)llm-qgpt-q4o"your prompt"-x(--extract)和--xl(--extract-last)参数是 LLM 的一个巧妙设计——在终端场景下,你往往只关心代码本身而非模型的解释文字,这两个参数直接提取响应中的代码块,省去了手动复制。
2. 模板系统:可复用的提示词
模板允许你保存和复用提示词配置,包括系统提示、模型选择、参数和工具:
# 创建一个模板llm-s"Translate to French"-mgpt-4.1-mini--savetranslate-fr# 使用模板llm-ttranslate-fr"Hello, how are you?"# 模板支持变量llm-s"Translate to$language"--savetranslate llm-ttranslate-planguage Spanish"Hello"模板以 YAML 文件存储,结构清晰:
system:Translate to{$language}model:gpt-4.1-minioptions:temperature:0.3更强大的是,模板可以绑定工具和 Schema(下文详述),这意味着你可以创建"一键执行"的复杂工作流。
GitHub 模板共享:通过llm-templates-github插件,你可以直接使用他人在 GitHub 上分享的模板:
llminstallllm-templates-github llm-tgh:simonw/pelican-svg-mo3-mini3. Fragments:长上下文组装器
Fragments 是 0.24 版本引入的关键特性,解决了长上下文场景下的提示词组装问题。它允许你从多个来源(URL、文件路径、数据库记录)组装一个长提示词,并且这些内容会在 SQLite 中去重存储:
# 从 URL 加载内容作为上下文llm-fhttps://llm.datasette.io/robots.txt'explain this file'# 组合多个来源llm-fpaper.pdf-fnotes.md'Compare these documents'# 在聊天中使用llm chat-fcodebase/'Ask questions about this code'Fragments 的真正威力在于插件生态。通过register_fragment_loaders()插件钩子,社区已经构建了丰富的片段加载器:
| 插件 | 用途 | 示例 |
|---|---|---|
| llm-video-frames | 视频转帧序列 | llm -f video-frames:video.mp4 |
| llm-fragments-github | 加载整个 GitHub 仓库 | llm -f github:simonw/files-to-prompt |
| llm-hacker-news | 导入 HN 对话 | llm -f hn:43615912 |
| llm-fragments-pypi | 加载 PyPI 包信息 | llm -f pypi:ruff |
| llm-fragments-pdf | PDF 转 Markdown | llm -f pdf:paper.pdf |
4. Schemas:结构化数据提取
0.23 版本引入的 Schema 功能是 LLM 最具实用价值的特性之一。它让大语言模型输出符合 JSON Schema 的结构化数据,而不是自由文本:
# 使用简洁的 Schema DSLllm--schema'name, age int, bio''Describe a nice dog'# 从新闻中提取人物llm--schema'name, title, organization, role''Extract people from this article'\-fnews-article.txt# 生成数组llm--schema'name, age int, bio'--schema-multi'Describe 3 nice dogs'在 Python API 中,Schema 可以使用 Pydantic 模型:
importllmfrompydanticimportBaseModelclassDog(BaseModel):name:strage:intmodel=llm.get_model("gpt-4o-mini")response=model.prompt("Describe a nice dog",schema=Dog)# 输出:{"name": "Buddy", "age": 3}这把 LLM 从"聊天工具"提升为"数据处理管道"——你可以用它从非结构化文本中批量提取结构化数据,然后存入数据库、生成报表或触发下游工作流。
5. Tools:让模型调用外部工具
0.26 版本引入的 Tool 支持是 LLM 的一次重大进化。模型现在可以调用 Python 函数来完成它自身无法完成的任务:
命令行使用:
# 内联定义工具llm--functions' def multiply(x: int, y: int) -> int: """Multiply two numbers.""" return x * y ''what is 34234 * 213345'# 使用插件注册的工具llm-Tsimple_eval'What is 2^20?'Python API——更强大的用法:
importllmdefmultiply(x:int,y:int)->int:"""Multiply two numbers."""returnx*y model=llm.get_model("gpt-4.1-mini")# chain() 方法自动处理多轮工具调用response=model.chain("What is 34234 * 213345?",tools=[multiply],)print(response.text())Toolbox 类——有状态的工具集合:
importllmclassMemory(llm.Toolbox):_memory=Nonedef_get_memory(self):ifself._memoryisNone:self._memory={}returnself._memorydefset(self,key:str,value:str):"Set something as a key"self._get_memory()[key]=valuedefget(self,key:str):"Get something from a key"returnself._get_memory().get(key)or""model=llm.get_model("gpt-4.1-mini")memory=Memory()conversation=model.conversation(tools=[memory])# 模型可以在多轮对话中使用 Memory 工具print(conversation.chain("Set name to Simon").text())print(conversation.chain("What is my name?").text())工具调试钩子——对开发者至关重要的功能:
defbefore_call(tool,tool_call):print(f"About to call{tool.name}with{tool_call.arguments}")defafter_call(tool,tool_call,tool_result):print(f"{tool.name}returned{tool_result.output}")response=model.chain("Complex question requiring tools",tools=[multiply,search],before_call=before_call,after_call=after_call,)社区已构建了丰富的工具插件:
| 插件 | 功能 |
|---|---|
| llm-tools-simpleeval | 数学表达式计算 |
| llm-tools-quickjs | 沙箱化 JavaScript 执行 |
| llm-tools-sqlite | 只读 SQL 查询 |
| llm-tools-datasette | 查询远程 Datasette |
| llm-tools-exa | 网络搜索 |
| llm-tools-rag | 嵌入集合检索 |
6. Embeddings:向量嵌入与语义搜索
LLM 不仅是语言模型的客户端,还是一个完整的嵌入管理工具:
# 生成单个嵌入llm embed-mtext-embedding-3-small-c"Hello world"# 批量嵌入文件内容llm embed-multi docs-mtext-embedding-3-small\--filesdocs/'*.md'--store# 语义相似度搜索llm similar docs-c"machine learning"Python API 同等强大:
importllm model=llm.get_embedding_model("text-embedding-3-small")# 生成嵌入向量vector=model.embed("Hello world")# 使用 Collection 进行批量管理collection=llm.Collection("docs",model)collection.embed("doc1","Content of document 1")collection.embed("doc2","Content of document 2")# 语义搜索results=collection.similar("machine learning")嵌入数据存储在 SQLite 中,配合llm-sentence-transformers、llm-clip、llm-embed-jina等插件,可以在本地构建完整的语义搜索系统。
7. SQLite 日志:完整的对话审计
LLM 默认将所有提示词和响应记录到本地 SQLite 数据库,这是一个被低估但极为重要的设计决策:
# 查看最近的日志llm logs# 按模型过滤llm logs-mgpt-4o# 搜索日志llm logs-q"pelican"# 查看特定对话llm logs--cidCONVERSATION_ID# 导出 Schema 收集的结构化数据llm logs--data--data-key name# 查看 Token 使用量llm logs-u这个设计带来了几个重要的好处:
- 可审计性:每次 AI 调用都有记录,方便回顾和追溯
- 可分析性:可以统计不同模型的使用频率和 Token 消耗
- 可复现性:对话历史完整保存,可以随时回溯
- 与 Datasette 集成:通过 Datasette 可以在浏览器中可视化浏览所有日志
8. 多模态支持
从 0.17 版本开始,LLM 支持图片、音频、视频等多模态输入:
# 图片(URL 或文件)llm-mgpt-4o"describe this image"\-ahttps://example.com/photo.jpg llm-mgpt-4o-mini"extract text"-ascanned-document.jpg# 多个附件llm-mgpt-4o"compare these images"-aimg1.jpg-aimg2.jpg# PDFllm-mgpt-4o"summarize this document"-areport.pdfPython API 同样支持:
model=llm.get_model("gpt-4o")response=model.prompt("Describe these images",attachments=[llm.Attachment(path="pelican.jpg"),llm.Attachment(url="https://example.com/photo.jpg"),])插件系统详解
插件钩子(Plugin Hooks)
LLM 的插件系统提供了六个核心钩子,覆盖了所有扩展场景:
| 钩子 | 用途 | 引入版本 |
|---|---|---|
register_commands(cli) | 添加新的 CLI 命令 | 早期 |
register_models(register) | 注册新的语言模型 | 早期 |
register_embedding_models(register) | 注册嵌入模型 | 早期 |
register_tools(register) | 注册工具函数 | 0.26 |
register_template_loaders(register) | 注册模板加载器 | 0.24 |
register_fragment_loaders(register) | 注册片段加载器 | 0.24 |
插件生态全景
本地模型插件:
| 插件 | 运行框架 | 平台 |
|---|---|---|
| llm-gguf | llama.cpp | 跨平台 |
| llm-mlx | Apple MLX | macOS |
| llm-ollama | Ollama | 跨平台 |
| llm-llamafile | llamafile | 跨平台 |
| llm-gpt4all | GPT4All | 跨平台 |
远程 API 插件:
覆盖了几乎所有主流模型提供商:Mistral、Gemini、Anthropic、Cohere、Perplexity、Groq、Fireworks、Together AI、DeepSeek、OpenRouter、Bedrock、xAI Grok 等。
如果某个 API 提供商兼容 OpenAI 接口格式,甚至不需要安装插件——只需在extra-openai-models.yaml中配置即可。
编写自己的插件:
LLM 的插件开发体验经过了精心打磨。以一个 Markov 链模型插件为例:
fromllmimportModel,registerclassMarkovModel(Model):model_id="markov"defexecute(self,prompt,stream,response,conversation):# 实现 execute 方法text=build_markov_chain(prompt.prompt)yieldtextdefregister_models(register):register(MarkovModel())安装和测试:
llminstall-e.llm-mmarkov"some input text"Python API:超越 CLI 的编程接口
LLM 不仅是 CLI 工具,还是一个完整的 Python 库。这意味着你可以将其集成到任何 Python 应用中:
基础用法
importllm# 获取模型model=llm.get_model("gpt-4o-mini")# 执行提示词(懒加载,直到调用 .text() 才真正执行)response=model.prompt("Five surprising names for a pet pelican")print(response.text())# 流式输出response=model.prompt("A poem about coding")forchunkinresponse:print(chunk,end="",flush=True)异步支持
importllm model=llm.get_async_model("gpt-4o")# 异步执行print(awaitmodel.prompt("Hello").text())# 异步流式输出asyncforchunkinmodel.prompt("Tell me a story"):print(chunk,end="",flush=True)对话管理
importllm model=llm.get_model("gpt-4.1-mini")conversation=model.conversation()response1=conversation.prompt("My name is Alice")print(response1.text())response2=conversation.prompt("What is my name?")# 模型知道你叫 Aliceprint(response2.text())Token 追踪与回调
importllm model=llm.get_model("gpt-4o-mini")response=model.prompt("A poem about a hippo")# 注册完成回调(可以用于追踪 Token 使用量)response.on_done(lambdar:print(r.usage()))print(response.text())# 输出:# Usage(input=20, output=494, details={})版本演进与关键里程碑
LLM 的版本迭代非常活跃,每个版本都引入了实质性功能:
| 版本 | 日期 | 核心特性 |
|---|---|---|
| 0.31 | 2026-04-24 | GPT-5.5 支持,文本详细度控制 |
| 0.30 | 2026-03-31 | 插件钩子增强,文档改进 |
| 0.29 | 2026-03-17 | GPT-5.4 系列模型 |
| 0.28 | 2025-12-12 | GPT-5.1/5.2,Python 3.10+ 要求 |
| 0.27 | 2025-08-11 | GPT-5 系列支持,模板可绑定工具 |
| 0.26 | 2025-05-27 | Tool 支持——里程碑版本 |
| 0.25 | 2025-05-04 | Fragment loader 支持附件,gpt-4.1/o3/o4-mini |
| 0.24 | 2025-04-07 | Fragments 与模板加载器——长上下文支持 |
| 0.23 | 2025-02-28 | Schema 支持——结构化数据提取 |
| 0.22 | 2025-02-16 | KeyModel/AsyncKeyModel,llm-mlx 插件 |
| 0.20 | 2025-01-22 | o1 模型,-x代码块提取 |
| 0.19 | 2024-12-01 | Token 使用量追踪与日志 |
| 0.18 | 2024-11-17 | 异步模型支持 |
| 0.17 | 2024-10-29 | 多模态附件——图片/音频/视频 |
| 0.16 | 2024-09-12 | OpenAI 模型使用内部 key 机制 |
| 0.15 | 2024-07-18 | gpt-4o-mini 成为默认模型 |
| 0.14 | 2024-05-13 | GPT-4o 支持 |
从演进路线可以看出,LLM 的功能拓展遵循了一条清晰的路径:基础调用 → 模型覆盖 → 数据持久化 → 多模态 → 异步 → 结构化输出 → 工具调用 → 长上下文。每一步都建立在之前的基础上,形成了有机的功能体系。
设计亮点与工程思考
1. SQLite 作为一等公民
LLM 对 SQLite 的使用是一个值得学习的工程决策。SQLite 不需要服务器进程,数据就在用户本地的logs.db文件中。这意味着:
- 零运维成本——不需要安装和配置数据库
- 便携性——整个对话历史就是一个文件
- 可查询——用 SQL 查询你的 AI 使用记录
- 与 Datasette 天然集成——在浏览器中浏览和分析
2. 懒加载的响应设计
Python API 中的Response对象采用懒加载设计——调用model.prompt()不会立即执行请求,只有在调用response.text()时才真正触发。这个设计让流式输出和回调注册变得自然:
response=model.prompt("A poem")response.on_done(lambdar:save_to_db(r))# 注册回调print(response.text())# 执行请求 + 流式输出 + 触发回调3. API Key 的多层管理
LLM 提供了三种 API Key 管理方式,覆盖不同安全需求:
llm keys set openai——加密存储到keys.json(文件权限 600)- 环境变量
OPENAI_API_KEY——CI/CD 和容器化场景 key=参数——Python API 编程场景
4. OpenAI 兼容模型的零插件接入
很多模型提供商(如 DeepSeek、vLLM、LocalAI)提供 OpenAI 兼容的 API。LLM 允许通过extra-openai-models.yaml配置这些模型,无需编写任何代码:
-model_id:deepseek-chatmodel_name:deepseek-chatapi_base:"https://api.deepseek.com/v1"api_key_name:deepseekcan_stream:truevision:truesupports_schema:true5. 对 Prompt Injection 的坦诚
与许多 AI 工具不同,LLM 在文档中明确警告了 Tool 使用场景下的 Prompt Injection 风险。这种坦诚的态度对于建立用户信任至关重要。
实战场景
场景一:代码审查管道
# 在 CI/CD 中自动审查代码变更gitdiffmain|llm-s"Review this code change. Focus on: 1. Security vulnerabilities 2. Performance issues 3. Code style problems Output as bullet points."-mgpt-4.1-mini场景二:文档批量提取结构化数据
importllm,json,glob model=llm.get_model("gpt-4.1-mini")forfileinglob.glob("contracts/*.txt"):withopen(file)asf:content=f.read()response=model.prompt(f"Extract contract details from:\n{content}",schema=llm.schema_dsl("party_a, party_b, value float, start_date, end_date, contract_type"))data=json.loads(response.text())print(json.dumps(data,indent=2))场景三:构建语义搜索系统
# 1. 批量嵌入文档llm embed-multi knowledge-base-mtext-embedding-3-small\--filesdocs/'*.md'--store# 2. 语义搜索llm similar knowledge-base-c"how to configure authentication"# 3. 结合 RAG 工具llminstallllm-tools-rag llm-Trag"What does the documentation say about API keys?"场景四:带工具的智能助手
importllmdefcalculate(expression:str)->str:"""Evaluate a mathematical expression safely."""importasttry:result=eval(compile(ast.parse(expression,mode='eval'),'','eval'))returnstr(result)exceptExceptionase:returnf"Error:{e}"defsearch_docs(query:str)->str:"""Search the documentation for relevant information."""# 自定义搜索逻辑returnsearch_internal_docs(query)model=llm.get_model("gpt-4.1")conversation=model.conversation(tools=[calculate,search_docs])whileTrue:user_input=input("> ")ifuser_input.lower()in('exit','quit'):breakresponse=conversation.chain(user_input)print(response.text())与同类工具对比
| 特性 | simonw/llm | LangChain | Ollama CLI | OpenAI CLI |
|---|---|---|---|---|
| 定位 | 通用 CLI + Python 库 | 应用开发框架 | 本地模型运行 | OpenAI 专属 |
| 多模型支持 | 100+(含插件) | 通过集成 | 仅本地模型 | 仅 OpenAI |
| 插件系统 | 成熟(6 个钩子) | 无(库级别扩展) | Modelfile | 无 |
| 对话日志 | SQLite 内置 | 需自行实现 | 无 | 无 |
| 结构化输出 | Schema DSL + Pydantic | 需 OutputParser | 无 | JSON Mode |
| 工具调用 | 内置 | Agent 框架 | 无 | Function Calling |
| 嵌入管理 | 内置 | 需 VectorStore | 无 | 无 |
| 本地模型 | 通过插件 | 通过集成 | 核心功能 | 无 |
| 学习曲线 | 低 | 高 | 低 | 低 |
LLM 的独特定位在于:它不是开发框架,而是开发者工具。你不需要学习复杂的 Agent 抽象、Chain 组装或者 Memory 管理——一条命令就能完成大部分工作,需要编程时也有简洁的 Python API。
局限与权衡
- 同步模型的阻塞问题:虽然 0.18 版本引入了异步支持,但并非所有插件都实现了
AsyncModel,在异步上下文中使用同步模型仍会阻塞事件循环 - Token 计费追踪粒度有限:虽然有
response.usage()和 SQLite 日志,但缺少按项目、按标签维度的成本聚合能力 - 没有内置的 Agent 编排:LLM 提供了
model.chain()和Toolbox,但没有 LangChain 那样的 Agent 编排框架(如 ReAct、Plan-and-Execute) - Windows 体验弱于 Unix:管道、文件路径、终端交互在 Windows 上偶尔会遇到兼容性问题
- Schema 支持依赖模型能力:结构化输出需要模型本身支持,并非所有模型都能可靠地遵循 Schema
总结
simonw/llm 是一个在 AI 工具生态中占据独特位置的项目。它不是另一个 LangChain,也不是另一个 Ollama——它是连接终端和大语言模型之间最直接的那座桥梁。
三个层面的价值:
- 工具层面:一条命令访问任何模型,管道友好的输入输出,SQLite 完整审计
- 平台层面:成熟的插件系统、模板共享、Schema/Tool/Fragment 三大扩展机制
- 哲学层面:Unix 哲学在 AI 时代的实践——简单、可组合、可编程
如果你是经常在终端工作的开发者,如果你厌倦了在不同 AI 网页之间切换,如果你想用脚本自动化 AI 工作流——LLM 值得一试。
pipinstallllm&&llm keyssetopenai&&llm"Why should developers use CLI tools for AI?"参考链接:
- 项目仓库:https://github.com/simonw/llm
- 官方文档:https://llm.datasette.io/
- 插件目录:https://llm.datasette.io/en/stable/plugins/directory.html
- 作者博客:https://simonwillison.net/tags/llm/
- 演示视频:https://www.youtube.com/watch?v=QUXQNi6jQ30