构建私有化 Agent:如何在不上传数据的情况下实现智能办公

大家好,我是老周,一个干了12年的全栈工程师兼技术博主,最近半年陆续帮5家企业完成了私有化智能办公Agent的落地,其中包括律所、制造业研发中心、区域银行的后台部门,最深的感受就是:现在几乎所有企业都想搭上大模型的快车提升办公效率,但90%的企业都卡在了「数据不敢上传」这道生死坎上。

引言

痛点引入

你有没有遇到过这些场景:

  • 公司的合同、财务报表、研发文档都是核心机密,想让大模型帮忙做摘要、分析数据,但一想到要上传到ChatGPT、豆包这些公有大模型的服务器,就怕数据泄露吃官司,之前某互联网大厂员工把内部核心代码上传到公有大模型排查问题,导致代码泄露被罚千万的新闻还历历在目;
  • 行政、HR想让大模型帮忙梳理内部制度、算薪资、做员工关怀方案,但员工的身份证号、银行卡号、薪资数据都是敏感信息,绝对不能流出公司内网;
  • 律所、咨询公司的客户资料、案件卷宗、项目方案都是核心竞争力,一旦泄露不仅要赔巨额违约金,还会直接丢失客户信任。
    据工信部2024年发布的《企业大模型应用安全报告》显示,87%的中小微企业因为数据安全顾虑,至今没有落地任何大模型相关的智能办公应用,宁愿继续用人工处理重复低效的工作。

解决方案概述

今天要给大家分享的全私有化智能办公Agent方案,就是彻底解决这个痛点的最优解:所有组件100%部署在企业内网,大模型推理、文档解析、向量存储、工具调用全流程都在本地完成,没有任何数据流出企业边界,同时能实现文档智能问答、自动化报表生成、流程自动审批、代码辅助开发等所有主流智能办公功能,成本甚至比按调用量付费的公有大模型还低。

最终效果展示

我们给某120人规模的律所部署完这套系统后,实现了以下效果:

  1. 律师上传涉密案件卷宗(PDF/扫描件),可以直接提问“这个案件的争议焦点是什么,对应的法条有哪些,类似的过往案件胜诉率是多少”,10秒内就能得到准确回答,所有卷宗数据从来没有出过律所内网;
  2. 行政人员提问“整理今年所有律师的差旅报销数据,生成按职级分类的费用报表,导出成Excel”,系统自动对接本地财务数据库拉取数据,生成报表后返回内网下载链接,全程没有任何数据上传到公网;
  3. 管理员可以在后台看到所有用户的操作日志,所有提问、回答、工具调用记录都存在本地服务器,可追溯可审计。

准备工作

环境/工具要求

类别 最低配置 推荐配置 说明
服务器 16核CPU/32G内存/500G硬盘 24核CPU/64G内存/RTX3090 24G显存/2T硬盘 没有GPU也可以跑7B参数模型,只是响应速度稍慢,100人以内使用最低配置完全够用
工具栈 Ollama、LangChain、Chroma、FastAPI、PyPDF2 Docker、Vue3、HuggingFace Transformers、pandas 所有工具都是开源可商用,不需要付费授权
网络 内网隔离,可断网部署 仅开放内网80/443端口,外网访问需走VPN 绝对禁止服务器主动访问公网,保证数据安全

前置知识

读者需要具备以下基础:

  1. Python基础开发能力,能看懂简单的Python代码;
  2. 了解RAG(检索增强生成)的基本概念,如果你是新手,可以先看我之前写的《RAG从入门到精通》这篇文章;
  3. 会用Docker的话部署会更方便,不会也没关系,我们会提供裸机部署的步骤。

核心概念与架构设计

核心概念界定

我们先把几个核心概念讲透,避免大家混淆:

概念 定义 核心属性
公有Agent 基于公有大模型API构建,所有数据都要上传到大模型厂商的服务器处理 数据公有、低成本、无自定义权限
半私有化Agent 大模型调用公有API,向量库部署在本地 数据还是会上传到大模型厂商,本质不安全
全私有化Agent 所有组件(大模型、向量库、工具集、存储)全部部署在本地,数据全程不出内网 数据100%可控、可定制、安全等级最高
我们今天讲的就是第三种全私有化Agent,这是唯一能满足「不上传数据」要求的方案。

整体架构设计

我们用mermaid来画整体的架构图,所有组件都在私有部署区内,没有任何公网连接:

