所有文章 > 日积月累 > OpenRouter 使用指南
OpenRouter 使用指南

OpenRouter 使用指南

大型语言模型的快速发展为多个领域带来了深远影响,尤其是在自然语言处理和图像识别领域。然而,对于许多开发者来说,部署和使用这些高性能模型仍然面临着硬件和技术上的挑战。OpenRouter 作为一种中间代理商,提供了多种开源大模型的 API 接口,让开发者能够在不拥有高性能 GPU 的情况下使用这些模型。

什么是 OpenRouter

OpenRouter 是一个整合了多种大模型的中间代理商,可以通过 API 调用超过 100 种优秀的大模型。这些模型涵盖了多个领域的应用,包括 OpenAIChatGPT 系列、AnthropicClaude 系列、以及谷歌的 PaLMGemini 系列等。在国内访问 OpenRouter 不需要额外的网络工具,这为国内开发者带来了极大的便利。

OpenRouter 的模型支持

OpenRouter 提供了多种免费的 7B 规模大小的模型,比如 nous-capybara-7bmistral-7b-instructgemma-7b-it 等。这些模型的选择使得开发者在没有高性能 GPU 服务器时,也能有效搭建自己的大模型助手。使用前需要先在 OpenRouter 注册账号,并生成 API key。

如何使用 OpenRouter

使用 OpenRouter 调用模型非常简单,开发者可以使用任何支持 HTTP 的语言和框架。例如,使用 Python 调用 gemma-7b 模型只需简单的几行代码。

import requests
import json

url = "https://openrouter.ai/api/v1/chat/completions"
model = "google/gemma-7b-it:free"
request_headers = {
    "Authorization": "Bearer 你的api_key",
    "HTTP-Referer": "http://localhost:8088",
    "X-Title": "test"
}
default_prompt = "You are an AI assistant that helps people find information."

def llm(user_prompt,system_prompt=default_prompt):
    messages = [
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": user_prompt},
    ]
    request_json = {
        "model": model,
        "messages": messages,
        "max_tokens": 2048
    }
    response = requests.request(
        url=url,
        method="POST",
        json=request_json,
        headers=request_headers
    )
    return json.loads(response.content.decode('utf-8'))['choices'][0]['message']['content']

if __name__ == '__main__':
    print(llm("你好,介绍一下你自己"))

使用 OpenAI 客户端调用模型

除了直接使用 HTTP 请求,OpenRouter 也支持通过 OpenAI 的客户端调用模型。这种方式可以让开发者更方便地管理调用流程。

from openai import OpenAI

model = "google/gemma-7b-it:free"
default_prompt = "You are an AI assistant that helps people find information."
client = OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key="你的api_key",
)

def llm(user_prompt, system_prompt=default_prompt):
    messages = [
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": user_prompt},
    ]
    completion = client.chat.completions.create(
        extra_headers={
            "HTTP-Referer": "http://localhost:8088",
            "X-Title": "test",
        },
        model=model,
        messages=messages,
        max_tokens = 2048
    )
    return completion.choices[0].message.content

if __name__ == '__main__':
    print(llm("你好,介绍一下你自己"))

搭建自己的大模型助手

通过 OpenRouter 的便利性,开发者可以轻松地搭建一个大模型助手。以下是一个简单的实现示例,后端使用 Python + Tornado 实现 Web 服务,前端使用基本的 HTML + jQuery

服务端搭建

首先,我们需要安装必要的依赖:

openai==0.27.8
tornado==6.3.2

接着,创建服务端接口 server.py,用于处理用户请求并返回模型的结果。

from tornado.concurrent import run_on_executor
from tornado.web import RequestHandler
import tornado.gen
from openai import OpenAI
import json

