Qdrant 是一个用 Rust 编写的开源向量数据库,提供向量相似度检索、payload 元数据过滤、分布式分片与副本等生产级能力。它解决的问题很具体:当 RAG、语义搜索、推荐召回需要在上亿向量中做「语义最相似」查询,同时还要按业务字段(用户、部门、类目、价格)过滤时,Elasticsearch 的关键词匹配无法覆盖语义相似,而 FAISS 这类算法库又缺少持久化、过滤与多语言 API。Qdrant 把「近似最近邻检索 + 业务过滤 + 持久化存储」合体现在一个服务里,以 REST/gRPC 接口对外提供,并配套 Python、Go、TypeScript 等官方 SDK。它的设计主线是从「可用的向量检索引擎」逐步演进为「搜索与过滤并重的生产级向量数据库」,这也是它与 Milvus、Weaviate、Pinecone 等同类产品最核心的差异。本文按速览、安装、上手、核心能力、生产部署、选型对比、应用场景、常见误区与面试题的结构展开,目标是让读者在 30 分钟内完成从安装到第一个检索查询。

岗位关联

职业价值:向量数据库是 RAG 与语义检索应用的核心基础设施,掌握 Qdrant 的建库、过滤、量化和部署方法,是从 demo 级原型走向生产级检索服务的必备选型能力。

目录
  1. 为什么需要 Qdrant:从「近似搜索库」到「生产级向量数据库」
  2. 安装与环境配置:3 步就绪
  3. 快速上手:10 分钟跑通「建库-写入-检索」
  4. 核心能力详解:5 大支柱
  5. 生产部署与监控:从上线到运维
  6. 版本迭代
  7. AI 应用场景
  8. 常见误区
  9. 面试题
  10. 参考来源
工具类型
开源向量数据库(近似最近邻检索 + 持久化存储)
开发商
Qdrant 公司(开源社区驱动)
开源协议
Apache License 2.0(可商用)
GitHub Stars
主要语言
Rust(服务端);Python/Go/TS 等官方 SDK
当前版本
v1.15.x(2025-02 发布)
安装方式
Docker / 预编译二进制 / pip install qdrant-client
下载地址
上手难度
★★☆☆☆(低)
适合人群
RAG / 语义搜索 / 推荐系统工程师
同类工具
Milvus · Weaviate · Pinecone · Chroma
托管服务
无

速览卡是工具类内容的固定首屏模块:30 秒判断「这工具是什么、能不能商用、适不适合我」。

为什么需要 Qdrant:从「近似搜索库」到「生产级向量数据库」

在 Qdrant 出现之前,工程团队做语义检索通常只有两类选择。一类是 FAISS、Annoy 这类近似最近邻(ANN,Approximate Nearest Neighbor,即不追求绝对精确、只求「足够接近」的近邻检索)算法库:检索快,但数据只存在于内存中,没有持久化、没有条件过滤、没有服务化 API,从「算出 Top-K」到「上线给业务调用」之间还隔着存储、并发、容灾一大堆自研工作。另一类是直接用 Elasticsearch 做语义扩展:倒排索引擅长关键词精确匹配,但在语义相似(同义改写、跨语言)上先天不足。两类方案都无法同时满足「语义检索 + 业务过滤 + 生产可用」三个条件。

Qdrant 把向量索引、payload 过滤、持久化存储、分片复制、监控指标打包成一个独立服务。payload 是附加在向量上的业务元数据(如用户 ID、类目、价格),Qdrant 允许在向量检索的同时按这些字段过滤,且过滤在索引内部完成(pre-filter),避免「先检索后过滤」导致的高分结果被丢弃。Rust 实现带来高并发与可控的内存占用;官方 SDK(Python、Go、TS/JS、Rust 等)屏蔽了 HTTP/gRPC 细节;API 在单机到集群的不同部署规模下保持一致。因此 Qdrant 常被选为 RAG 管道的默认向量存储。

与 LangChain 这类编排框架相比,Qdrant 只负责「存储 + 检索」这一层,职责单一、接口稳定;与 Milvus 相比,Qdrant 单机起步更轻、分布式组件更少;与 Pinecone 相比,它完全开源可自托管。它代表的是「检索与过滤并重」的技术路线,而不是「纯向量相似度」的简易包装。

安装与环境配置:3 步就绪