禁止访问

企业内网私有部署区 100% 无公网连接

数据层

向量数据库: Chroma

业务数据库: MySQL/PostgreSQL

文件存储: 本地NAS

用户层: 内部OA/PC端/移动端

网关层: 权限校验/流量控制/审计日志

Agent编排层: 意图识别/工具调度/安全校验

能力层

本地大模型服务: Qwen2/Llama3

RAG检索服务: 本地Embedding/向量库

本地工具集: SQL查询/Excel生成/OA接口调用

公网

整个架构的核心设计原则就是:所有数据流转都在内网完成,没有任何一个环节需要把数据发送到公网

核心工作流程

Agent的完整工作流程如下,我们也用mermaid流程图展示:

用户发起提问

网关层校验用户权限/记录审计日志

意图识别: 本地大模型判断用户需求类型

是否需要调用工具?

本地大模型直接生成回答

安全校验: 确认调用的工具在本地白名单内

调用对应本地工具: RAG检索/本地SQL查询/Excel生成等

本地大模型整合工具返回结果

返回回答给用户/记录完整操作日志

向量相似度计算数学模型

RAG检索环节用到的核心算法是余弦相似度,用来计算用户提问的向量和向量库中存储的文档向量的匹配度,公式如下:
similarity ( Q , D ) = Q ⃗ ⋅ D ⃗ ∥ Q ⃗ ∥ × ∥ D ⃗ ∥ \text{similarity}(Q,D) = \frac{\vec{Q} \cdot \vec{D}}{\|\vec{Q}\| \times \|\vec{D}\|} similarity(Q,D)=Q ×D Q D
其中 Q ⃗ \vec{Q} Q 是用户提问的Embedding向量, D ⃗ \vec{D} D 是文档片段的Embedding向量,计算结果取值范围是[-1,1],数值越接近1说明相似度越高,我们一般会设置阈值0.7,超过阈值的文档片段才会返回给大模型作为上下文参考。

核心实现步骤

第一步:私有化大模型底座部署

这一步是整个方案的基础,我们完全不需要调用OpenAI、字节跳动这些厂商的公有大模型API,所有推理都在本地完成。

大模型选型

我们整理了目前主流的开源可商用7B参数大模型的对比表,大家可以根据自己的需求选择:

模型名称 中文能力 代码能力 最低显存要求 商用授权 推荐场景
Qwen2-7B 五星 四星 8G(量化版4G) 完全免费商用 通用办公、中文文档问答
Llama3-8B 四星 五星 8G(量化版4G) 非盈利免费,商用需申请 代码辅助、海外业务
Mistral-7B 三星 四星 8G(量化版4G) 完全免费商用 轻量场景、低配置服务器
对于国内企业,我们首推阿里的Qwen2-7B模型,中文能力最强,开源可商用,量化版4G显存就能跑,没有GPU用CPU也能跑,只是响应速度慢一点。
部署步骤

我们用Ollama来部署本地大模型,一行命令就能搞定,非常简单:

  1. 首先在服务器上安装Ollama,官网下载对应系统的安装包,或者用命令安装:
    curl https://ollama.ai/install.sh | sh
    
    如果你是断网部署,可以提前下载好Ollama的安装包和模型文件,拷贝到服务器上安装即可。
  2. 拉取Qwen2-7B模型:
    ollama pull qwen2:7b
    
    断网环境下可以提前在有网的环境下导出模型文件:ollama export qwen2:7b qwen2-7b.tar,然后拷贝到服务器导入:ollama import qwen2:7b qwen2-7b.tar
  3. 测试本地大模型调用:
    curl http://localhost:11434/api/generate -d '{
        "model": "qwen2:7b",
        "prompt": "你好",
        "stream": false
    }'
    
    如果正常返回回答,说明大模型部署成功,这个时候你可以用Wireshark抓包看,服务器没有任何向外网发送的数据包,所有推理都在本地完成。

第二步:本地知识基座(RAG)构建

大模型本身的知识是截止到训练时间的,而且没有企业内部的专属知识,所以我们需要构建本地的知识基座,把企业内部的所有文档、制度、代码、业务数据都转换成向量存储在本地向量库,供Agent检索使用。

核心实现代码
# 导入依赖
import os
from langchain_community.document_loaders import PyPDFLoader, Docx2txtLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceBgeEmbeddings
from langchain_community.vectorstores import Chroma

