Back to blog
    ollamaopenai-apilocal-modelintegrationfine-tuning

    Ollama 的 OpenAI 兼容 API:将微调模型无缝接入任何 OpenAI 集成

    Ollama 暴露 OpenAI 兼容的 REST API。任何为 OpenAI SDK 编写的代码——Langchain、LlamaIndex、你自己的应用——只需更改一个 URL 即可使用你的本地微调模型。以下是你需要知道的。

    Edward Xi Yang

    Ollama 在 http://localhost:11434/v1 上暴露了一套 OpenAI 兼容的 REST API。这意味着每一个与 OpenAI 集成的库、框架和应用,都可以只改一行代码就指向你本地的微调模型。

    不需要新的 SDK,不需要写 API 包装层。改掉 baseURL 和模型名称就可以了。

    “OpenAI 兼容”到底意味着什么

    Ollama 实现了 OpenAI Chat Completions API 的格式:

    • POST /v1/chat/completions,也就是最主要的那个端点
    • 请求体格式与 OpenAI 完全一致(model、messages、temperature、max_tokens、stream 等等)
    • 响应格式同样一致(choices、message.content、usage 等等)

    并非 OpenAI 的每一项功能都有实现。已支持的部分:

    • Chat completions(最重要的一项)
    • 通过 stream: true 实现的流式输出
    • 通过 POST /v1/embeddings 提供的向量嵌入(部分模型)
    • 通过 GET /v1/models 列出模型

    未支持的部分:

    • 通过 API 做微调(这部分你在 Ertas 里完成)
    • 图像生成
    • 语音/音频 API
    • Assistants API(那套有状态的 threads/runs 接口)
    • OpenAI 特有的功能,例如内容审核,或带严格 schema 的 JSON 模式

    就推理而言,也就是绝大多数使用场景,兼容性是完整的。

    一行代码完成迁移

    JavaScript / Node.js:

    // 迁移前(OpenAI 云端)
    import OpenAI from 'openai';
    const client = new OpenAI({
      apiKey: process.env.OPENAI_API_KEY
    });
    
    // 迁移后(Ollama 本地模型),只改一处
    import OpenAI from 'openai';
    const client = new OpenAI({
      baseURL: 'http://localhost:11434/v1',
      apiKey: 'ollama' // 必填字段,但 Ollama 不会校验它
    });
    
    // 你的生成代码完全不用动
    const response = await client.chat.completions.create({
      model: 'your-fine-tuned-model', // 这里换成你的 Ollama 模型名
      messages: [
        { role: 'user', content: 'Your prompt here' }
      ]
    });
    
    console.log(response.choices[0].message.content);

    Python:

    # 迁移前
    from openai import OpenAI
    client = OpenAI(api_key="sk-...")
    
    # 迁移后,只改一处
    from openai import OpenAI
    client = OpenAI(
        base_url="http://localhost:11434/v1",
        api_key="ollama"  # 不会被校验
    )
    
    # 生成代码保持不变
    response = client.chat.completions.create(
        model="your-fine-tuned-model",
        messages=[{"role": "user", "content": "Your prompt"}]
    )
    print(response.choices[0].message.content)

    Curl:

    # 迁移前
    curl https://api.openai.com/v1/chat/completions \
      -H "Authorization: Bearer $OPENAI_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "Hello"}]}'
    
    # 迁移后,改 URL 和模型名
    curl http://localhost:11434/v1/chat/completions \
      -H "Authorization: Bearer ollama" \
      -H "Content-Type: application/json" \
      -d '{"model": "your-fine-tuned-model", "messages": [{"role": "user", "content": "Hello"}]}'

    开箱即用的框架与库

    因为 Ollama 是 OpenAI 兼容的,以下这些除了 baseURL 之外不需要任何代码改动:

    框架/库配置方式
    LangChain(JS/Python)ChatOpenAI({ baseUrl: "http://localhost:11434/v1" })
    LlamaIndexOpenAI(api_base="http://localhost:11434/v1")
    Vercel AI SDKcreateOpenAI({ baseURL: "http://localhost:11434/v1" })
    OpenAI Agents SDK设置 OPENAI_BASE_URL 环境变量
    Instructor传入配置了 Ollama baseURL 的 OpenAI 客户端
    DSPylm = dspy.LM("ollama/your-model")
    Semantic Kernel使用自定义端点的 OpenAI 连接器
    FlowiseOpenAI 节点,覆盖 base path
    n8nOpenAI 节点,覆盖 baseURL

    只要工具支持「OpenAI 加自定义 base URL」,基本都能用。把 OpenAI 的 URL 写死在代码里的工具则不行。

    远程 Ollama 服务器

    当 Ollama 跑在 VPS 上而不是本机时,你需要把它暴露出来:

    在 VPS 上:

    # 设置了 OLLAMA_HOST 之后,Ollama 默认监听 0.0.0.0
    OLLAMA_HOST=0.0.0.0:11434 ollama serve

    安全提示: 绝对不要把 Ollama 的端口直接暴露到公网。在前面放一层 Nginx,加上基础认证或 API key 校验:

    server {
        listen 443 ssl;
        server_name ollama.yourdomain.com;
    
        location /v1/ {
            # 简单的 API key 校验
            if ($http_authorization != "Bearer your-secret-key") {
                return 401 '{"error": "Unauthorized"}';
            }
            proxy_pass http://localhost:11434/v1/;
        }
    }

    然后在代码里:

    const client = new OpenAI({
      baseURL: 'https://ollama.yourdomain.com/v1',
      apiKey: 'your-secret-key'
    });

    这样你就得到了一个完全受保护、可远程访问、并且 OpenAI 兼容的微调模型 API。Ollama 服务器部署一次,任何客户端都能调用。

    流式响应

    流式输出的用法与 OpenAI 完全相同:

    const stream = await client.chat.completions.create({
      model: 'your-fine-tuned-model',
      messages: [{ role: 'user', content: 'Generate a long document...' }],
      stream: true
    });
    
    for await (const chunk of stream) {
      process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
    }

    如果是界面类应用(Next.js 搭配 Vercel AI SDK,或者带流式渲染的 React):

    // Vercel AI SDK + Ollama
    import { createOpenAI } from '@ai-sdk/openai';
    import { streamText } from 'ai';
    
    const ollama = createOpenAI({
      baseURL: 'http://localhost:11434/v1',
      apiKey: 'ollama',
    });
    
    // 在你的 API route 中
    const result = streamText({
      model: ollama('your-fine-tuned-model'),
      messages: [...],
    });
    
    return result.toDataStreamResponse();

    流式数据的格式与 OpenAI 一致,所以你现有的流式 UI 组件不用改动就能继续用。


    延伸阅读

    就本文向 AI 提问

    Ship AI that runs on your users' devices.

    Free plan with 30 credits/mo, no card required. Paid plans from $10/mo USD.

    Keep reading