步骤一:Docker 方式(推荐)。拉取镜像并启动,容器暴露两个端口:6333 是 REST API,6334 是 gRPC。生产环境务必用 -v 挂载持久化卷,容器内数据目录为 /qdrant/storage,否则容器重建后数据丢失。启动后可访问 http://localhost:6333/dashboard 打开内置管理界面。

步骤二:二进制方式。适合没有 Docker 的生产服务器。从 GitHub Releases 下载对应平台的预编译压缩包,解压后目录内自带 config/config.yaml,直接执行 ./qdrant 即可,默认读取同目录配置。

步骤三:安装客户端并验证。Python 客户端是 qdrant-client 包;服务是否就绪用 GET /healthz 检查,返回 ok 即正常。

bash13 行
# 1. Docker 方式(推荐)docker run -d --name qdrant \  -p 6333:6333 -p 6334:6334 \  -v "$(pwd)/qdrant_storage:/qdrant/storage" \  qdrant/qdrant # 2. 二进制方式(Linux x86_64)curl -L https://github.com/qdrant/qdrant/releases/latest/download/qdrant-x86_64-unknown-linux-gnu.tar.gz -o qdrant.tar.gztar xzf qdrant.tar.gz && cd qdrant && ./qdrant # 3. 客户端安装与验证pip install qdrant-clientcurl http://localhost:6333/healthz

快速上手:10 分钟跑通「建库-写入-检索」

最小可用流程只有四步:连接客户端 → 创建 collection(集合,即一组向量的容器)→ upsert(写入或更新)带向量与 payload 的数据点 → search 检索。核心概念是:collection 在创建时就固定了向量维度(size)与距离度量(distance),之后不可修改,所以第一步必须先确定 embedding 模型的输出维度。

1. 创建 collection:在 Python 中指定 VectorParams(size=768, distance=Distance.COSINE),768 要与你使用的 embedding 模型输出维度一致;文本语义检索默认用 Cosine(余弦相似度)。

2. 写入数据:upsert 每个点包含 id(唯一标识)、vector(浮点数组)、payload(业务元数据字典)。

3. 执行检索:search 传入查询向量、过滤条件与返回数量,返回结果按相似度降序。

4. 进阶技巧:在 search 的 query_filter 中按 payload 字段过滤,即可实现「先过滤再检索」的复合查询。

执行后你会看到 id=2 的结果排在前面,且只返回 category="ai" 的点,说明「向量排序 + payload 过滤」在同一次查询内完成。这就是 Qdrant 和纯检索库最直观的差别。

python29 行
from qdrant_client import QdrantClientfrom qdrant_client.models import Distance, VectorParams, Filter, FieldCondition, MatchValue client = QdrantClient(host="localhost", port=6333) # 1. 创建 collection(维度与 embedding 模型输出对齐)client.create_collection(    collection_name="articles",    vectors_config=VectorParams(size=768, distance=Distance.COSINE),) # 2. 写入数据(向量 + 业务元数据)client.upsert(    collection_name="articles",    points=[        {"id": 1, "vector": [0.1] * 768, "payload": {"category": "tech", "views": 1200}},        {"id": 2, "vector": [0.2] * 768, "payload": {"category": "ai", "views": 3400}},    ],) # 3. 检索:语义相似 + 按 category 过滤hits = client.search(    collection_name="articles",    query_vector=[0.15] * 768,    query_filter=Filter(must=[FieldCondition(key="category", match=MatchValue(value="ai"))]),    limit=5,)for hit in hits:    print(hit.id, hit.score, hit.payload)  # score 为相似度分数,越大越相似

核心能力详解:5 大支柱

支柱一:HNSW 索引与多种距离度量。Qdrant 默认使用 HNSW(分层可导航小世界图,一种通过多层图结构做近似最近邻检索的索引),在召回率与查询延迟之间取得平衡,可通过 m、ef_construct、ef 三个参数调节「内存 vs 精度」。支持四种距离度量:Cosine(余弦,文本语义检索默认)、Dot(点积,适合已归一化向量与推荐打分)、Euclid(欧氏距离)、Manhattan(曼哈顿距离,用于低维特征或特殊业务距离)。距离度量在创建 collection 时选定,之后不可更改。

