从零开始搭建本地安全 AI 大模型攻防知识库
字数 1758 2025-08-19 12:40:36

本地安全AI大模型攻防知识库搭建教程

1. 概述

本教程将详细介绍如何从零开始搭建一个本地大模型问答知识库,重点解决在搭建过程中遇到的各种问题及其解决方案。

1.1 搭建方案选择

目前搭建大语言问答知识库主要有三种方案:

  1. 微调模型(Fine-tuning):在预训练模型基础上进行特定任务的调整
  2. 再次训练模型(Retraining):从零开始训练模型
  3. 增强检索生成(RAG, Retrieval Augmented Generation):结合检索和生成的技术

推荐方案:考虑到成本和响应速度,建议使用开源本地大型语言模型结合RAG方案。经过测试,llama3:8b和qwen2:7b这类体量的模型响应速度快,适合搭建问答知识库。

2. RAG原理详解

2.1 RAG基本工作原理

RAG(检索增强生成)结合了信息检索和文本生成技术,主要步骤如下:

  1. 对知识库内容进行分片处理
  2. 使用embedding模型将分片后的知识库向量化
  3. 使用embedding模型将用户问题向量化
  4. 计算问题向量与知识库向量的相似度,找出最相似的k个结果
  5. 将这k个结果作为上下文放入prompt中,连同用户问题一起提交给大模型

2.2 向量相似度计算示例

import numpy as np

