随着人工智能技术的飞速发展,AI应用的交互性和实用性越来越受到关注。为了满足用户对AI应用的多样化需求,博查AI开放平台与Ollama、OpenWebUI的结合,为开发者提供了一个强大的本地部署解决方案。本文将详细介绍如何在Ollama + OpenWebUI环境中集成博查联网搜索能力,实现一个功能强大的AI应用。

博查AI开放平台简介

博查是一个专为AI应用设计的世界知识搜索引擎,能够为AI Agents、AI Chatbots、AI Search以及各类RAG应用提供干净、准确、高质量的搜索结果。博查AI开放平台提供了Web Search API、Semantic Reranker API等搜索服务,支持多模态混合搜索与语义排序技术,适用于线上应用或数据冷启动。其数据安全、成本控制及内容合规性表现卓越,确保数据不出海并符合国内安全规范。

Ollama本地部署

Ollama是一款用于本地部署和定制大型语言模型的工具,简化了模型的创建、运行和管理过程。它提供了丰富的预构建模型库,方便用户集成到不同应用中。以下是Ollama的本地部署步骤:

下载与安装

以Windows为例,下载并运行OllamaSetup.exe完成安装。

检验安装

打开终端,输入以下命令检验Ollama是否正确安装:

bash复制

ollama

若安装成功,将显示Ollama的版本信息和帮助信息。

模型选择与下载

Ollama支持多种模型,可在library上查看。以deepseek-r1为例,运行以下命令下载并运行模型:

bash复制

ollama pull deepseek-r1:1.5b
ollama run deepseek-r1:1.5b

Ollama常用指令

  • 启动Ollama服务:ollama serve

  • 下载模型:ollama pull [模型名称]

  • 运行模型:ollama run [模型名称]

  • 查看本地模型列表:ollama list

  • 删除本地模型:ollama rm [模型名称]

  • 查看运行中的模型:ollama ps

  • 复制本地模型:ollama cp [源模型名称] [目标模型名称]

OpenWebUI本地部署

OpenWebUI是一个功能丰富的自托管AI平台,支持Ollama和OpenAI兼容API。以下是OpenWebUI的本地部署步骤:

环境准备

确保使用Python 3.11以避免兼容性问题。

下载代码

bash复制

git clone https://github.com/BochaAI/open-webui-Bocha.git
cd open-webui-Bocha/

配置文件

.env.example复制一份并重命名为.env

构建后端环境

bash复制

conda create --name webui python=3.11
conda activate webui
cd ./backend
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt -U

构建前端环境

bash复制

cd ../
npm config set registry=https://registry.npmmirror.com
npm i
npm run build

启动OpenWebUI

进入open-webui-Bocha/backend目录,根据操作系统执行以下命令:

  • Linux

    bash复制

    bash start.sh
  • Windows

    bash复制

    start_windows.bat

若启动时出现端口占用问题,可通过以下命令解决:

bash复制

netstat -aon | findstr 8080
taskkill /F /PID [PID]

启动成功后,访问http://localhost:8080即可使用OpenWebUI。

集成博查联网搜索

获取博查API Key

访问博查AI开放平台 | Search API, Reranker API,登录后获取API Key。

配置联网搜索

在OpenWebUI的管理员面板中,进入设置 -> 联网搜索,选择bocha并输入API Key,保存设置。

启用联网搜索

在对话中启用联网搜索功能,即可在当前对话中使用博查的联网搜索能力。

现有OpenWebUI源码修改以支持博查搜索

若已部署OpenWebUI,可通过以下步骤修改源码以支持博查搜索:

修改配置文件

./config.py的第1639行后添加:

Python复制

BOCHA_SEARCH_API_KEY = PersistentConfig(
    "BOCHA_SEARCH_API_KEY",
    "rag.web.search.bocha_search_api_key",
    os.getenv("BOCHA_SEARCH_API_KEY", ""),
)

修改后端代码

./backend/open_webui/main.py的第182行后添加:

Python复制

BOCHA_SEARCH_API_KEY,

在第516行后添加:

Python复制

app.state.config.BOCHA_SEARCH_API_KEY = BOCHA_SEARCH_API_KEY

添加博查搜索模块

./backend/open_webui/retrieval/web目录下新建bocha.py文件,内容如下:

Python复制

import logging
from typing import Optional

import requests
import json
from open_webui.retrieval.web.main import SearchResult, get_filtered_results
from open_webui.env import SRC_LOG_LEVELS

log = logging.getLogger(__name__)
log.setLevel(SRC_LOG_LEVELS["RAG"])

def _parse_response(response):
    result = {}
    if "data" in response:
        data = response["data"]
        if "webPages" in data:
            webPages = data["webPages"]
            if "value" in webPages:
                result["webpage"] = [
                    {
                        "id": item.get("id", ""),
                        "name": item.get("name", ""),
                        "url": item.get("url", ""),
                        "snippet": item.get("snippet", ""),
                        "summary": item.get("summary", ""),
                        "siteName": item.get("siteName", ""),
                        "siteIcon": item.get("siteIcon", ""),
                        "datePublished": item.get("datePublished", "") or item.get("dateLastCrawled", ""),
                    }
                    for item in webPages["value"]
                ]
    return result

def search_bocha(
    api_key: str, query: str, count: int, filter_list: Optional[list[str]] = None
) -> list[SearchResult]:
    """Search using Bocha's Search API and return the results as a list of SearchResult objects.

    Args:
        api_key (str): A Bocha Search API key
        query (str): The query to search for
    """
    url = "https://api.bochaai.com/v1/web-search?utm_source=ollama"
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    
    payload = json.dumps({
        "query": query,
        "summary": True,
        "freshness": "noLimit",
        "count": count
    })

    response = requests.post(url, headers=headers, data=payload, timeout=5)
    response.raise_for_status()
    results = _parse_response(response.json())
    print(results)
    if filter_list:
        results = get_filtered_results(results, filter_list)

    return [
        SearchResult(
            link=result["url"], 
            title=result.get("name"), 
            snippet=result.get("summary")
        )
        for result in results.get("webpage", [])[:count]  
    ]

修改路由文件

./backend/open_webui/routers/retrieval.py中进行以下修改:

  • 第47行后添加:

    Python复制

    from open_webui.retrieval.web.bocha import search_bocha
  • 第381行后添加:

    Python复制

    app.state.config.BOCHA_SEARCH_API_KEY = BOCHA_SEARCH_API_KEY
  • 第526行后添加:

    Python复制

    request.app.state.config.BOCHA_SEARCH_API_KEY = (
        form_data.web.search.bocha_search_api_key
    )
  • 第590行后添加:

    Python复制

    "bocha_search_api_key": request.app.state.config.BOCHA_SEARCH_API_KEY,
  • 第1171行后添加:

    Python复制

    elif engine == "bocha":
        if request.app.state.config.BOCHA_SEARCH_API_KEY:
            return search_bocha(
                request.app.state.config.BOCHA_SEARCH_API_KEY,
                query,
                request.app.state.config.RAG_WEB_SEARCH_RESULT_COUNT,
                request
Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