支柱二:payload 过滤与复合查询。每个向量可携带任意 JSON payload,Qdrant 为 payload 字段建立独立索引,支持数值范围、字符串匹配、标签集合、嵌套对象以及地理位置过滤(圆形、矩形、多边形)。过滤与向量检索在同一次查询内执行,是 pre-filter 而非后置过滤,因此不会因过滤截断而丢失高相关结果。

支柱三:量化与内存控制。标量量化(scalar quantization)把 float32 向量压为 int8,内存降约 4 倍;二进制量化(binary quantization)压到 1 bit,向量部分内存再降一个数量级。量化会损失召回率,可配合 oversampling(过采样,即检索时多取候选再重排)补偿。这一能力让千万级向量在单节点上运行成为现实。

支柱四:多向量与混合检索。支持 named vectors(一个点存多个命名向量,例如同时存标题向量与正文向量)。自 1.12 起支持全文稀疏向量(基于 BM25 的稀疏表示),可与稠密向量做混合检索,用 RRF(倒数排名融合,把多个检索结果按排名倒数加权合并)或加权和融合,同时兼顾语义相似与精确关键词匹配——这对 RAG 中「专有名词必须精确命中」的场景尤其关键。

支柱五:分布式与运维原生能力。collection 可拆分为多个分片(shard),每个分片配置多个副本;分片分发策略支持基于 payload 字段的 hash 与自定义 key。内置快照(snapshot)备份与恢复、集合别名、Prometheus /metrics 指标端点。最核心的特性是 API 不随部署规模变化:单机进程与多节点集群使用同一套接口,迁移成本低。

生产部署与监控:从上线到运维

方式一:Docker Compose 单机部署。这是大多数团队的第一站,但生产环境必须补三件事:挂载持久化卷(容器内 /qdrant/storage)、配置 restart 策略、限制容器资源。一个最小可用的 compose 配置如下,./qdrant_storage 会落在宿主机上,容器重建不丢数据。

方式二:Kubernetes / Helm 与 Qdrant Cloud。需要水平扩展时,官方 Helm chart 支持分片副本、持久卷声明与水平扩缩容;Qdrant Cloud 则提供全托管与混合云部署,把升级、备份、监控全部外包。选型依据很简单:团队有 7×24 运维能力的选自托管,没有则优先托管服务;日向量查询量在千万级以下,单机 + 量化通常已经够用。

可观测性。Qdrant 在 6333 端口暴露 /metrics,输出 Prometheus 格式指标(向量点数、分片状态、请求延迟直方图),接入 Prometheus 后可用 Grafana 展示;健康检查使用 GET /healthz 与 GET /livez;日志默认 JSON 格式便于采集。备份策略建议用快照 API 定期导出到对象存储,而不是直接拷贝数据目录。

<p class="para-label">避坑清单:</p>

<ul class="dash-list"><li>生产环境不挂载持久化卷:Docker 容器默认数据写在容器内层,重启或重建即全部丢失;务必挂载 /qdrant/storage,并对卷做独立备份。</li><li>向量维度与距离度量创建后不可修改:建 collection 时若 size 设错,只能删除重建并重灌数据;先确认 embedding 模型输出维度,再决定 384/768/1536 等取值。</li><li>升级版本前先做快照与恢复演练:Qdrant 快照在同版本恢复最可靠,跨大版本恢复前必须在测试环境验证,降级方向尤其危险。</li></ul>

yaml9 行
services:  qdrant:    image: qdrant/qdrant:latest    ports:      - "6333:6333"      - "6334:6334"    volumes:      - ./qdrant_storage:/qdrant/storage    restart: unless-stopped
维度QdrantMilvusWeaviatePinecone
定位Rust 开源向量数据库,检索与过滤并重Go/C++ 开源分布式向量数据库Go 开源向量数据库,内建知识图谱全托管向量数据库 SaaS
部署形态单机二进制 / Docker / K8s / 云Milvus Lite 单机 / Docker / 分布式Docker / K8s / 嵌入式模块纯托管,无自托管选项
过滤能力强:嵌套过滤、全文索引、地理过滤、复合条件中:标量字段过滤中:class 属性过滤 + GraphQL 查询中:metadata 过滤
存储压缩标量/二进制量化 + oversampling量化 + MMap,组件多PQ 压缩自动索引,细节不可控
混合检索稀疏向量 + 加权/RRF 融合稀疏稠密混合(v2.4+)多向量 late fusion部分支持
学习曲线低:一套 API 从单机到集群中:coordinator/query/index 组件多中:需熟悉 GraphQL 语法低:API 简单
LicenseApache 2.0Apache 2.0BSD-3-Clause商业
适合谁RAG / 搜索 / 推荐团队超大规模分布式、Deep K8s 团队语义搜索 + 知识图谱场景快速原型、无运维团队

