文档切片向量化

23 阅读3分钟

通用的方法,关键字过滤chunk

import faiss
import numpy as np

# 文本切片(带重叠)
def recursive_split_text(text, chunk_size=300, chunk_overlap=50):
    chunks = []
    if not text:
        return chunks
    start_idx = 0
    while start_idx < len(text):
        end_idx = min(start_idx + chunk_size, len(text))
        chunks.append(text[start_idx:end_idx])
        start_idx += (chunk_size - chunk_overlap)
    return chunks

# 关键词筛选:根据提取需求挑相关片段
def filter_chunks(chunks, keywords):
    res = []
    for seg in chunks:
        if any(k in seg for k in keywords):
            res.append(seg)
    return res

# 年报文本
annual_report_text = """
XX公司2025年度年报
一、经营概况
本报告期公司实现营业收入 28.65 亿元,同比增长 12.3%。
归属于上市公司股东的净利润 4.21 亿元,同比增长 8.7%。
二、业务板块
主营业务覆盖医药研发与生产,全年研发投入1.8亿元。
三、股东信息
前三大股东持股比例分别为25%、18%、12%。
四、未来规划
公司计划持续加大海外市场拓展力度。
"""

chunks = recursive_split_text(annual_report_text)
print(f"文档共分割为 {len(chunks)} 个片段\n")

# 定义检索关键词
query_keywords = ["营业收入", "净利润", "研发投入", "股东持股"]
# 筛选有效片段
# related_chunks = filter_chunks(chunks, query_keywords)
# context = "\n".join(related_chunks)
context = "\n".join(chunks)
print("筛选到的相关文本:\n", context, "\n")

# 调用通义千问
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
    api_key=‘",
    base_url="",
    model_name="qwen-plus",
    temperature=0
)

query = "提取年报中的营业收入、净利润、研发投入、前三大股东持股比例"
prompt = f"""
请根据下面的年报文本内容,完成提取任务:{query}
要求:严格输出标准JSON格式,只保留结果,不要多余解释。
文本内容:
{context}
"""

result = llm.invoke(prompt)
print("提取的结构化年报信息:\n", result.content)

按照结构过滤(如年报的结构)

import faiss
import numpy as np

# ===================== 1. 结构化切片(适配年报层级结构) =====================
def split_by_structure(text):
    """
    按年报天然结构分割:空行、换行、标题分割,保留章节完整性
    """
    # 先按连续空行分割大章节
    raw_sections = [s.strip() for s in text.split("\n\n") if s.strip()]
    chunks = []
    for sec in raw_sections:
        # 单章节过长,再按字符二次分割(防止单块太大)
        if len(sec) > 600:
            start = 0
            chunk_size = 400
            overlap = 60
            while start < len(sec):
                end = start + chunk_size
                chunks.append(sec[start:end])
                start += (chunk_size - overlap)
        else:
            chunks.append(sec)
    return chunks

# 关键词精准筛选(按年报业务板块匹配)
def match_section(chunks):
    # 分类关键词,对应年报不同模块
    target_keys = {
        "财务数据": ["营业收入", "净利润", "利润", "营收", "同比"],
        "研发信息": ["研发", "研发投入"],
        "股东信息": ["股东", "持股", "股权"]
    }
    res = []
    for seg in chunks:
        for keys in target_keys.values():
            if any(k in seg for k in keys):
                res.append(seg)
                break
    return res

# ===================== 2. 年报文本(保留原有结构) =====================
annual_report_text = """
XX公司2025年度年报

一、经营概况
本报告期公司实现营业收入 28.65 亿元,同比增长 12.3%。
归属于上市公司股东的净利润 4.21 亿元,同比增长 8.7%。

二、业务板块
主营业务覆盖医药研发与生产,全年研发投入1.8亿元。

三、股东信息
前三大股东持股比例分别为25%、18%、12%。

四、未来规划
公司计划持续加大海外市场拓展力度,布局全球市场。
"""

# 结构化分割
chunks = split_by_structure(annual_report_text)
print(f"按年报结构分割,共 {len(chunks)} 个片段\n")

# 筛选目标章节
related_chunks = match_section(chunks)
context = "\n".join(related_chunks)
print("筛选出的结构化章节内容:\n", context, "\n")

# ===================== 3. 调用通义千问提取数据 =====================
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
    api_key="",
    base_url="",
    model_name="qwen-plus",
    temperature=0
)

query = "提取年报中的营业收入、净利润、研发投入、前三大股东持股比例"
prompt = f"""
请根据下面结构化的年报文本完成提取任务:{query}
要求:严格输出标准JSON格式,只保留结果,不要多余文字、解释。
文本内容:
{context}
"""

result = llm.invoke(prompt)
print("最终提取结果:\n", result.content)