作者:吴业亮
博客:wuyeliang.blog.csdn.net

本文将完整实现基于LlamaIndex的AI法律助手,环境为Ubuntu22.04,使用Conda管理Python3.12.4环境,本地Ollama提供大模型能力,支持法律文档(法规、案例等)的加载、索引构建和智能问答。

一、环境准备

1. 安装Conda(若未安装)

# 下载Miniconda(适配Ubuntu22.04)
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh

# 执行安装脚本(一路回车,最后同意conda init)
bash Miniconda3-latest-Linux-x86_64.sh

# 重启终端或刷新环境变量
source ~/.bashrc

2. 创建并激活Python3.12.4环境

# 创建conda环境(指定Python版本)
conda create -n legal-ai python=3.12.4 -y

# 激活环境
conda activate legal-ai

3. 安装Ollama(本地大模型服务)

# 安装Ollama
curl -fsSL https://ollama.com/install.sh | sh

# 启动Ollama服务(Ubuntu默认开机自启,手动启动命令如下)
systemctl start ollama
systemctl enable ollama  # 设置开机自启

# 验证Ollama安装
ollama --version

# 拉取适合法律场景的大模型(推荐Llama3-8B/Qwen2-7B,本地运行足够)
ollama pull llama3:8b
# 可选:中文优化的模型
ollama pull qwen2:7b

二、安装核心依赖

在激活的legal-ai环境中安装以下包:

# LlamaIndex核心包
pip install llama-index-core==0.10.67

# Ollama LLM集成包
pip install llama-index-llms-ollama==0.1.26

# 文档加载器(支持TXT/PDF/Word等法律文档)
pip install llama-index-readers-file==0.1.37

# 可选:PDF解析增强(解决复杂PDF排版问题)
pip install pymupdf==1.24.10

# 可选:中文分词优化
pip install jieba==0.42.1

三、AI法律助手核心代码实现

1. 完整代码(legal_assistant.py)

import os
from llama_index.core import (
    VectorStoreIndex,
    SimpleDirectoryReader,
    Settings,
    PromptTemplate,
    StorageContext,
    load_index_from_storage
)
from llama_index.llms.ollama import Ollama

# -------------------------- 1. 配置全局设置 --------------------------
# 配置Ollama LLM(指定本地模型、温度、上下文窗口)
Settings.llm = Ollama(
    model="llama3:8b",  # 替换为qwen2:7b(若拉取了中文模型)
    base_url="http://localhost:11434",  # Ollama默认端口
    temperature=0.1,  # 法律场景降低随机性,提高准确性
    context_window=8192  # 适配模型的上下文窗口
)

# 设置嵌入模型(本地轻量嵌入,避免联网)
Settings.embed_model = "local:BAAI/bge-small-zh-v1.5"  # 中文法律文本优化的嵌入模型

# -------------------------- 2. 自定义法律场景提示词 --------------------------
# 系统提示词:约束模型仅基于提供的法律文档回答,符合法律规范
SYSTEM_PROMPT = PromptTemplate(
    """
    你是一名专业的AI法律助手,需严格遵守以下规则:
    1. 仅基于提供的法律文档(法规、案例、司法解释)回答问题,不编造法律条款或案例;
    2. 回答需引用具体的法律条款编号、案例名称(如有),保证准确性和可追溯性;
    3. 对于模糊或有争议的法律问题,需说明不同的解释方向,不给出绝对化结论;
    4. 所有回答使用中文,语言简洁、专业,符合法律文书规范;
    5. 若问题与提供的法律文档无关,明确告知无法回答,并说明原因。

    法律文档内容:
    {context_str}

    用户问题:{query_str}
    """
)

# -------------------------- 3. 加载法律文档并构建索引 --------------------------
def build_legal_index(doc_dir: str, index_storage_dir: str = "./legal_index") -> VectorStoreIndex:
    """
    构建法律文档索引(支持增量构建,已存在则加载)
    :param doc_dir: 法律文档存放目录
    :param index_storage_dir: 索引持久化目录
    :return: 构建好的索引
    """
    # 检查索引是否已存在,存在则加载
    if os.path.exists(index_storage_dir):
        print(f"🔍 检测到已存在的索引,加载中...")
        storage_context = StorageContext.from_defaults(persist_dir=index_storage_dir)
        index = load_index_from_storage(storage_context)
        return index
    
    # 不存在则加载文档并构建索引
    print(f"📄 加载法律文档:{doc_dir}")
    # 加载目录下所有文档(支持TXT/PDF/Word)
    documents = SimpleDirectoryReader(
        input_dir=doc_dir,
        required_exts=[".txt", ".pdf", ".docx"],  # 仅加载法律相关文档格式
        recursive=True  # 递归加载子目录文档
    ).load_data()
    
    print(f"📊 共加载 {len(documents)} 个文档片段,开始构建索引...")
    # 构建向量索引
    index = VectorStoreIndex.from_documents(documents)
    
    # 持久化索引(避免重复构建)
    index.storage_context.persist(persist_dir=index_storage_dir)
    print(f"✅ 索引构建完成,已保存至:{index_storage_dir}")
    return index