选型建议:单机起步、强调 payload 过滤与混合检索的 RAG 项目,优先选 Qdrant;已有成熟 K8s 且向量规模在十亿级以上、需要弹性扩展的团队,Milvus 更合适;需要内建知识图谱和 GraphQL 语义查询的选 Weaviate;不想承担任何运维成本、追求最快上线的选 Pinecone。建议在选定前用自身数据做过滤场景压测,三个开源工具均可本地部署验证。

版本迭代

Qdrant 于 2021 年开源,2022 年在 0.x 阶段快速迭代,2023 年 7 月发布 1.0 稳定版,此后以约每月一版的节奏演进。主线清晰:从「可用的向量检索服务」→「过滤与多向量能力」→「量化与内存优化」→「稀疏向量与混合检索」,每次大版本都直接扩大可用场景边界。(截至训练数据,可能已有更新版本)

版本时间变化提升
v1.0.02023-07首个正式稳定版REST/gRPC API 转正,支持事务与快照备份,进入生产可用阶段
v1.5.02023-12过滤与查询能力增强payload 过滤能力增强,HNSW 检索性能与稳定性优化
v1.7.02024-02多向量支持每个点可存多个命名向量,支持按向量名查询与过滤
v1.10.02024-06二进制量化稳定向量内存占用压缩约一个数量级,oversampling 补偿召回率
v1.12.02024-09全文稀疏向量内置 BM25 全文检索,与稠密向量融合实现混合检索
v1.15.02025-02Agent 与混合检索增强面向 Agent 场景的检索能力强化,部署与交付体验优化
结论

本工具未发布可复现的权威第三方榜单成绩,评测数据对比表省略;公开基准多见于官方博客的内部对比,结论是过滤检索场景下 Qdrant 高并发表现突出,选型时应以自建场景压测为准。实际工程影响最大的两次迭代是 v1.10 的二进制量化(把千万级向量的内存成本降到一个数量级以下)和 v1.12 的全文稀疏向量(让关键词精确匹配与语义检索共用一套 API)。

AI 应用场景

场景一:企业级 RAG 知识库

阶段:RAG 管道构建 / 文档智能

解决的问题:RAG 要求「先按语义召回相关片段,再按租户、时间、权限过滤」,传统「全部召回后应用层过滤」的方案会丢弃被过滤掉的高分结果。Qdrant 把过滤下推到索引内完成(pre-filter),一次查询同时满足语义与权限要求;配合 payload 中的部门、可见性等级实现多租户隔离,配合稀疏向量对产品型号等专有名词做精确匹配兜底。

具体案例:某企业内部知识库将约 200 万条文档分块 embedding(768 维)写入 Qdrant,每条附带部门与更新时间的 payload;检索时按部门过滤 + 语义排序,常规生产配置下单查询 P95 延迟在数十毫秒内,整体检索耗时相比旧方案下降一个数量级。

场景二:推荐系统语义召回

阶段:向量召回 / 推荐系统

解决的问题:推荐粗排前需要从千万级物品中召回候选,纯 embedding 检索无法表达「只能推某店铺、某价格带、某地域」等业务约束。Qdrant 支持在召回阶段用 Dot 距离(适合打分排序)加 payload 过滤(店铺、价格区间、类目、上架状态)直接产出候选集,在召回阶段就剔除大部分不满足条件的物品。

具体案例:电商场景将物品 embedding(128~512 维)与店铺 ID、价格字段写入同一 collection;召回时附带店铺与价格上限过滤,单次召回延迟毫秒级,相比「全量检索后再过滤」的方案,召回候选更精准,粗排阶段的无效计算显著减少。

场景三:实时风控与异常检测

阶段:实时推理 / 流式数据处理

