LLM:用一条命令统一所有大语言模型的 CLI 工具

深度解析 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 哲学------做一件事并做好。它将"与语言模型交互"这个行为,抽象为一条可以在终端执行的命令:

bash 复制代码
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  │
└────────┘└────────┘└────────┘

这种架构带来了三个关键优势:

  1. 核心精简:基础安装只包含 OpenAI 模型支持,不引入不必要的依赖
  2. 按需扩展 :需要 Claude?llm install llm-anthropic。需要本地模型?llm install llm-ollama
  3. 社区驱动:任何人都可以编写插件来支持新的模型提供商

安装与快速上手

安装

支持多种安装方式,覆盖不同用户偏好:

bash 复制代码
# pip
pip install llm

# Homebrew(macOS/Linux)
brew install llm

# pipx(隔离环境安装)
pipx install llm

# uv(Rust 实现的快速包管理器)
uv tool install llm

30 秒上手

bash 复制代码
# 1. 设置 OpenAI API Key
llm keys set openai
# 粘贴你的 API Key

# 2. 执行一个提示词(默认使用 gpt-4o-mini)
llm "Ten fun names for a pet pelican"

# 3. 从图像中提取文本
llm "extract text" -a scanned-document.jpg

# 4. 用系统提示分析代码
cat myfile.py | llm -s "Explain this code"

# 5. 启动交互式聊天
llm chat -m gpt-4.1

接入其他模型

bash 复制代码
# Google Gemini
llm install llm-gemini
llm keys set gemini
llm -m gemini-2.0-flash 'Tell me fun facts about Mountain View'

# Anthropic Claude
llm install llm-anthropic
llm keys set anthropic
llm -m claude-4-opus 'Impress me with wild facts about turnips'

# 本地模型(Ollama)
llm install llm-ollama
ollama pull llama3.2:latest
llm -m llama3.2:latest 'What is the capital of France?'

核心功能深度解析

1. 提示词执行与管道

LLM 最基础的能力是在命令行执行提示词,但它远不止于此。它天然适配 Unix 管道:

bash 复制代码
# 将文件内容作为提示词输入
cat README.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 -q gpt -q 4o "your prompt"

-x--extract)和 --xl--extract-last)参数是 LLM 的一个巧妙设计------在终端场景下,你往往只关心代码本身而非模型的解释文字,这两个参数直接提取响应中的代码块,省去了手动复制。

2. 模板系统:可复用的提示词

模板允许你保存和复用提示词配置,包括系统提示、模型选择、参数和工具:

bash 复制代码
# 创建一个模板
llm -s "Translate to French" -m gpt-4.1-mini --save translate-fr

# 使用模板
llm -t translate-fr "Hello, how are you?"

# 模板支持变量
llm -s "Translate to $language" --save translate
llm -t translate -p language Spanish "Hello"

模板以 YAML 文件存储,结构清晰:

yaml 复制代码
system: Translate to {$language}
model: gpt-4.1-mini
options:
  temperature: 0.3

更强大的是,模板可以绑定工具和 Schema(下文详述),这意味着你可以创建"一键执行"的复杂工作流。

GitHub 模板共享 :通过 llm-templates-github 插件,你可以直接使用他人在 GitHub 上分享的模板:

bash 复制代码
llm install llm-templates-github
llm -t gh:simonw/pelican-svg -m o3-mini

3. Fragments:长上下文组装器

Fragments 是 0.24 版本引入的关键特性,解决了长上下文场景下的提示词组装问题。它允许你从多个来源(URL、文件路径、数据库记录)组装一个长提示词,并且这些内容会在 SQLite 中去重存储:

bash 复制代码
# 从 URL 加载内容作为上下文
llm -f https://llm.datasette.io/robots.txt 'explain this file'

# 组合多个来源
llm -f paper.pdf -f notes.md 'Compare these documents'

# 在聊天中使用
llm chat -f codebase/ '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 的结构化数据,而不是自由文本:

bash 复制代码
# 使用简洁的 Schema DSL
llm --schema 'name, age int, bio' 'Describe a nice dog'

# 从新闻中提取人物
llm --schema 'name, title, organization, role' 'Extract people from this article' \
  -f news-article.txt

# 生成数组
llm --schema 'name, age int, bio' --schema-multi 'Describe 3 nice dogs'

在 Python API 中,Schema 可以使用 Pydantic 模型:

python 复制代码
import llm
from pydantic import BaseModel

class Dog(BaseModel):
    name: str
    age: int

model = 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 函数来完成它自身无法完成的任务:

命令行使用:

bash 复制代码
# 内联定义工具
llm --functions '
def multiply(x: int, y: int) -> int:
    """Multiply two numbers."""
    return x * y
' 'what is 34234 * 213345'

# 使用插件注册的工具
llm -T simple_eval 'What is 2^20?'

Python API------更强大的用法:

python 复制代码
import llm