# -------------------------- 4. 创建法律问答引擎 --------------------------
def create_legal_query_engine(index: VectorStoreIndex) -> object:
    """
    创建定制化的法律问答引擎
    """
    query_engine = index.as_query_engine(
        text_qa_template=SYSTEM_PROMPT,
        similarity_top_k=5,  # 返回Top5最相关的法律文档片段
        response_mode="compact"  # 紧凑模式,优先引用核心条款
    )
    return query_engine

# -------------------------- 5. 交互式问答主函数 --------------------------
def main():
    # 法律文档目录(需提前放入民法典、司法解释、案例等文件)
    LEGAL_DOC_DIR = "./legal_docs"
    # 索引存储目录
    INDEX_DIR = "./legal_index"
    
    # 创建法律文档目录(若不存在)
    if not os.path.exists(LEGAL_DOC_DIR):
        os.makedirs(LEGAL_DOC_DIR)
        print(f"⚠️  法律文档目录已创建:{LEGAL_DOC_DIR},请放入法律文档后重新运行!")
        return
    
    # 构建/加载索引
    index = build_legal_index(LEGAL_DOC_DIR, INDEX_DIR)
    
    # 创建问答引擎
    query_engine = create_legal_query_engine(index)
    
    # 交互式问答
    print("\n=====================================")
    print("🎯 AI法律助手已就绪,输入问题即可咨询(输入'退出'结束)")
    print("=====================================\n")
    
    while True:
        user_query = input("您的法律问题:")
        if user_query.strip() in ["退出", "q", "Q"]:
            print("👋 感谢使用AI法律助手,再见!")
            break
        
        try:
            # 执行查询
            response = query_engine.query(user_query)
            # 输出回答
            print("\n📝 法律助手回答:")
            print(response.response)
            
            # 可选:输出引用的法律文档片段
            print("\n📚 引用的法律依据:")
            for i, node in enumerate(response.source_nodes, 1):
                print(f"\n{i}. 相关度:{node.score:.2f}")
                print(f"   内容:{node.text[:200]}...")  # 截断长文本,仅显示前200字
        except Exception as e:
            print(f"❌ 回答出错:{str(e)}")

if __name__ == "__main__":
    main()

2. 准备法律文档

  1. 创建legal_docs目录:
    mkdir legal_docs
    
  2. 放入法律相关文档(推荐先测试《民法典》文本):
    • 下载《民法典》TXT版本,放入legal_docs目录;
    • 也可放入本地的法律案例、司法解释、地方性法规等文档(支持TXT/PDF/Word)。

四、运行与测试

1. 启动法律助手

# 确保conda环境已激活
conda activate legal-ai

# 运行代码
python legal_assistant.py

2. 测试示例问答

=====================================
🎯 AI法律助手已就绪,输入问题即可咨询(输入'退出'结束)
=====================================

您的法律问题:民法典中关于民间借贷的利率上限是多少?

📝 法律助手回答:
根据《中华人民共和国民法典》及相关司法解释,民间借贷的利率上限遵循以下规则:
1. 借贷双方约定的利率未超过合同成立时一年期贷款市场报价利率(LPR)的四倍,出借人请求借款人按照约定的利率支付利息的,人民法院应予支持;
2. 超过上述四倍利率的部分,人民法院不予支持。

📚 引用的法律依据:

1. 相关度:0.98
   内容:第六百八十条 禁止高利放贷,借款的利率不得违反国家有关规定。借款合同对支付利息没有约定的,视为没有利息。借款合同对支付利息约定不明确,当事人不能达成补充协议的,按照当地或者当事人的交易方式、交易习惯、市场利率等因素确定利息;自然人之间借款的,视为没有利息。...

2. 相关度:0.95
   内容:最高人民法院关于审理民间借贷案件适用法律若干问题的规定第二十五条 出借人请求借款人按照合同约定利率支付利息的,人民法院应予支持,但是双方约定的利率超过合同成立时一年期贷款市场报价利率四倍的除外。...

五、进阶优化

1. 支持更多法律文档格式

  • 新增llama-index-readers-azure-blob-storage/llama-index-readers-s3支持云端法律文档;
  • 安装llama-index-readers-html解析法律网页(如法院公告、法规官网)。

2. 索引优化

  • 使用MultiVectorIndex拆分长法律文档(如整本法条),提高检索精度;
  • 配置BM25Retriever结合向量检索,解决法律术语的精确匹配问题。

3. 部署优化

  • 使用FastAPI封装为API服务,对接前端界面;
  • 配置Ollama的num_gpu参数(ollama run llama3:8b --num_gpu 1),利用GPU加速推理。

六、常见问题解决

  1. Ollama连接失败:检查服务状态(systemctl status ollama),确保端口11434未被占用;
  2. 文档加载乱码:PDF文件使用pymupdf解析,TXT文件统一编码为UTF-8;
  3. 回答不准确:降低temperature(如0.05),增加similarity_top_k(如8),优化嵌入模型为BAAI/bge-large-zh-v1.5
  4. 内存不足:切换更小的模型(如llama3:70b改为llama3:8b),关闭其他占用内存的进程。

总结

本方案基于LlamaIndex+Ollama实现了本地化部署的AI法律助手,无需联网,数据隐私可控,适配Ubuntu22.04+Python3.12.4环境。可根据实际需求扩展文档来源、优化检索策略,适配律所、企业法务等场景的法律问答需求。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