解决的问题:支付与登录风控需要把「当前行为」与「历史行为分布」做快速相似比较,异常点即与最近邻距离超过阈值的点。Qdrant 支持高吞吐写入与增量 upsert,行为向量可流式入库,配合时间范围过滤实现「只比较近 24 小时行为」的滑动窗口查询。

具体案例:风控团队将设备指纹与会话行为聚合为向量实时写入,查询时按时间戳过滤,与历史正常行为向量比较距离;相比每次全量计算距离的批处理方案,响应从分钟级降到百毫秒级,可支撑在线决策。

常见误区

误区直接把文本或图片传给 Qdrant,以为它会自己完成向量化并存储。

正解Qdrant 是向量存储与检索层,不负责生成 embedding。向量必须由外部模型(如 OpenAI、BGE、Cohere)生成后,通过 upsert 写入。官方提供 FastEmbed 这类客户端库来简化本地 embedding 生成,但必须在客户端显式引入;服务端默认不做任何文本向量化。

为何常见:很多向量数据库厂商宣传「端到端」,且 RAG 教程常把 embedding 模型与向量数据库混在一起讲,导致职责边界被忽略。

误区把 Qdrant 等同于 FAISS 这类纯内存算法库,认为数据重启即丢、无法水平扩展。

正解Qdrant 从设计上就是持久化数据库,向量与 payload 落在磁盘上;分布式模式支持 collection 分片(shard)与副本(replica),节点故障时副本继续提供读服务,写入通过一致性配置保证。单机进程只是最小部署单元,不是能力上限。

为何常见:大多数教程用 Docker 单容器演示,短平快的上手体验让人忽略了它完整的分布式能力。

误区embedding 模型输出 1536 维就用 1536 维,认为维度越高检索越准。

正解维度增加会带来内存与检索耗时线性增长,而召回率提升有限。正确做法是让 collection 的 size 与所选 embedding 模型的输出维度严格一致(常见 384、768、1536),并通过量化控制成本,而不是盲目追求高维。

为何常见:主流 embedding 模型普遍输出高维向量,用户误以为「模型输出就是最优配置」,忽略了维度与硬件成本的权衡。

误区payload 里存了文本字段,就以为 Qdrant 能像 Elasticsearch 一样做关键词全文检索。

正解payload 默认不建立全文索引,普通字符串匹配是精确匹配而非分词检索。需要关键词搜索时,要么在建索引时为文本字段开启 full-text index,要么使用 1.12+ 的全文稀疏向量能力;纯粹的倒排索引搜索并非 Qdrant 的设计目标。

为何常见:看到 payload 能存储任意 JSON,默认以为存储即检索,混淆了「结构化字段过滤」与「全文检索」两种能力。

误区向量数据库就是「升级版搜索引擎」,任一场景下两者随便换。

正解两者定位不同:Elasticsearch 以倒排索引为主,擅长关键词精确匹配与聚合分析;Qdrant 以向量相似度为主,擅长语义匹配与向量+元数据复合过滤。混合需求(既要语义又要精确关键词)的正确做法是使用 Qdrant 的混合检索(稠密 + 稀疏),而不是简单二选一。

为何常见:两者都叫「索引」「查询」,概念重叠多,不深入理解倒排与向量两种数据结构差异时很容易混淆。

面试题

Q1. Qdrant 服务端核心引擎主要使用哪门语言编写?

单选题 · easy

  • A.Go 语言
  • B.Rust 语言← 正确答案
  • C.Java 语言
  • D.C++ 语言

答案:B。Qdrant 服务端完全由 Rust 编写,Rust 的内存安全与高并发性能是其高吞吐检索的基石。Go 是 Weaviate 的实现语言,C++ 是 Milvus 存储层选型,Java 不在 Qdrant 技术栈中,Python 仅用于官方客户端。

Q2. Qdrant 默认使用的向量索引算法是?

单选题 · easy

  • A.HNSW 索引← 正确答案
  • B.IVF-PQ 索引
  • C.FLAT 索引
  • D.MRPT 索引

答案:A。Qdrant 默认使用 HNSW(分层可导航小世界图)索引,在召回率与查询延迟之间取得平衡。IVF-PQ 是 Milvus 等系统常见的索引类型,FLAT 是暴力扫描,MRPT 是 FAISS 的索引,均不是 Qdrant 默认选择。

Q3. 使用 Docker 启动 Qdrant 后,REST API 默认监听端口是?