def multiply(x: int, y: int) -> int:
    """Multiply two numbers."""
    return x * y

model = llm.get_model("gpt-4.1-mini")

# chain() 方法自动处理多轮工具调用
response = model.chain(
    "What is 34234 * 213345?",
    tools=[multiply],
)
print(response.text())

Toolbox 类------有状态的工具集合:

python 复制代码
import llm

class Memory(llm.Toolbox):
    _memory = None

    def _get_memory(self):
        if self._memory is None:
            self._memory = {}
        return self._memory

    def set(self, key: str, value: str):
        "Set something as a key"
        self._get_memory()[key] = value

    def get(self, key: str):
        "Get something from a key"
        return self._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())

工具调试钩子------对开发者至关重要的功能:

python 复制代码
def before_call(tool, tool_call):
    print(f"About to call {tool.name} with {tool_call.arguments}")

def after_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 不仅是语言模型的客户端,还是一个完整的嵌入管理工具:

bash 复制代码
# 生成单个嵌入
llm embed -m text-embedding-3-small -c "Hello world"

# 批量嵌入文件内容
llm embed-multi docs -m text-embedding-3-small \
  --files docs/ '*.md' --store

# 语义相似度搜索
llm similar docs -c "machine learning"

Python API 同等强大:

python 复制代码
import llm

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-transformersllm-clipllm-embed-jina 等插件,可以在本地构建完整的语义搜索系统。

7. SQLite 日志:完整的对话审计

LLM 默认将所有提示词和响应记录到本地 SQLite 数据库,这是一个被低估但极为重要的设计决策:

bash 复制代码
# 查看最近的日志
llm logs

# 按模型过滤
llm logs -m gpt-4o

# 搜索日志
llm logs -q "pelican"

# 查看特定对话
llm logs --cid CONVERSATION_ID

# 导出 Schema 收集的结构化数据
llm logs --data --data-key name

# 查看 Token 使用量
llm logs -u

这个设计带来了几个重要的好处:

  • 可审计性:每次 AI 调用都有记录,方便回顾和追溯
  • 可分析性:可以统计不同模型的使用频率和 Token 消耗
  • 可复现性:对话历史完整保存,可以随时回溯
  • 与 Datasette 集成:通过 Datasette 可以在浏览器中可视化浏览所有日志

8. 多模态支持

从 0.17 版本开始,LLM 支持图片、音频、视频等多模态输入:

bash 复制代码
# 图片(URL 或文件)
llm -m gpt-4o "describe this image" \
  -a https://example.com/photo.jpg
llm -m gpt-4o-mini "extract text" -a scanned-document.jpg

# 多个附件
llm -m gpt-4o "compare these images" -a img1.jpg -a img2.jpg

# PDF
llm -m gpt-4o "summarize this document" -a report.pdf

Python API 同样支持:

python 复制代码
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 链模型插件为例:

python 复制代码
from llm import Model, register

class MarkovModel(Model):
    model_id = "markov"

    def execute(self, prompt, stream, response, conversation):
        # 实现 execute 方法
        text = build_markov_chain(prompt.prompt)
        yield text

def register_models(register):
    register(MarkovModel())

安装和测试:

bash 复制代码
llm install -e .
llm -m markov "some input text"

Python API:超越 CLI 的编程接口

LLM 不仅是 CLI 工具,还是一个完整的 Python 库。这意味着你可以将其集成到任何 Python 应用中:

基础用法

python 复制代码
import llm

# 获取模型
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")
for chunk in response:
    print(chunk, end="", flush=True)

异步支持

python 复制代码
import llm

model = llm.get_async_model("gpt-4o")

# 异步执行
print(await model.prompt("Hello").text())

# 异步流式输出
async for chunk in model.prompt("Tell me a story"):
    print(chunk, end="", flush=True)

对话管理

python 复制代码
import llm

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?")
# 模型知道你叫 Alice
print(response2.text())

Token 追踪与回调

python 复制代码
import llm

model = llm.get_model("gpt-4o-mini")
response = model.prompt("A poem about a hippo")

