构建一个基于 OpenSearch 的佛教文献检索系统,支持 巴利文、中文、英文 的多语种搜索,覆盖经文、译文、字典等资源,满足以下核心需求:
三层设计 数据层,api 层 , 交互层 满足简单查询到 RAG 的不同需求
系统需要存储和检索以下资源:
字典
巴利语经文
译文
id:openSearch 唯一 IDresource_id:文档在数据库中的 ID(UUID)resource_type:文档类型(article | term | dictionary | translation | origin_text|nissaya)granularity:文档颗粒度 "book | chapter | sutta | section | paragraph | sentence"title:文档标题,可以是中文或巴利文
display:文档显示用 不搜索text: 纯文本,模糊搜索用vector: embeddingsummary:文档摘要 llm 根据 content 生成
text: 摘要文本vector: embeddingcontent:文档主体内容
display:文档显示用,支持 Markdown,可能包含黑体字text: 纯文本,模糊搜索用 小写exact: 精确搜索tokens: 对象数组surface : 显示拼写lemma : 去格位拼写compound_parts 复合词组分case 语法信息 如:sg_accvector:文档内容的 embeddingrelated_id:关联的段落 ID、句子 ID ["chapter_93-5","m.n. 38","93-5","95-7-2-10"]bold_single:单个黑体文本,用于搜索加权bold_multi:多个黑体文本,用于搜索加权page_refs:页码标记数组(如 ["V3.81","M3.58","PTS Vin II 57"])tags:文档主题标签(数组)category:文档分类 枚举 "pali"| "commentary"|'subcommentary'path:经文路径 "/suttapitaka/dighanikaya/mahavaggo/satipatthanasutta"language:资源语言 pali, zh-Hans, zh-Hant, en-US, my 等metadata:
APA: APA 格式引文字符串MLA: MLA 格式引文字符串author:作者或译者channel: wikipali channelupdated_at:原始文档更新时间
{
"id": "openSearch唯一ID",
"resource_id": "UUID",
"resource_type": "article | term | dictionary | translation | origin_text | nissaya",
"granularity": "book | chapter | sutta | section | paragraph | sentence"|"auto", // 新增
"title": "文档标题(中文或巴利文)",
"summary": {
"text": "摘要文本",
"vector": [
/* embedding 向量 */
]
},
"content": {
"display": "Markdown 格式,含黑体字",
"text": "小写纯文本,模糊搜索用",
"exact": "精确匹配用",
"tokens": [
{ "surface": "bhikkhave", "lemma": "bhikkhu", "case": "voc_pl" }
],
"vector": [
/* embedding 向量 */
]
},
"related_id": ["m.n.38", "93-5"],
"bold_single": ["某个黑体词"],
"bold_multi": ["多个黑体词"],
"page_refs": ["V3.81", "M3.58", "PTS Vin II 57"],
"tags": ["禅修", "业报"],
"category": ["pali", "atthakatha","tika"],
"path": "/suttapitaka/dighanikaya/mahavaggo/satipatthanasutta",
"language": "pali | zh-Hans | zh-Hant | en-US | my",
"metadata": {
"APA": "Smith, J. (2020). Title of the book. Publisher.",
"MLA": "Smith, John. Title of the Book. Publisher, 2020.",
"author": "译者或作者",
},
"updated_at": "2025-09-19T00:00:00Z"
}
全文搜索
page_refs 页码搜素巴利文格位归一化搜索
在配置里定义一个查询时同义词分析器:
"analyzer": {
"pali_query_analyzer": {
"tokenizer": "standard",
"filter": ["lowercase", "pali_synonyms"]
},
},
"filter": {
"pali_synonyms": {
"type": "synonym_graph",
"synonyms_path": "analysis/pali_synonyms.txt"
},
}
查询时指定 analyzer:
{
"query": {
"match": {
"content.text": {
"query": "夜叉",
"analyzer": "pali_query_analyzer"
}
}
}
}
过滤/精确查询
tags 过滤主题category 过滤文献分类黑体字搜索加权
bold_single bold_multi(Markdown 黑体),排名靠前语义搜索
vector 检索相似句子vector 检索不同语言相似句子
-巴利相似句
页码搜索
page_refs简繁体互查
处理变音符号
模糊搜索+精确匹配
{
"mappings": {
"properties": {
"content": {
"type": "text",
"analyzer": "icu_analyzer",
"fields": {
"raw": { "type": "keyword" }
// 精确匹配整段内容或句子
}
}
}
},
"settings": {
"analysis": {
"analyzer": {
"icu_analyzer": {
"tokenizer": "icu_tokenizer",
"filter": ["icu_folding", "lowercase"]
}
}
}
}
}
模糊搜索(支持巴利 diacritics 和英文转写)
{
"query": {
"match": {
"content": "mettā"
}
}
}
精确匹配(只要完全等于)
{
"query": {
"term": {
"title.raw": "mettā"
}
}
}
混合搜索 hybrid
模糊搜索+语义搜索 权重为 7:3
k-NN 插件(已支持向量搜索,无需额外安装)ikanalysis-icuicu_transform适合快速上线,效果好,但依赖外部服务。
text-embedding-3-small支持 100+ 语言(含中文、英文、缅文)。
1536 维向量。
专门为跨语言搜索优化。
部署成本:只需 API 调用。
场景:最稳妥,适合你的「用户用中文 → 检索缅文/英文/巴利文」需求。
curl https://api.openai.com/v1/embeddings \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "text-embedding-3-small",
"input": "佛陀在祇园精舍说法"
}'
15 token
Prices per 1M tokens.
| Model | Cost | Batch cost |
|---|---|---|
| text-embedding-3-small | $0.02 | $0.01 |
| text-embedding-3-large | $0.13 | $0.065 |
laravel API.实现简单和复杂两个查询接口
GET /api/v3/search
查询参数:
q (string): 搜索关键词resource_type (string): article|term|dictionary|translation|origin_text|nissayagranularity (string): book|chapter|sutta|section|paragraph|sentencelanguage (string): pali|zh-Hans|zh-Hant|en-US|mycategory (array): 文献分类过滤 ["pali", "commentary", "subcommentary"]tags (array): 主题标签过滤page_refs (string): 页码搜索,如 "M3.58"page (int): 页码,默认 1page_size (int): 每页数量,默认 20,最大 100search_mode (string): fuzzy|exact|semantic|hybrid,默认 fuzzy关键词搜索
GET /api/v3/search?q=世尊&search_mode=fuzzy
语义搜索:
GET /api/v3/search?q=佛陀关于慈悲的教导&search_mode=semantic
巴利相似句搜索:
GET /api/v3/search?q=sabbe dhammā anattā&resource_type=origin_text&language=pali&granularity=sentence&search_mode=fuzzy
页码搜索:
GET /api/v3/search?page_refs=M3.58
响应格式:
{
"success": true,
"data": {
"total": 156,
"page": 1,
"page_size": 20,
"took": "120ms",
"results": [
{
"id": "doc_123",
"resource_id": "uuid-456",
"resource_type": "origin_text",
"granularity": "sentence",
"title": "法印经",
"content": {
"display": "sabbe dhammā anattāti",
"tokens": [
{ "surface": "sabbe", "lemma": "sabba", "case": "nom_pl" },
{ "surface": "dhammā", "lemma": "dhamma", "case": "nom_pl" },
{ "surface": "anattāti", "lemma": "anatta", "case": "nom_pl" }
]
},
"related_id": ["93-15"],
"page_refs": ["M3.58"],
"language": "pali",
"path": "/suttapitaka/majjhimanikaya",
"score": 0.95,
"similarity": 0.92 // 巴利相似句特有字段
}
],
"aggregations": {
"resource_type": {
"buckets": [{ "key": "origin_text", "doc_count": 89 }]
},
"language": {
"buckets": [{ "key": "pali", "doc_count": 89 }]
}
}
},
"query_info": {
"original_query": "sabbe dhammā anattā",
"search_type": "pali_similar_sentence" // 后端识别的搜索类型
}
}
输入英文字母,能查到带有特殊符号的巴利文
GET /api/v3/search-suggest
查询参数:
q (string): 输入的部分文本type (enum): term|pali_romanized|page_reflanguage (string): 建议的目标语言limit (int): 返回数量,默认 10
{
"success": true,
"data": {
"suggestions": [
{
"text": "四念处",
"pali": "satipaṭṭhāna",
"romanized": "satipatthana",
"type": "term",
"frequency": 156
}
]
}
}
REACT + antd 实现聊天 Agent 调用不同的查询函数实现复杂的多轮对话查询
四圣谛相关的资源禅那 禅那缘related_id=95-4。用于经文阅读界面。我们的全文搜索项目将采用“多个函数、较少参数”的设计理念。这一策略旨在通过创建一组专精、单一职责的工具函数,来构建一个高效、可扩展且易于维护的搜索代理(Agent)。
传统的代理设计常将所有功能打包进一个庞大的函数(例如 searchDocument),并用大量参数来区分不同意图。这种做法虽然直观,但会给大型语言模型(LLM)带来认知负担,导致参数混淆和调用错误,并使得代码难以扩展。
我们的设计为:每个函数只负责一种明确的搜索意图,并只接受其完成任务所必需的最少参数。这就像为代理配备了一套专用的工具箱,而不是一把万能钥匙。
我们为不同的搜索需求定义了以下几个功能独立的函数:
search_by_query(query, search_mode, ...): 处理通用的、描述性的模糊或语义搜索。search_by_page_ref(page_refs): 专门用于精确的页码搜索。get_term_definition(term): 仅用于获取佛教术语的定义。search_pali(query): 专门用于巴利文的精确匹配搜索。代理将通过解析用户查询,准确地调用这四个函数中的一个。例如,当用户输入“M3.58”时,代理会立即识别为页码搜索意图,并调用 search_by_page_ref 函数,而不会在其他不相关的参数上浪费算力。
search_by_author(author) 函数即可,无需改动任何现有代码。你是一个专业的、精通巴利语和汉语的佛教文献检索助手。你的任务是分析用户的查询,并利用你拥有的工具(函数)来获取信息。
严格遵守以下原则:
1. 优先并恰当地使用提供的工具来满足用户的查询需求。
2. 你的回答必须简洁、直接,仅包含从工具中获得的信息,不添加任何额外闲聊。
3. 如果一个查询无法被任何工具处理,或者需要与用户进行澄清,请清晰地说明。
4. 当用户的查询包含**页码标记**(例如:M3.58, V3.81)时,必须使用 `search_by_page_ref` 函数。
5. 当用户的查询是**明确的佛教术语或词汇**(例如:四圣谛, mettā)时,必须使用 `get_term_definition` 或 `search_pali` 函数。
6. 当用户的查询是**描述性、自然语言问题**(例如:佛陀关于慈悲的教导)时,必须使用 `search_by_query` 函数并指定 `search_mode='semantic'`。
7. 当用户的查询是**普通关键词**(例如:比丘, 袈裟)时,使用 `search_by_query` 函数并指定 `search_mode='fuzzy'`。
以下是你的工具箱:
- `search_by_query`: 用于通用的模糊和语义搜索。
- `search_by_page_ref`: 专门用于处理页码搜索。
- `get_term_definition`: 专门用于获取术语定义。
- `search_pali`: 专门用于处理巴利文精确搜索。
请严格根据上述原则,选择最恰当的工具来处理用户的请求。
[
{
"name": "search_by_query",
"description": "根据关键词或自然语言描述在佛教文献库中进行通用搜索,支持模糊和语义匹配。适用于“佛陀关于慈悲的教导”或“什么是八正道”这类查询。",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "用户的搜索关键词或句子。"
},
"search_mode": {
"type": "string",
"enum": ["fuzzy", "semantic"],
"description": "指定搜索模式:'fuzzy' 用于模糊搜索, 'semantic' 用于语义相似度搜索。"
}
},
"required": ["query", "search_mode"]
}
},
{
"name": "search_by_page_ref",
"description": "根据页码标记(如 PTS VinIII 24, M3.58)在文献库中进行精确搜索,快速定位特定经文。",
"parameters": {
"type": "object",
"properties": {
"page_refs": {
"type": "string",
"description": "页码标记,例如 'PTS VinIII 24', 'M3.58', 'P3.81'。"
}
},
"required": ["page_refs"]
}
},
{
"name": "get_term_definition",
"description": "获取佛教术语或词汇的精确定义和解释,用于回答“什么是四圣谛”或“禅那是什么意思”这类问题。",
"parameters": {
"type": "object",
"properties": {
"term": {
"type": "string",
"description": "需要查询的佛教术语或词汇。"
}
},
"required": ["term"]
}
},
{
"name": "search_pali",
"description": "在巴利文经文中搜索精确匹配的词汇或短语,支持巴利文格位归一化。适用于“sabbe dhammā anattā”这类查询。",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "需要精确匹配的巴利文词汇或短语。"
}
},
"required": ["query"]
}
}
]
TypeScript 类型定义
// ---------------------------------------------------------------- //
// 核心搜索函数参数类型:search_documents //
// ---------------------------------------------------------------- //
/**
* 搜索模式的枚举,用于指定不同类型的搜索。
* - 'fuzzy': 模糊搜索,支持巴利文变音符号、简繁体等。
* - 'exact': 精确匹配,用于专有名词或特定短语。
* - 'semantic': 语义搜索,基于向量检索。
* - 'hybrid': 混合搜索 fuzzy+semantic。
*/
export type SearchMode = 'fuzzy' | 'exact' | 'semantic' | 'hybrid';
/**
* 文档类型的枚举,用于筛选不同来源的文档。
*/
export type ResourceType = 'article' | 'term' | 'dictionary' | 'translation' | 'original_text' | 'nissaya';
/**
* 语言代码的枚举。
*/
export type Language = 'pali' | 'zh-Hans' | 'zh-Hant' | 'en-US' | 'my';
/**
* search_documents 函数的参数类型。
* 这将作为 Function Calling 的 `arguments` 参数传递。
*/
export interface SearchDocumentsArgs {
/**
* 用户的搜索关键词或句子。
*/
query: string;
/**
* 指定搜索模式,由 AI 助手根据用户意图判断。
*/
search_mode: SearchMode;
/**
* 文档类型数组,用于过滤搜索结果。
*/
resource_type?: ResourceType[];
/**
* 语言数组,用于过滤搜索结果。
*/
language?: Language[];
/**
* 页码标记,仅在 search_mode 为 'page_search' 时使用。
*/
page_refs?: string;
/**
* 主题标签数组,用于进一步过滤。
*/
tags?: string[];
}
// ---------------------------------------------------------------- //
// 术语定义函数参数类型:get_term_definition //
// ---------------------------------------------------------------- //
/**
* get_term_definition 函数的参数类型。
*/
export interface GetTermDefinitionArgs {
/**
* 需要查询的佛教术语或词汇。
*/
term: string;
}
// ---------------------------------------------------------------- //
// AI 助手返回的 Function Call 类型 //
// ---------------------------------------------------------------- //
/**
* AI 助手返回的函数调用对象。
*/
export type AICallbackFunction = {
/**
* 要调用的函数名。
*/
name: 'search_documents' | 'get_term_definition';
/**
* 传递给函数的参数。
* 这里使用泛型来确保参数类型与函数名匹配。
*/
arguments: SearchDocumentsArgs | GetTermDefinitionArgs;
};
// ---------------------------------------------------------------- //
// 后端 API 响应类型(示例) //
// ---------------------------------------------------------------- //
/**
* 核心文档卡片的数据结构。
*/
export interface DocumentResult {
id: string;
resource_id: string;
resource_type: ResourceType;
title: string;
content: {
display: string;
text: string;
vector?: number[];
};
related_id: string[];
page_refs?: string[];
language: Language;
score: number;
similarity?: number;
}
/**
* API 搜索响应的完整结构。
*/
export interface SearchResponse {
success: boolean;
data: {
total: number;
page: number;
page_size: number;
took: string;
results: DocumentResult[];
};
query_info: {
original_query: string;
search_type: SearchMode | 'term_definition';
};
}