1. 项目概述:一个为越南企业打造的AI法律助手
如果你在越南经营一家初创公司或中小企业,处理法律文件可能是件头疼的事。请律师审一份合同,费用不菲;自己看吧,又怕漏掉关键风险条款。我最近在GitHub上发现了一个名为“Paparusi/legal-ai-agent”的开源项目,它试图用AI来解决这个痛点。简单来说,这是一个专为越南市场设计的AI法律助手,集成了法律检索、合同审查、文档起草和自主文件管理功能,界面设计得像VSCode一样,对开发者非常友好。
这个项目的核心价值在于,它不仅仅是一个简单的聊天机器人。它内置了一个拥有24种工具的AI智能体,能够像一位虚拟法务一样,主动读取、编辑、对比你的合同文件,并根据越南现行法律(如《民法典》、《商法》、《劳动法》)进行合规性检查。最吸引我的是它的“智能体化”能力——你可以直接告诉它“列出所有合同”或“修改这份合同中的罚则条款使其符合法律”,它会自动调用一系列工具完成任务,就像给律师配了一个超级高效的AI助手。对于预算有限但又需要基本法律风险防控的越南企业主或法务人员来说,这无疑是一个值得深入研究的工具。
2. 核心架构与技术栈深度解析
2.1 后端与AI引擎:FastAPI与多模型支持
项目后端采用FastAPI构建,这是一个高性能的现代Python Web框架,以其异步支持和自动生成API文档(OpenAPI)而闻名。选择FastAPI而非Django或Flask,主要考量是其对构建需要处理大量AI请求(如流式响应)的API非常友好,性能出色且开发效率高。
AI部分是项目的灵魂。它采用了**“自带大模型”** 的设计理念,支持接入多个主流LLM提供商:
- Anthropic Claude:项目默认且深度集成的模型,特别是Sonnet和Opus版本,以其强大的推理和长上下文能力(最高200K tokens)著称,非常适合处理冗长的法律文本分析。
- OpenAI GPT系列:支持GPT-4o、GPT-4o Mini等,提供了另一种高性能选择。
- Google Gemini:支持Gemini 2.5 Pro/Flash等,以其超长上下文(最高1M tokens)在处理超长合同时可能有优势。
- 自定义/本地模型:通过API兼容层,可以接入Ollama、vLLM或LM Studio部署的本地模型,这对数据隐私要求极高的企业至关重要。
注意:这种多模型支持并非简单的API切换。项目实现了一个统一的提供者接口,将不同模型的函数调用(Function Calling)格式进行标准化。这意味着上层的AI智能体(Agent)逻辑无需关心底层调用的是Claude还是GPT,大大提升了系统的可维护性和可扩展性。API密钥在数据库中使用Fernet(基于AES-256)进行加密存储,安全性有基本保障。
2.2 数据层:PostgreSQL与向量搜索
数据存储使用PostgreSQL,并利用pgvector扩展来实现向量搜索。这是构建法律检索(RAG,检索增强生成)系统的关键。
其工作流程如下:
- 知识库构建:将爬取或导入的越南法律条文(如《劳动法》、《商法》等)进行文本分割(Chunking)。
- 向量化:使用嵌入模型(Embedding Model)将每个文本块转换为一个高维向量。
- 存储与索引:将这些向量连同原文存入PostgreSQL的特定表中,pgvector会为其创建高效的索引(如IVFFlat或HNSW),以加速相似性搜索。
- 检索:当用户提问“劳动合同中的试用期最长是多久?”时,系统先将问题转换为向量,然后在向量数据库中搜索与之最相似的几个法律条文片段。
- 增强生成:将检索到的相关法律条文作为上下文,连同用户问题一起提交给LLM,让LLM生成准确且有法律依据的回答。
这种架构确保了AI的回答不是凭空臆想,而是建立在现有法律数据库之上,提高了答案的准确性和可信度。
2.3 前端:极简的Vanilla JS SPA
前端是一个单页应用,但有趣的是,它没有使用React、Vue等现代框架,而是用纯Vanilla JS编写,所有代码集中在一个约5600行的app.html文件中。这种选择可能出于以下考虑:
- 极致的部署简便性:前端就是一个静态HTML文件,可以放在任何地方,与后端完全解耦,无需复杂的构建流程。
- 快速启动与低开销:没有框架运行时开销,对于功能相对集中(主要是CRUD和聊天界面)的应用来说,开发和控制力更强。
- 模仿VSCode体验:实现了三栏式布局、命令面板(Ctrl+K)、主题切换(深色/浅色)等,对于开发者用户群体来说,学习成本低,体验亲切。
当然,这种架构在项目非常庞大时可能会面临可维护性挑战,但对于一个目标明确的中型工具类应用,这不失为一种务实的选择。
3. 核心功能实操与细节拆解
3.1 AI智能体与自主文档管理
这是项目最亮眼的功能。传统的法律AI可能只是一个问答机器人,但这个项目的AI被赋予了**“动手能力”**。
智能体工具链示例: 假设你有一份租赁合同,觉得罚则条款可能有问题。你可以直接对AI说:“Sửa điều khoản phạt trong HĐ thuê mặt bằng ABC cho đúng luật”(修改ABC租赁合同中的罚则条款以符合法律)。AI会自主执行以下步骤:
read_document:定位并读取“ABC租赁合同”的全文内容。search_law:在越南法律数据库中检索关于“合同罚则”的相关规定,例如找到《商法》2005年第301条,其中规定罚金一般不超过违约部分价值的8%。edit_document:找到合同中罚则条款的具体位置,如果发现约定罚金为20%,则会将其修改为不超过8%,并生成修改记录。document_history:展示本次修改的详细日志,说明哪里被改了以及为什么。
这背后的技术实现依赖于LLM的函数调用能力。系统为AI定义了一套完整的工具函数(共24个),并描述了每个工具的用途、输入参数和输出格式。当LLM理解用户指令后,它会判断是否需要以及需要调用哪个工具,然后以结构化格式请求后端执行。后端执行工具后,将结果返回给LLM,LLM再组织成自然语言回复给用户。这个过程可以循环多次,形成一个多步骤的工作流。
实操心得:
- 指令需要具体明确:虽然AI很强大,但初始指令越清晰,效果越好。例如,“列出上个月所有关于‘保密协议’的文档”比“找我的一些文档”要有效得多。
- 权限与安全:在自部署时,务必理解这些工具的强大能力。
edit_document和delete_document(软删除,30天内可恢复)是高风险操作。确保你的用户权限系统(RBAC)设计完善,普通员工可能只有读取权限,只有法务负责人有修改权限。
3.2 合同AI审查:从上传到报告
合同审查是核心应用场景。其流程设计得非常完整:
步骤一:上传与解析支持拖拽上传或批量上传(最多10个文件)。系统会解析文件内容(支持PDF、DOCX、TXT等),提取文本,并尝试自动识别合同类型(如劳动合同、租赁合同)。
步骤二:风险分析与评分AI会逐条分析合同条款,对照越南法律库进行审查。风险被分为10大类(如不利条款、过高罚金、与法律冲突、缺少关键保护条款等),并为每个识别出的问题点赋予LOW/MEDIUM/HIGH/CRITICAL风险等级和一个具体的风险分数(0-100)。
步骤三:生成结构化报告审查结果不是一段笼统的文字,而是一个结构化的JSON数据,便于前端展示和后续处理。报告包含:
- 总体风险评分与等级:让你一眼了解合同整体风险程度。
- 条款级分析:每个有问题条款的具体内容、风险等级、法律依据(精确到法律条文号)和修改建议。
- 缺失条款建议:指出合同可能缺少的关键条款,如“不可抗力”条款,并说明其重要性。
- 合规性概览:以表格形式展示合同在《民法典》、《商法》等主要法律下的合规状态。
步骤四:导出与行动你可以将审查报告导出为Word文档(.docx),直接用于与对方谈判或内部留档。报告中的修改建议非常具体,例如“将第5条罚金从20%修改为不超过8%,以符合《商法》2005年第301条规定”。
避坑指南:AI审查的准确性极度依赖于其背后的法律知识库。项目虽然提供了从
thuvienphapluat.vn等网站爬取数据的脚本,但法律是动态更新的。在用于重要合同前,务必确认你的本地法律数据库是最新的。定期运行爬虫脚本更新数据库,是保证审查效力的关键。
3.3 法律检索(RAG)系统搭建实战
要让AI能准确回答法律问题,构建一个高质量的法律检索系统是关键。项目提供了完整的工具链。
1. 数据获取与爬虫集成项目集成了CrawlKit来从越南主流法律网站爬取数据。你需要:
- 访问
crawlkit.org获取一个免费API密钥(每日100次请求限额)。 - 在
.env文件中配置CRAWLKIT_API_KEY。 - 运行脚本开始爬取,例如:
docker compose exec app python scripts/crawl_thuvien.py。
这个爬虫会抓取法律文书的标题、编号、发布日期、正文、生效状态等结构化信息。
2. 数据处理与向量化原始的法律条文很长,不能直接丢给LLM。需要“分块”处理。
# 运行数据加载和索引脚本 python scripts/load_law_data.py # 将爬取的数据导入数据库 python scripts/index_chunks.py # 进行文本分块、向量化并创建搜索索引index_chunks.py脚本做了几件重要的事:
- 文本分割:按段落或固定长度将长法律文本切成小块(chunks),确保每块信息量适中且语义完整。
- 生成嵌入向量:使用嵌入模型(如OpenAI的
text-embedding-3-small或开源的BAAI/bge-m3)为每个文本块生成向量。 - 构建索引:利用pgvector在PostgreSQL中为这些向量字段创建HNSW索引,这是实现毫秒级相似性搜索的基础。
3. 检索流程优化简单的向量搜索可能因为词汇不匹配而漏掉相关结果。项目在此基础上做了增强:
- 同义词扩展:当用户搜索“HĐ lao động”(劳动合同)时,系统可能同时搜索“hợp đồng lao động”、“hợp động làm việc”等同义或近义词。
- 混合搜索:结合向量相似性搜索和传统全文检索(PostgreSQL的
tsvector)。全文检索擅长关键词匹配,向量搜索擅长语义匹配,两者结合召回率更高。 - 重排序:初步检索出N个结果后,可能用一个更精细的模型(交叉编码器)对结果进行重新排序,将最相关的结果排在最前面。
实操心得:
- 分块策略是灵魂:分块大小和重叠度需要调优。块太大,检索精度低;块太小,可能丢失上下文。对于法律条文,按“条”或“款”进行分块通常是较好的起点。
- 嵌入模型选择:如果使用本地部署,选择针对越南语优化的嵌入模型(如
dangvantuan/vietnamese-embedding)会比通用模型效果更好。 - 测试检索效果:搭建好系统后,一定要用一系列典型问题测试,比如“试用期工资最低标准是多少?”、“公司解散后债务如何处理?”,检查返回的法律条文是否切题。
4. 企业级部署与运维指南
4.1 基于Docker的一键部署
项目强烈推荐使用Docker Compose部署,这能极大简化环境配置。
详细部署步骤:
克隆与配置:
git clone https://github.com/Paparusi/legal-ai-agent.git cd legal-ai-agent cp .env.example .env编辑
.env文件,最核心的配置是ANTHROPIC_API_KEY(你的Claude API密钥)。其他如数据库密码可以保持默认或修改。启动服务:
docker compose up -d这条命令会启动两个容器:一个PostgreSQL 15数据库(包含pgvector扩展),一个运行FastAPI应用的Web容器。
初始化数据: 容器启动后,数据库是空的。你需要手动初始化法律数据库,否则“法律检索”功能无法使用。
# 进入应用容器执行爬虫脚本(推荐,获取最新数据) docker compose exec app python scripts/crawl_thuvien.py # 或者,如果你有备份的数据文件 docker compose exec app python scripts/load_law_data.py docker compose exec app python scripts/index_chunks.py访问应用: 打开浏览器,访问
http://你的服务器IP:8080/static/app.html。你应该能看到登录界面。首次使用需要注册一个账号,该账号会自动关联到一个默认的公司(Tenant)。
系统资源建议:
- 最低配置:1核CPU,1GB内存,2GB磁盘空间。适合测试和少量用户。
- 生产建议:2核CPU,4GB内存,20GB SSD。如果法律文档库很大(超过10万份),需要相应增加存储。
- 网络:确保服务器能稳定访问你所选的LLM API(如
api.anthropic.com)。
4.2 平台超级管理员功能
项目内置了一个多租户(SaaS)架构和强大的平台超级管理员面板,这对于自托管服务给多个团队或客户使用非常有用。
访问方式:部署后,通过/platform-admin路径访问(例如http://localhost:8080/platform-admin),需要使用具有超级管理员角色的账号登录。
管理员面板核心功能:
- 全局仪表盘:查看平台整体数据,如公司总数、用户数、文档数、当日查询量、LLM token消耗估算及成本。
- 多租户管理:可以创建、编辑、禁用不同的“公司”(租户)。可以为每个公司设置独立的订阅计划(免费版、入门版、专业版、企业版),并配置其专属配额(如每日查询次数、合同上传数量上限)。
- 用户管理:查看所有公司的所有用户,可以重置密码、修改用户角色(如成员、管理员)。
- 系统设置:集中配置LLM提供商、文件大小限制、是否开放注册等全局开关。
- 审计日志:记录所有关键操作,如用户登录、合同上传、AI审查、文档修改等,便于安全审计和问题追踪。
实操心得:
- 善用配额管理:在
.env中可以为不同订阅计划设置默认配额。在管理员面板中,你可以为特定公司临时提升或降低配额,这在处理大客户或进行促销时非常灵活。 - 成本监控:LLM API调用是主要成本。管理员面板提供的token消耗统计能帮你预估每月费用,并分析哪些公司或用户是“重度使用者”,便于优化或调整定价策略。
- 数据隔离:数据库设计上,不同公司的数据通过
company_id字段严格隔离。确保你的所有数据查询都正确加上了这个过滤条件,这是多租户系统安全性的基石。
4.3 更新与备份策略
更新到最新版本:
# 进入项目目录 cd legal-ai-agent # 拉取最新代码 git pull origin main # 重新构建并启动容器 docker compose build --no-cache # 如果依赖有更新,建议使用--no-cache docker compose up -d # 查看日志,确认无报错 docker compose logs -f app数据备份: PostgreSQL数据存储在名为legal-ai-agent_pgdata的Docker卷中。备份至关重要。
# 方法1:使用pg_dump备份数据库(推荐) docker compose exec db pg_dump -U postgres legalai > backup_$(date +%Y%m%d).sql # 方法2:备份整个Docker卷 docker run --rm -v legal-ai-agent_pgdata:/source -v $(pwd):/backup alpine tar czf /backup/pgdata_backup_$(date +%Y%m%d).tar.gz -C /source .恢复数据:
# 从SQL文件恢复 cat backup_20231027.sql | docker compose exec -T db psql -U postgres legalai # 从卷备份恢复(需先停止并删除旧容器) docker compose down -v # 警告:这会删除现有卷! docker volume create legal-ai-agent_pgdata docker run --rm -v $(pwd):/backup -v legal-ai-agent_pgdata:/target alpine sh -c "tar xzf /backup/pgdata_backup_20231027.tar.gz -C /target" docker compose up -d5. 常见问题排查与性能调优
5.1 部署与启动问题
问题1:启动后访问页面显示“Internal Server Error”或数据库连接失败。
- 排查:首先查看应用容器日志:
docker compose logs app。常见原因是数据库未就绪应用已启动。PostgreSQL启动需要时间。 - 解决:在
docker-compose.yml中为app服务添加健康检查或依赖等待脚本。一个简单的办法是在启动命令前加一个等待脚本,或者直接重启应用容器:docker compose restart app。
问题2:法律搜索功能返回空结果或错误。
- 排查:确认法律数据库是否已成功初始化。进入数据库容器查询:
docker compose exec db psql -U postgres -d legalai -c "SELECT COUNT(*) FROM law_documents;"。如果结果为0,说明数据库是空的。 - 解决:按前述步骤运行爬虫或数据加载脚本。同时检查
scripts/index_chunks.py是否成功运行,确认document_chunks表中有数据且有向量字段。
问题3:AI聊天或审查响应非常慢。
- 排查:可能是LLM API调用慢或网络问题。查看应用日志中AI调用的耗时。也可能是向量搜索未建索引。
- 解决:
- 确保pgvector的HNSW索引已创建:
docker compose exec db psql -U postgres -d legalai -c "\d document_chunks;"查看索引。 - 考虑更换LLM提供商或模型。GPT-4o Mini比GPT-4o更快更便宜,Claude Haiku比Sonnet更快。
- 检查服务器到LLM API端点的网络延迟。
- 确保pgvector的HNSW索引已创建:
5.2 功能使用问题
问题4:AI智能体无法正确执行“编辑文档”或“移动文件”等工具调用。
- 排查:这通常是LLM的“函数调用”能力或提示词(Prompt)理解问题。打开浏览器开发者工具的“网络”选项卡,查看
/v1/legal/ask接口的请求和响应,观察AI返回的tool_calls字段是否正确。 - 解决:
- 优化指令:确保你的指令足够清晰、无歧义。包含文件名、具体操作和期望结果。
- 检查工具定义:在
src/agents/legal_agent.py中,每个工具都有详细的描述。确保描述清晰说明了工具的用途和参数格式。 - 切换LLM模型:某些模型在工具调用上表现更好。可以尝试从Claude Sonnet切换到GPT-4o,看是否有改善。
问题5:合同审查的风险评分感觉不准确或遗漏了关键问题。
- 排查:审查质量取决于两点:法律知识库的完备性和审查提示词的设计。
- 解决:
- 丰富知识库:确保你的法律数据库包含了与合同类型相关的所有最新法规、司法解释和判例。
- 定制审查规则:项目的审查逻辑写在AI的提示词和后续处理代码中。你可以根据越南当地的法律实践,修改
src/agents/legal_agent.py中关于合同审查的部分,添加或调整风险检查项。例如,针对特定行业(如建筑、金融)的合同,可以加入行业特有的合规检查点。 - 人工复核:切记,AI审查是辅助工具。对于重大合同,必须由专业律师进行最终复核。
5.3 性能与扩展调优
优化1:向量搜索性能
- 调整索引参数:在
scripts/index_chunks.py中,创建pgvector HNSW索引时可以调整m(每个节点的最大连接数)和ef_construction(构建时的动态候选集大小)参数。增加这些值可以提高搜索精度,但会降低构建速度和增大索引体积。对于法律检索,平衡点可能需要实验。# 示例:创建HNSW索引 cur.execute(""" CREATE INDEX ON document_chunks USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64); """) - 优化分块大小:法律条文的分块大小直接影响检索相关性。可以尝试不同的分块策略(按句、按段、按固定字符数),并通过一组标准问题测试召回率和准确率。
优化2:API响应速度
- 启用流式响应:对于AI聊天,务必使用
/v1/legal/ask-stream端点(SSE),让用户能边生成边看到结果,提升体验感。 - 实现缓存:对于常见的法律问题(如“最低工资标准”),其答案在短期内不会变化。可以在FastAPI层使用
redis或memcached对问答结果进行缓存,设置合理的TTL(如24小时),大幅减少对LLM和向量数据库的调用。 - 数据库连接池:确保使用像
asyncpg这样的异步数据库驱动,并配置合适的连接池大小,避免数据库连接成为瓶颈。
优化3:成本控制
- 设置用量配额与告警:在管理员面板中,为每个公司设置严格的每日/每月查询次数和Token消耗上限。当用量接近阈值时,系统应能发送告警邮件或通知。
- 使用性价比更高的模型:对于简单的法律问答,可以使用Claude Haiku或GPT-4o Mini。仅在复杂的合同审查和起草任务中调用更强大的Sonnet或GPT-4o。
- 压缩提示词:在将合同文本发送给LLM前,可以尝试用更小的模型(如Haiku)先进行摘要,再将摘要和关键条款发送给大模型进行深度分析,以减少输入的Token数量。