# 注册完成回调(可以用于追踪 Token 使用量)
response.on_done(lambda r: 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() 时才真正触发。这个设计让流式输出和回调注册变得自然:

python 复制代码
response = model.prompt("A poem")
response.on_done(lambda r: save_to_db(r))  # 注册回调
print(response.text())  # 执行请求 + 流式输出 + 触发回调

3. API Key 的多层管理

LLM 提供了三种 API Key 管理方式,覆盖不同安全需求:

  1. llm keys set openai------加密存储到 keys.json(文件权限 600)
  2. 环境变量 OPENAI_API_KEY------CI/CD 和容器化场景
  3. key= 参数------Python API 编程场景

4. OpenAI 兼容模型的零插件接入

很多模型提供商(如 DeepSeek、vLLM、LocalAI)提供 OpenAI 兼容的 API。LLM 允许通过 extra-openai-models.yaml 配置这些模型,无需编写任何代码:

yaml 复制代码
- model_id: deepseek-chat
  model_name: deepseek-chat
  api_base: "https://api.deepseek.com/v1"
  api_key_name: deepseek
  can_stream: true
  vision: true
  supports_schema: true

5. 对 Prompt Injection 的坦诚

与许多 AI 工具不同,LLM 在文档中明确警告了 Tool 使用场景下的 Prompt Injection 风险。这种坦诚的态度对于建立用户信任至关重要。

实战场景

场景一:代码审查管道

bash 复制代码
# 在 CI/CD 中自动审查代码变更
git diff main | llm -s "Review this code change. Focus on:
1. Security vulnerabilities
2. Performance issues
3. Code style problems
Output as bullet points." -m gpt-4.1-mini

场景二:文档批量提取结构化数据

python 复制代码
import llm, json, glob

model = llm.get_model("gpt-4.1-mini")

for file in glob.glob("contracts/*.txt"):
    with open(file) as f:
        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))

场景三:构建语义搜索系统

bash 复制代码
# 1. 批量嵌入文档
llm embed-multi knowledge-base -m text-embedding-3-small \
  --files docs/ '*.md' --store

# 2. 语义搜索
llm similar knowledge-base -c "how to configure authentication"

# 3. 结合 RAG 工具
llm install llm-tools-rag
llm -T rag "What does the documentation say about API keys?"

场景四:带工具的智能助手

python 复制代码
import llm

def calculate(expression: str) -> str:
    """Evaluate a mathematical expression safely."""
    import ast
    try:
        result = eval(compile(ast.parse(expression, mode='eval'), '', 'eval'))
        return str(result)
    except Exception as e:
        return f"Error: {e}"

def search_docs(query: str) -> str:
    """Search the documentation for relevant information."""
    # 自定义搜索逻辑
    return search_internal_docs(query)

model = llm.get_model("gpt-4.1")
conversation = model.conversation(tools=[calculate, search_docs])

while True:
    user_input = input("> ")
    if user_input.lower() in ('exit', 'quit'):
        break
    response = 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。

局限与权衡

  1. 同步模型的阻塞问题 :虽然 0.18 版本引入了异步支持,但并非所有插件都实现了 AsyncModel,在异步上下文中使用同步模型仍会阻塞事件循环
  2. Token 计费追踪粒度有限 :虽然有 response.usage() 和 SQLite 日志,但缺少按项目、按标签维度的成本聚合能力
  3. 没有内置的 Agent 编排 :LLM 提供了 model.chain()Toolbox,但没有 LangChain 那样的 Agent 编排框架(如 ReAct、Plan-and-Execute)
  4. Windows 体验弱于 Unix:管道、文件路径、终端交互在 Windows 上偶尔会遇到兼容性问题
  5. Schema 支持依赖模型能力:结构化输出需要模型本身支持,并非所有模型都能可靠地遵循 Schema

总结

simonw/llm 是一个在 AI 工具生态中占据独特位置的项目。它不是另一个 LangChain,也不是另一个 Ollama------它是连接终端和大语言模型之间最直接的那座桥梁。

三个层面的价值:

  • 工具层面:一条命令访问任何模型,管道友好的输入输出,SQLite 完整审计
  • 平台层面:成熟的插件系统、模板共享、Schema/Tool/Fragment 三大扩展机制
  • 哲学层面:Unix 哲学在 AI 时代的实践------简单、可组合、可编程

如果你是经常在终端工作的开发者,如果你厌倦了在不同 AI 网页之间切换,如果你想用脚本自动化 AI 工作流------LLM 值得一试。

bash 复制代码
pip install llm && llm keys set openai && llm "Why should developers use CLI tools for AI?"

参考链接:

相关推荐
ZRS的AI笔记1 小时前
AI Agent 工具链演进:从框架混战到协议标准化
人工智能
ZhengEnCi1 小时前
LLM01-大模型API调用平台性价比深度分析
llm
K姐研究社1 小时前
OiiOii 2.0 实测 – 智能画布实现 AI 视频创作自动化
运维·人工智能·自动化
掘金一周1 小时前
裁员了,公司很爽快,赔偿一分没少 | 沸点周刊 7.8
前端·人工智能·后端
lpfasd1231 小时前
2026年第27周科技社区趋势周报
github
yaoyouzhong1 小时前
GPT-Image-2 文生图:产品场景提示词撰写指南
人工智能
+wacyltd大模型备案算法备案1 小时前
大模型评估测试题库怎么建?风险分类、测试样本的完整方法
人工智能·算法·安全·分类·大模型·大模型备案·大模型上线登记
DonngZH1 小时前
【大模型、工程实践】LLM Wiki 实战:用 6 份行业报告 PDF 构建一个能跨文档问答的知识库
人工智能
Token观测者1 小时前
AGENT实例-智能体量化交易真相:告别算命,拥抱信息差
人工智能·agent skills·agent自进化·agnet实例