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?"

参考链接:

相关推荐
hay_lee17 小时前
Agent 时代的“TCP/IP“:多智能体协议如何重塑企业 AI 基础设施
人工智能
feelmylife5917 小时前
企业级 LLM Mass Gateway — 多租户高并发网关,真正难点是 streaming 下的配额计数
人工智能·后端
太子釢17 小时前
从零搭建一个最小的 Agent Loop
人工智能
Black蜡笔小新17 小时前
企业AI算力工作站/AI大模型训练工作站DLTM企业私有化AI视觉中台建设方案设计
人工智能
花生智源17 小时前
Java实现Prompt工程的技巧——从模板到工程化,告别字符串拼接
java·人工智能
墨虹雨茶17 小时前
Loop Engineering 正在重新定义"程序员"这个职业
人工智能
夕小瑶17 小时前
字节把 PS 做进了生图模型里,实测 Seedream 5.0 Pro 指哪改哪
人工智能
用户2959485550517 小时前
重力空间的一次实践——我做了个与众不同的本地知识库
github
量化吞吐机17 小时前
2026年AI量化工具评估,先分开学习开发和验证
人工智能·python
IvorySQL17 小时前
PG 日报|新增 VFD 缓存监控视图,精细化数据库调优
大数据·数据库·人工智能·缓存·postgresql·区块链