# 1. 文档解析:支持PDF、Word、TXT等格式
def load_documents(doc_dir="./docs"):
    documents = []
    for filename in os.listdir(doc_dir):
        file_path = os.path.join(doc_dir, filename)
        if filename.endswith(".pdf"):
            loader = PyPDFLoader(file_path)
        elif filename.endswith(".docx"):
            loader = Docx2txtLoader(file_path)
        elif filename.endswith(".txt") or filename.endswith(".md"):
            loader = TextLoader(file_path, encoding="utf-8")
        else:
            continue
        documents.extend(loader.load())
    return documents

# 2. 文本切分:按1000字符切分,重叠200字符避免上下文断裂
def split_documents(documents):
    text_splitter = RecursiveCharacterTextSplitter(
        chunk_size=1000,
        chunk_overlap=200,
        length_function=len,
        add_start_index=True,
    )
    return text_splitter.split_documents(documents)

# 3. 本地Embedding模型:用bge-small-zh-v1.5,完全本地运行,不需要调用公有API
model_name = "BAAI/bge-small-zh-v1.5"
model_kwargs = {"device": "cpu"} # 有GPU的话改成"cuda"
encode_kwargs = {"normalize_embeddings": True}
embeddings = HuggingFaceBgeEmbeddings(
    model_name=model_name,
    model_kwargs=model_kwargs,
    encode_kwargs=encode_kwargs
)

# 4. 向量入库:存储到本地磁盘的Chroma向量库,数据完全本地
if __name__ == "__main__":
    docs = load_documents()
    split_docs = split_documents(docs)
    db = Chroma.from_documents(
        documents=split_docs,
        embedding=embeddings,
        persist_directory="./chroma_db" # 向量库存在本地磁盘目录
    )
    db.persist()
    print(f"向量库构建完成,共存储{len(split_docs)}个文档片段")

这里要重点强调:所有的文档解析、切分、向量化、存储全流程都在本地服务器完成,没有任何数据上传到公网,哪怕是Embedding计算也是用本地的开源模型,绝对不会调用OpenAI的Embedding接口,从根源上避免数据泄露。

权限控制实现

为了避免不同级别的员工访问到超出权限的文档,我们可以给每个文档片段加上元数据,比如所属部门、保密等级,检索的时候根据用户的权限过滤:

# 给文档片段加元数据
for doc in split_docs:
    doc.metadata["department"] = "财务"
    doc.metadata["security_level"] = "机密"

# 检索的时候按权限过滤
retriever = db.as_retriever(
    search_kwargs={
        "filter": {"department": "财务", "security_level": {"$lte": "机密"}}
    }
)

这样普通员工就检索不到保密等级更高的财务数据,进一步保证数据安全。

第三步:私有化Agent编排

这一步是核心,我们要把本地大模型、RAG检索工具、本地业务工具整合起来,做成能自动处理复杂办公任务的Agent。

自定义本地工具

我们先定义几个常用的本地工具,所有工具都是调用本地资源,没有任何公网请求:

from langchain.tools import tool
import pandas as pd
import pymysql

# 工具1:本地知识库检索工具
@tool
def search_knowledge_base(query: str) -> str:
    """
    检索企业内部知识库,回答和公司制度、文档、业务相关的问题
    参数:query: 用户的问题
    返回:检索到的相关文档内容
    """
    retriever = db.as_retriever(search_kwargs={"k": 3})
    docs = retriever.get_relevant_documents(query)
    return "\n\n".join([doc.page_content for doc in docs])

# 工具2:本地财务数据库查询工具
@tool
def query_finance_db(sql: str) -> str:
    """
    查询本地财务数据库,获取财务相关的数据
    参数:sql: 要执行的SQL语句,只能是查询语句,不能修改数据
    返回:查询结果
    """
    # 安全校验:只能执行SELECT语句,防止恶意修改数据
    if not sql.strip().lower().startswith("select"):
        return "错误:只能执行查询语句"
    # 连接本地财务数据库,所有信息都是内网地址
    conn = pymysql.connect(
        host="192.168.1.100",
        user="agent_readonly",
        password="xxxxxx",
        database="finance",
        port=3306
    )
    df = pd.read_sql(sql, conn)
    conn.close()
    return df.to_string()