单选题 · mid

  • A.6333 端口← 正确答案
  • B.6334 端口
  • C.8080 端口
  • D.9200 端口

答案:A。6333 是 REST API 端口,6334 是 gRPC 端口,两者在 Docker 启动命令中都要映射。8080 是常见 Web 服务默认端口,9200 是 Elasticsearch 的默认端口,与 Qdrant 无关。

Q4. 创建 collection 时,向量的维度(size)应如何确定?

单选题 · mid

  • A.与 embedding 模型输出维度一致← 正确答案
  • B.维度越大检索效果一定越好
  • C.与文档数量保持相同数值
  • D.任意设置一个固定常数即可

答案:A。向量维度必须与 embedding 模型输出维度严格一致(如 384、768、1536),否则查询时维度不匹配会报错。维度并非越大越好,内存与检索成本随维度线性增长,collection 创建后维度不可修改,选错只能重建。

Q5. 下列哪些距离度量属于 Qdrant 官方支持?

多选题 · mid

  • A.Cosine 距离← 正确答案
  • B.Dot 距离← 正确答案
  • C.KL 散度值
  • D.Euclid 距离← 正确答案

答案:ABD。Qdrant 的 Distance 枚举包含 Cosine、Dot、Euclid、Manhattan 四种度量。KL 散度是概率分布之间的距离度量,不在 Qdrant 支持范围内。选择哪度量取决于业务:文本语义默认 Cosine,已归一化向量的推荐打分常用 Dot。

Q6. 二进制量化(Binary Quantization)的主要作用是?

单选题 · easy

  • A.压缩向量内存占用← 正确答案
  • B.提升 embedding 模型精度
  • C.替代 HNSW 索引
  • D.扩大向量搜索范围

答案:A。二进制量化把每个向量维度压缩为 1 bit,向量内存占用可降约一个数量级,是 Qdrant 控制大规模内存成本的核心手段。它不改变 embedding 语义,也不替代 HNSW 索引,量化造成的召回损失需用 oversampling 补偿。

Q7. 关于 Qdrant 分布式部署,下列说法正确的是?

多选题 · hard

  • A.collection 可分为多个分片← 正确答案
  • B.分片可配置副本数量← 正确答案
  • C.分布式模式必须依赖 K8s
  • D.副本可提高读取可用性← 正确答案

答案:ABD。Qdrant 分布式模式下 collection 可拆分为多个分片,每个分片可设置副本数;副本在节点故障时继续提供读取,提升可用性。分布式模式不强制依赖 K8s,Docker 集群亦可运行,K8s 只是官方支持的一种部署方式。

Q8. 为 collection 创建快照的 REST API 是?

单选题 · mid

  • A.POST /collections/{name}/snapshots← 正确答案
  • B.GET /collections/{name}/snapshots
  • C.POST /snapshots/{name}/create
  • D.PUT /collections/{name}/backups

答案:A。Qdrant 的快照创建 API 是 POST /collections/{collection_name}/snapshots,返回任务 ID;GET 同路径用于列出已有快照,PUT /backups 与 /snapshots/{name}/create 都不是官方定义。快照下载则使用 /snapshots/{snapshot_name}。

Q9. 下列哪些客户端由 Qdrant 官方提供?

多选题 · easy

  • A.Python 官方 SDK← 正确答案
  • B.Go 官方 SDK← 正确答案
  • C.TS/JS 官方 SDK← 正确答案
  • D.Ruby 社区 SDK

答案:ABC。Qdrant 官方维护 Python、Go、TypeScript/JavaScript、Rust 等客户端 SDK,覆盖主流服务端语言。Ruby 客户端不在官方支持列表中,属于社区实现,官方文档也未将其列入,生产选型时应优先使用官方 SDK。

Q10. 关于 Qdrant 快照恢复,下列说法错误的是?

单选题 · hard

  • A.快照可用于数据迁移
  • B.快照保存在 storage 目录
  • C.快照只能在原节点恢复← 正确答案
  • D.快照可跨集群恢复数据

答案:C。Qdrant 快照可下载、可迁移,也可恢复到其他节点甚至其他集群,并非「只能在原节点恢复」;A、B、D 描述均正确。快照是官方推荐的备份与迁移手段,生产环境应定期导出到对象存储,并在恢复前做演练。

参考来源