def cosine_similarity(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

# 示例数据
context = ["北京,上海,杭州", "苹果,橘子,桃子", "太阳,月亮,星星"]
questions = ["城市", "水果", "天体"]

# 计算相似度
for i in range(3):
    for j in range(3):
        similar = cosine_similarity(qVector[i], vector[j])
        print(f"{questions[i]}{context[j]}的相似度为:{similar}")

2.3 RAG的必要性

  • 私有数据处理:当知识库包含私有数据(不在大模型训练数据中)时,RAG是比微调更经济的方案
  • 上下文长度限制:直接放入全部知识库内容会超过token限制(如qwen2:7b最大128k tokens)
  • 成本效益:相比微调或重新训练,RAG成本更低,实现更快

3. 技术实现细节

3.1 向量存储与检索方案

对于大规模知识库,需要专门的向量数据库来存储和快速检索:

推荐工具:

  • redis-search
  • chroma
  • elasticsearch
  • opensearch
  • lancedb
  • pinecone
  • qdrant
  • weaviate
  • zilliz

3.1.1 使用redis-search实现

import redis
from redis.commands.search.query import Query
from redis.commands.search.field import TextField, VectorField

class RedisCache:
    def __init__(self, host: str = "localhost", port: int = 6379):
        self.cache = redis.Redis(host=host, port=port)
    
    # 其他方法省略...

# 初始化
redis = RedisCache()

# 定义字段
info = TextField("info")
name = "embedding"
algorithm = "HNSW"
attributes = {
    "TYPE": "FLOAT32",
    "DIM": DIM,  # 向量维度
    "DISTANCE_METRIC": "COSINE"
}
embed = VectorField(name=name, algorithm=algorithm, attributes=attributes)

# 创建索引
scheme = (info, embed)
index = redis.getSchema(self.redisIndexName)
redis.createIndex(index, scheme)

# 插入数据
def insertData(self, model):
    j = 0
    for file in self.filesPath:
        for i in file.content:
            embed = self.engine.embeddings(i, model=model)
            emb = numpy.array(embed, dtype=numpy.float32).tobytes()
            im = {
                "info": i,
                "embedding": emb,
            }
            name = f"{self.redisIndexName}-{j}"
            j += 1
            self.redis.hset(name, im)

# 查询
k = 10
base_query = f"* => [KNN {k} @embedding $query_embedding AS similarity]"
return_fields = ["info", "similarity"]
qr = self.engine.embeddings(question, model=model)
params_dict = {"query_embedding": np.array(qr, dtype=np.float32).tobytes()}
index = self.redis.getSchema(self.redisIndexName)
result = self.redis.query(index, base_query, return_fields, params_dict, k)

3.2 Prompt设计示例

prompt = [
    {
        "role": "user",
        "content": f"""当你收到用户的问题时,请编写清晰、简洁、准确的回答。你会收到一组与问题相关的上下文,请使用这些上下文,请使用中文回答用户的提问。不允许在答案中添加编造成分,如果给定的上下文没有提供足够的信息,就回答"##no##"。不要提供与问题无关的信息,也不要重复。
> 上下文:
>>>
{context}
>>>
> 问题:
{question}"""
    }
]

4. 实际应用中的难点与解决方案

4.1 难点一:大语言模型能力不足

问题表现

  • 本地小模型(如qwen2:7b)能力有限,回答质量不如GPT-4
  • Embedding模型准确率低(约50-60%)

解决方案

  1. 优化提问方式和上下文顺序
  2. 使用rerank模型提高准确率

4.1.1 Rerank模型实现

from BCEmbedding import RerankerModel

# 初始化rerank模型
rerankModel = RerankerModel(model_name_or_path="maidalun1020/bce-reranker-base_v1", local_files_only=True)

# 搜索出前20相似内容
k = 20
result = self.redis.query(index, base_query, return_fields, params_dict, k)
passages = [doc.info for doc in result.docs]

# 重打分
rerank_results = rerankModel.rerank(question, passages)
info = rerank_results["rerank_passages"]
last_result = info[:10]  # 取前10高分结果

4.2 难点二:提问的复杂性

4.2.1 范围搜索性提问

问题示例

  • "2024年的文章有哪些?"
  • "CTF相关的文章有哪些?"

挑战

  • 难以确定合适的k值
  • 可能遗漏相关内容或浪费计算资源

解决方案

  1. 设置较大的初始k值(如1000)
  2. 根据相似度阈值过滤结果
  3. 使用上下文压缩技术

4.2.2 多轮对话处理

问题示例
用户: 2024年的文章有哪些?
助手: (列出部分文章)
用户: 还有吗?

解决方案

  • 检测低相似度分数判断为多轮对话
  • 维护对话状态和已显示结果

4.3 难点三:文本处理

4.3.1 图片处理方案

  1. 使用OCR识别图片文字(效果有限)
  2. 使用llava或GPT-4等模型描述图片
  3. 直接返回图片链接并在prompt中说明

4.3.2 文本分片策略

问题

  • 简单按长度分片会割裂相关上下文(如代码段)
  • 重叠分片效果提升有限

推荐方案

  • 根据文档结构分片(如按一级标题)
  • 每个chunk包含文章基础信息
  • 对长代码段特殊处理
  • 针对不同格式文档设计专门分片策略

示例

from llama_index import SimpleDirectoryReader
from llama_index.node_parser import SimpleNodeParser

documents = SimpleDirectoryReader(input_dir="./Documents").load_data()
node_parser = SimpleNodeParser.from_defaults(chunk_size=514, chunk_overlap=80)
nodes = node_parser.get_nodes_from_documents(documents)

4.4 上下文压缩技术

def compress(self, question: str, context: list[str], maxToken: int = 1024) -> list[str]:
    template = f"下面将会提供问题和上下文,请判断上下文信息是否和问题相关,如果不相关,请回复##no##,如果相关,请提取出和上下文相关的内容。*注意*:请直接提取出上下文的关键内容,请*不要*自行发挥,*不要*进行任何修改或者压缩删减操作。\n\n> 问题:{question}\n> 上下文:\n>>>\n%s\n>>>"
    
    result = []
    for c in context:
        qs = template % c
        answer = self.engine.chat(qs)
        if "##no##" not in answer:
            result += [answer]
    
    newContent = "\n".join(result)
    question = f"你是一个去重机器人,下面将会提供一组上下文,请你对上下文进行去重处理。*注意*,请*不要*自行发挥,*不要*进行任何添加修改,请直接在上下文内容中进行去重。\n上下文:>>>\n{newContent}\n>>>"
    answer = self.engine.chat(question)
    return answer

5. 优化策略总结

  1. 相似度过滤:设置相似度阈值(如>0.4)和rerank分数阈值(如>0.5)
  2. 动态k值:根据查询类型动态调整k值大小
  3. 上下文压缩:去除无关内容,增加有效上下文量
  4. 分片优化:根据文档结构而非简单长度分片
  5. 多模型协作:结合embedding模型、rerank模型和生成模型

6. 参考资源

  1. QAnything项目
  2. LLMLingua项目
  3. llama_index文档
  4. langchain框架

7. 结论

当前本地问答知识库的搭建仍面临诸多挑战,主要受限于大语言模型的能力。最佳实践是构建灵活框架,便于替换不同组件和模型。随着大语言模型技术的发展,未来有望实现更快速、更精准的问答系统。

本地安全AI大模型攻防知识库搭建教程 1. 概述 本教程将详细介绍如何从零开始搭建一个本地大模型问答知识库,重点解决在搭建过程中遇到的各种问题及其解决方案。 1.1 搭建方案选择 目前搭建大语言问答知识库主要有三种方案: 微调模型(Fine-tuning) :在预训练模型基础上进行特定任务的调整 再次训练模型(Retraining) :从零开始训练模型 增强检索生成(RAG, Retrieval Augmented Generation) :结合检索和生成的技术 推荐方案 :考虑到成本和响应速度,建议使用开源本地大型语言模型结合RAG方案。经过测试,llama3:8b和qwen2:7b这类体量的模型响应速度快,适合搭建问答知识库。 2. RAG原理详解 2.1 RAG基本工作原理 RAG(检索增强生成)结合了信息检索和文本生成技术,主要步骤如下: 对知识库内容进行分片处理 使用embedding模型将分片后的知识库向量化 使用embedding模型将用户问题向量化 计算问题向量与知识库向量的相似度,找出最相似的k个结果 将这k个结果作为上下文放入prompt中,连同用户问题一起提交给大模型 2.2 向量相似度计算示例 2.3 RAG的必要性 私有数据处理 :当知识库包含私有数据(不在大模型训练数据中)时,RAG是比微调更经济的方案 上下文长度限制 :直接放入全部知识库内容会超过token限制(如qwen2:7b最大128k tokens) 成本效益 :相比微调或重新训练,RAG成本更低,实现更快 3. 技术实现细节 3.1 向量存储与检索方案 对于大规模知识库,需要专门的向量数据库来存储和快速检索: 推荐工具: redis-search chroma elasticsearch opensearch lancedb pinecone qdrant weaviate zilliz 3.1.1 使用redis-search实现 3.2 Prompt设计示例 4. 实际应用中的难点与解决方案 4.1 难点一:大语言模型能力不足 问题表现 : 本地小模型(如qwen2:7b)能力有限,回答质量不如GPT-4 Embedding模型准确率低(约50-60%) 解决方案 : 优化提问方式和上下文顺序 使用rerank模型提高准确率 4.1.1 Rerank模型实现 4.2 难点二:提问的复杂性 4.2.1 范围搜索性提问 问题示例 : "2024年的文章有哪些?" "CTF相关的文章有哪些?" 挑战 : 难以确定合适的k值 可能遗漏相关内容或浪费计算资源 解决方案 : 设置较大的初始k值(如1000) 根据相似度阈值过滤结果 使用上下文压缩技术 4.2.2 多轮对话处理 问题示例 : 用户: 2024年的文章有哪些? 助手: (列出部分文章) 用户: 还有吗? 解决方案 : 检测低相似度分数判断为多轮对话 维护对话状态和已显示结果 4.3 难点三:文本处理 4.3.1 图片处理方案 使用OCR识别图片文字(效果有限) 使用llava或GPT-4等模型描述图片 直接返回图片链接并在prompt中说明 4.3.2 文本分片策略 问题 : 简单按长度分片会割裂相关上下文(如代码段) 重叠分片效果提升有限 推荐方案 : 根据文档结构分片(如按一级标题) 每个chunk包含文章基础信息 对长代码段特殊处理 针对不同格式文档设计专门分片策略 示例 : 4.4 上下文压缩技术 5. 优化策略总结 相似度过滤 :设置相似度阈值(如>0.4)和rerank分数阈值(如>0.5) 动态k值 :根据查询类型动态调整k值大小 上下文压缩 :去除无关内容,增加有效上下文量 分片优化 :根据文档结构而非简单长度分片 多模型协作 :结合embedding模型、rerank模型和生成模型 6. 参考资源 QAnything项目 LLMLingua项目 llama_ index文档 langchain框架 7. 结论 当前本地问答知识库的搭建仍面临诸多挑战,主要受限于大语言模型的能力。最佳实践是构建灵活框架,便于替换不同组件和模型。随着大语言模型技术的发展,未来有望实现更快速、更精准的问答系统。