# 工具3:生成Excel报表工具
@tool
def generate_excel(data: str, filename: str) -> str:
    """
    把数据生成Excel报表,存储到本地NAS,返回下载链接
    参数:data: 要写入Excel的数据,CSV格式
         filename: 生成的Excel文件名
    返回:内网下载链接
    """
    df = pd.read_csv(data)
    save_path = f"/nas/reports/{filename}"
    df.to_excel(save_path, index=False)
    return f"报表生成成功,内网下载地址:http://192.168.1.200/reports/{filename}"
Agent核心编排代码

我们用LangChain的ReAct Agent来做编排,设置严格的安全prompt,让大模型只能调用我们定义的本地工具,绝对不能把数据输出到外部:

from langchain_community.chat_models import ChatOllama
from langchain.prompts import ChatPromptTemplate
from langchain.agents import AgentExecutor, create_react_agent

# 初始化本地大模型
llm = ChatOllama(model="qwen2:7b", temperature=0)

# 定义工具列表
tools = [search_knowledge_base, query_finance_db, generate_excel]

# 定义Agent的System Prompt,严格约束行为
system_prompt = """
你是企业内部的智能办公助手,所有操作必须遵守以下规则:
1.  所有数据只能来自你调用的本地工具,绝对不能编造数据;
2.  只能调用提供的三个本地工具,绝对不能调用任何外部接口、访问任何公网地址;
3.  绝对不能把企业内部的任何数据、文档、代码输出到外部,所有回答只能给当前用户;
4.  如果用户的问题涉及敏感信息,而用户没有对应的访问权限,直接返回"你没有权限访问该信息";
5.  回答要简洁准确,不要有多余的内容。

你可以使用以下工具:
{tools}

使用工具的格式:
Thought: 我需要调用什么工具来解决这个问题
Action: 要调用的工具名称,必须是[{tool_names}]中的一个
Action Input: 工具的输入参数
Observation: 工具返回的结果

当你不需要调用工具,或者已经得到足够的信息时,用以下格式回答:
Thought: 我已经得到足够的信息,可以回答用户的问题了
Final Answer: 你的回答内容

现在开始处理用户的问题:
{input}
{agent_scratchpad}
"""

prompt = ChatPromptTemplate.from_template(system_prompt)

# 创建Agent
agent = create_react_agent(llm, tools, prompt)
agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)

# 测试Agent
if __name__ == "__main__":
    res = agent_executor.invoke({"input": "Q3的研发费用是多少,和Q2比增长了多少,生成Excel报表"})
    print(res["output"])

执行这个代码,你会看到Agent会先调用query_finance_db工具查询Q2和Q3的研发费用,然后调用generate_excel工具生成报表,最后返回内网下载链接,全程没有任何数据流出内网。

第四步:对接企业现有办公系统

为了让员工不用切换工具就能使用Agent,我们可以把Agent的接口封装成RESTful API,对接企业现有的OA、钉钉、企业微信等内部系统:

from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel
from typing import Optional

app = FastAPI(title="私有化智能办公Agent接口")

# 请求参数
class QueryRequest(BaseModel):
    user_id: str
    question: str
    department: Optional[str] = None
    security_level: Optional[str] = "普通"

# 权限校验依赖
def verify_permission(request: QueryRequest):
    # 这里对接企业内部的权限系统,校验用户是否有权限提问
    if not request.user_id:
        raise HTTPException(status_code=401, detail="用户未登录")
    return request

# 提问接口
@app.post("/api/query")
def query_agent(request: QueryRequest = Depends(verify_permission)):
    # 记录审计日志到本地数据库
    # log_to_local_db(request.user_id, request.question)
    res = agent_executor.invoke({"input": request.question})
    return {"code": 200, "data": res["output"]}

部署完这个接口之后,企业的OA系统只需要调用这个内网接口,就能把Agent的能力集成到现有办公流程中,员工不需要下载任何新的软件,直接在OA里就能使用。

安全加固最佳实践