class Assistant(RequestHandler):
    model = "google/gemma-7b-it:free"
    client = OpenAI(
        base_url="https://openrouter.ai/api/v1",
        api_key="你的api_key",
    )
    default_prompt = "You are an AI assistant that helps people find information."

    def prepare(self):
        self.executor = self.application.pool

    def set_default_headers(self):
        self.set_header('Access-Control-Allow-Origin', "*")
        self.set_header('Access-Control-Allow-Headers', "Origin, X-Requested-With, Content-Type, Accept")
        self.set_header('Access-Control-Allow-Methods', "GET, POST, PUT, DELETE, OPTIONS")

    @tornado.gen.coroutine
    def post(self):
        json_data = json.loads(self.request.body)
        if 'questions' not in json_data or 'history' not in json_data:
            self.write({
                "code": 400,
                "message": "缺少必填参数"
            })
            return
        questions = json_data['questions']
        history = json_data['history']
        result = yield self.do_handler(questions, history)
        self.write(result)

    @run_on_executor
    def do_handler(self, questions, history):
        try:
            answer, history = self.llm(questions, history)
            return {
                "code": 200,
                "message": "success",
                "answer": answer,
                "history": history
            }
        except Exception as e:
            return {
                "code": 400,
                "message": str(e)
            }

    def llm(self, user_prompt, messages, system_prompt=default_prompt):
        if not messages:
            messages = []
        messages.append({"role": "user", "content": user_prompt})
        completion = self.client.chat.completions.create(
            extra_headers={
                "HTTP-Referer": "http://localhost:8088",
                "X-Title": "test",
            },
            model=self.model,
            messages=messages,
            max_tokens=2048
        )
        answer = completion.choices[0].message.content
        messages.append({"role": "assistant", "content": answer})
        return answer, messages

前端搭建

前端部分需要一个简单的聊天界面,使用 HTMLjQuery 实现。模型返回的数据需要解析成 HTML 格式以便展示。




    
    AI 聊天对话
    
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 0;
        }

        .container {
            display: flex;
            height: 100vh;
        }

        .left-panel {
            flex: 15%;
            background-color: #f2f2f2;
            padding: 10px;
        }

        .right-panel {
            flex: 85%;
            background-color: #ffffff;
            display: flex;
            flex-direction: column;
        }

        .chat-log {
            flex: 1;
            overflow-y: auto;
            padding: 20px;
        }

        .chat-bubble {
            display: flex;
            align-items: center;
            margin-bottom: 10px;
        }

        .user-bubble {
            justify-content: flex-end;
        }

        .bubble-content {
            padding: 10px 15px;
            border-radius: 20px;
        }

        .user-bubble .bubble-content {
            background-color: #d6eaff;
            color: #000000;
        }

        .ai-bubble .bubble-content {
            background-color: #e5ece7;
            color: #000;
        }

        .input-area {
            display: flex;
            align-items: center;
            padding: 20px;
        }

        .input-text {
            flex: 1;
            padding: 10px;
            margin-right: 10px;
        }

        .submit-button {
            padding: 10px 20px;
            background-color: #2196f3;
            color: #ffffff;
            border: none;
            cursor: pointer;
        }

        li {
            margin-top: 10px;
        }

        a {
            text-decoration: none;
        }

        table {
            border: 1px solid #000;
            border-collapse: collapse;
        }

        table td, table th {
            border: 1px solid #000;
        }

        table td, table th {
            padding: 10px;
        }

        .language-sql {
            width: 95%;
            background-color: #F6F6F6;
            padding: 10px;
            font-weight: bold;
            border-radius: 5px;
            word-wrap: break-word;
            white-space: pre-line;
            /* overflow-wrap: break-word; */
            display: block;
        }

        select {
            width: 100%;
            height: 30px;
            border: 2px solid #6089a4;
            font-size: 15px;
            margin-top: 5px;
        }
        .recommendation{
            color: #1c4cf3;
            margin-top: 10px;
        }

    


智能问答助手

常用问题

帮我写一个Java快速排序
Java 8有什么新特性
JVM优化建议
内存占用高,如何优化
MySQL优化建议
MySQL如何查看执行计划
// 聊天历史记录 var messageHistory = []; // 添加AI信息 function addAIMessage(message) { $("#chat-log").append( "
n" + "
" + message + "
n" + "
" ) } // 添加人类信息 function addUserMessage(message) { $("#chat-log").append( "
n" + "
" + message + "
n" + "
" ) } // 滑动到底部 function slideBottom() { let chatlog = document.getElementById("chat-log"); chatlog.scrollTop = chatlog.scrollHeight; } // 调用api function chatApi(message) { slideBottom(); data = { questions: message, history: messageHistory }; $.ajax({ url: "http://127.0.0.1:8081/assistant", type: "POST", contentType: "application/json", dataType: "json", data: JSON.stringify(data), success: function (res) { if (res.code === 200) { let answer = res.answer; answer = marked.parse(answer); addAIMessage(answer); messageHistory = res.history; } else { addAIMessage("服务接口调用错误。"); } }, error: function (e) { addAIMessage("服务接口调用异常。"); } }); } // 发送消息 function sendMessage() { let userInput = $('#user-input'); let userMessage = userInput.val(); if (userMessage.trim() === '') { return; } userInput.val(""); addUserMessage(userMessage); chatApi(userMessage); } // 清空聊天记录 function clearChat() { $("#chat-log").empty(); messageHistory = []; addAIMessage("你好,请输入你想问的问题。"); } // 初始化 function init() { addAIMessage("你好,请输入你想问的问题。"); var submit = $("#submit"); var userInput = $("#user-input"); var focus = false; // 监听输入框焦点 userInput.focus(function () { focus = true; }).blur(function () { focus = false; }); // 回车监听事件 document.addEventListener("keydown", function (event) { if (event.keyCode === 13) { console.log(focus); if (focus) { submit.click(); } } }); } init();

解决常见问题

在使用 OpenRouterTornado 搭建服务时,可能会遇到一些常见问题,比如服务接口调用异常。这通常是由于跨域请求预检(OPTIONS 请求)未正确处理导致的。解决方案是确保服务器正确处理 OPTIONS 请求,设置 CORS 策略。

修改后的代码示例

server.py 中添加 OPTIONS 请求的处理:

from tornado.concurrent import run_on_executor
from tornado.web import RequestHandler
import tornado.gen
from openai import OpenAI
import json

class Assistant(RequestHandler):
    model = "google/gemma-7b-it:free"
    client = OpenAI(
        base_url="https://openrouter.ai/api/v1",
        api_key="你的api_key",
    )
    default_prompt = "You are an AI assistant that helps people find information."

    def prepare(self):
        self.executor = self.application.pool

    def set_default_headers(self):
        self.set_header('Access-Control-Allow-Origin', "*")
        self.set_header('Access-Control-Allow-Headers', "Origin, X-Requested-With, Content-Type, Accept")
        self.set_header('Access-Control-Allow-Methods', "GET, POST, PUT, DELETE, OPTIONS")

    @tornado.gen.coroutine
    def post(self):
        json_data = json.loads(self.request.body)
        if 'questions' not in json_data or 'history' not in json_data:
            self.write({
                "code": 400,
                "message": "缺少必填参数"
            })
            return
        questions = json_data['questions']
        history = json_data['history']
        result = yield self.do_handler(questions, history)
        self.write(result)

    @run_on_executor
    def do_handler(self, questions, history):
        try:
            answer, history = self.llm(questions, history)
            return {
                "code": 200,
                "message": "success",
                "answer": answer,
                "history": history
            }
        except Exception as e:
            return {
                "code": 400,
                "message": str(e)
            }

    def llm(self, user_prompt, messages, system_prompt=default_prompt):
        if not messages:
            messages = []
        messages.append({"role": "user", "content": user_prompt})
        completion = self.client.chat.completions.create(
            extra_headers={
                "HTTP-Referer": "http://localhost:8088",
                "X-Title": "test",
            },
            model=self.model,
            messages=messages,
            max_tokens=2048
        )
        answer = completion.choices[0].message.content
        messages.append({"role": "assistant", "content": answer})
        return answer, messages

    def options(self):
        # No body
        self.set_status(204)
        self.finish()

FAQ

  1. 问:如何获取 OpenRouter 的 API key?

  2. 问:使用 OpenRouter 是否需要支付费用?

    • 答:OpenRouter 提供多种免费的 7B 模型,用户可以根据需求选择免费或付费版本。
  3. 问:如何处理跨域请求问题?

    • 答:在使用 Tornado 搭建服务时,确保正确设置 Access-Control-Allow-OriginAccess-Control-Allow-Methods 响应头,并处理 OPTIONS 请求。
  4. 问:OpenRouter 支持哪些编程语言?

    • 答:OpenRouter 支持任何能够发起 HTTP 请求的编程语言,包括 Python、JavaScript、Java 等。
  5. 问:如何更换模型?

    • 答:更换模型只需修改 API 调用中的模型名称,无需更改代码逻辑。

通过上述方式,我们可以在不具备高性能硬件的情况下,快速搭建一个基于大模型的智能助手,极大地降低了使用门槛。OpenRouter 的出现为开发者提供了更多的可能性,也推动了 AI 应用的普及。

#你可能也喜欢这些API文章!