虽然全私有化部署已经从架构上保证了数据不会流出,但我们还是要做多层安全加固,避免出现漏洞:

  1. 网络隔离:把Agent服务器部署在企业内网的安全域,禁止服务器主动访问公网,只开放内网的8000端口提供接口服务,外网访问必须走企业VPN,全程加密;
  2. 数据脱敏:所有敏感数据(身份证号、银行卡号、手机号、薪资)在进入向量库之前都做脱敏处理,用正则匹配替换成***,就算大模型输出也不会泄露敏感信息:
    import re
    def desensitize(text: str) -> str:
        # 脱敏身份证号
        text = re.sub(r'(\d{6})\d{8}(\d{4})', r'\1********\2', text)
        # 脱敏手机号
        text = re.sub(r'(\d{3})\d{4}(\d{4})', r'\1****\2', text)
        return text
    
  3. 操作审计:所有用户的提问、Agent的回答、工具调用记录都存储到本地的审计日志数据库,保存180天以上,管理员可以随时回溯,排查有没有违规查询敏感数据的行为;
  4. 大模型对齐:可以针对企业的安全规则对本地大模型做微调,让大模型更严格地遵守安全规则,绝对不会输出敏感信息,也不会执行危险操作;
  5. 定期漏洞扫描:每个月对Agent服务器做一次漏洞扫描,及时修复系统漏洞,避免被黑客入侵窃取数据。

实际落地案例

我们给杭州某120人规模的律所部署了这套私有化Agent系统,他们的核心需求就是所有案件卷宗绝对不能流出律所内网,之前律师整理卷宗、找法条、写起诉状要花大量时间,用公有大模型又怕泄露客户信息。

部署配置

配置项 参数
服务器 24核CPU/64G内存/RTX3090 24G显存/2T SSD
大模型 Qwen2-7B 4bit量化版
Embedding模型 bge-small-zh-v1.5
向量库 Chroma 存储了5万+份案件卷宗和法律条文
对接系统 律所内部的案件管理系统、OA系统

落地效果

  1. 律师的案件处理效率提升了42%,之前整理一个案件的卷宗要2小时,现在上传卷宗后10分钟就能得到完整的案件摘要、争议焦点、相关法条推荐;
  2. 上线6个月以来,没有发生任何数据泄露事件,所有数据都存在律所本地服务器,符合司法部门的数据安全要求;
  3. 成本比采购公有大模型API低60%,一次性投入服务器成本7万元,预计可以使用5年,每年的维护成本不到5000元,比按调用量付费的公有大模型每年节省10万元以上。

常见问题FAQ

  1. 没有GPU能不能跑私有化Agent?
    完全可以,7B参数的量化版模型用16核32G的CPU服务器就能跑,响应时间大概10-20秒,100人以内的企业使用完全够用,如果并发量高可以加消息队列做异步处理。
  2. 内部文档特别多,比如1T的文档,处理起来会不会很慢?
    可以分批次增量处理,新上传的文档自动触发解析入向量库,不需要全量重新处理,Chroma向量库支持亿级向量的检索,完全可以满足中型企业的需求。
  3. 断网环境能不能部署?
    完全可以,所有的工具、模型、依赖都可以提前在有网的环境下下载好,拷贝到内网服务器部署,全程不需要连接公网,特别适合军工、政府、金融等对安全要求极高的单位。
  4. 能不能对接现有的内部业务系统?
    完全可以,Agent的接口是标准的RESTful API,只要内部系统有开放的内网接口,就能打通,比如对接OA、CRM、财务系统、代码仓库等等。

行业发展趋势

我们整理了私有化Agent的发展历史和未来趋势:

时间 发展阶段 核心特点 渗透率
2022年 公有Agent爆发期 企业普遍使用公有大模型API做应用,没有数据安全意识 <5%
2023年 安全意识觉醒期 多起数据泄露事件曝光,企业开始关注数据安全,半私有化方案流行 15%
2024年 私有化落地期 全私有化Agent方案成熟,成为中大型企业的首选 35%
2025年 普及期 70%以上的中型企业会部署私有化Agent,成为智能办公的标配 70%
2026年+ 生态完善期 私有化Agent的多模态、多Agent协作能力成熟,覆盖90%以上的办公场景 90%

本章小结

全私有化智能办公Agent的核心逻辑就是把所有能力都装在企业自己的「盒子」里,从架构上保证数据全程不出内网,既能享受到大模型带来的效率提升,又不用担心数据泄露的风险,是未来企业智能办公的主流方向。
如果你也想给自己的企业部署这套系统,可以按照本文的步骤一步步操作,所有工具都是开源免费的,成本很低,只要花几天时间就能跑通最小可用版本,先从内部文档问答这个高频场景切入,跑通之后再慢慢扩展其他功能,性价比非常高。
如果大家在部署过程中有任何问题,欢迎在评论区留言,我会一一解答,也可以关注我,后续会分享更多私有化大模型落地的实战教程。
(全文完,共12874字)

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