AI应用开发实战:从零搭建RAG企业知识库问答系统
2026/9/2 3:45:30 网站建设 项目流程

最近两年,AI 领域始终存在一个很有意思的错位:一边是大模型的能力每隔几个月就刷新一次认知,一边是企业里真正跑在生产环境里的 AI 功能少得可怜。做 AI 产品的人经常被问到同一个问题:“你们是不是在追热点?大模型已经这么强了,我们到底还能做什么?”

同一个行业里,有人觉得 AI 热得过头了,也有人觉得 AI 市场被严重低估了。后一种观点里,比较有代表性的一位是风险投资公司 Benchmark 合伙人 Eric Vishria。他在相关讨论中表达的核心判断是:AI 的商业化进度、应用覆盖范围,以及它改变工作流的速度,可能比市场上大多数人预期的都要大。换句话说,不是 AI 没机会,而是市场把 AI 的机会看得太小了。

你可能会想:投资人的判断,和我一个写代码的有什么关系?关系很大。如果 AI 真的被低估,那意味着未来三到五年,企业会需要大量能把模型变成产品的工程师。市场低估的并不是“ChatGPT 式聊天”,而是“用 AI 重构现有工作流”这件事本身。对技术人来说,这是一个清晰的方向信号。

这篇文章会做三件事:先拆解“AI 被低估”背后的技术与投资逻辑;再从工程视角分析 AI 应用开发真正的瓶颈;最后用一个最小但完整的企业知识库问答项目,把 RAG 这条技术路径完整跑通,包括环境、代码、验证、排查和最佳实践。读完这篇文章,你不仅能理解“AI 市场被低估”对开发者意味着什么,而且能立刻上手搭建一个可复用的 AI 应用原型。

1. 这篇文章真正要解决的问题

如果只把“AI 市场被低估了”当成一个宏观话题,听完就过去了,那对技术人几乎没有价值。这篇文章从一开始就有一个明确的立场:它不是一个投资分析问题,而是一个工程机会问题。

技术人员面对这种判断时,最容易犯的错误是把它解读成“赶紧去学大模型算法”。但真正需要关注的是另一个侧面:如果 AI 真的会进入每一个业务流程,那么软件的工程量会有多大?这个问题的答案,才直接决定技术选型、岗位需求和职业发展方向。

目前大多数团队的现状是:Demo 做得很快,上线上得很慢。原因也很简单,调用一个模型接口只需要几分钟,但要把模型、数据、评测、监控、权限、交互这些环节组合成稳定服务,工作量会大一个数量级。当前阶段,多数团队卡在“能用”和“能上线”之间。而这条鸿沟,恰恰是开发者的机会所在。

因此,本文不打算花大量篇幅复述大模型的原理,也不会劝你训练自己的基座模型。我想解决的是四件事:

  1. 说清楚 Eric Vishria 代表的投资判断为什么值得关注,但不神化它;
  2. 把“被低估”翻译成三个和技术直接相关的核心判断;
  3. 分析 AI 应用开发中真正稀缺的能力,以及开发者该从哪里切入;
  4. 带你从零跑通一个基于 RAG 的企业知识库问答项目,把判断落到可操作的技术动作上。

如果你正在思考“要不要在项目里引入 AI”,或者已经在做 AI 应用但觉得效果不稳定,这篇文章会比较适合你。

2. 谁在说“AI 被低估”:Eric Vishria 与 Benchmark 的视角

在看待一个观点之前,先了解说话人的位置是有必要的。Eric Vishria 是 Benchmark 的普通合伙人。Benchmark 是硅谷老牌风险投资公司,以长期主义和小规模团队著称,历史上曾经投资过 Workday、Uber 等公司。Eric 本人则有深厚的技术和产品背景,早期创业做过视频技术公司 Ooyala,后来担任多家技术公司的高管。因此,他对企业软件和基础设施的理解,比一般只看财务模型的投资人更技术化。

在技术圈里,互联网行业的人习惯于把 VC 的话解读成“为了推自己的项目”,这种怀疑有一定道理,但不应该因此忽略背后的推导逻辑。成熟的投资人,尤其是做早期风险投资的人,判断技术浪潮通常不是看短期热度,而是看三条曲线。

第一条是需求曲线:AI 是否在从“开发者玩具”变成“企业必需品”?第二条是成本曲线:单位智能的成本是在上涨还是持续下降?第三条是工作流迁移曲线:企业引入 AI 后,是否会不可逆地改变原来的工作方式?

Eric 这类投资人之所以认为 AI 市场被低估,本质上是因为这三条曲线都在朝同一个方向移动。需求侧,AI 已经从聊天进入了代码生成、文档处理、客服、运维、销售、法律和医疗等场景;成本侧,模型推理成本在过去几年快速下降,小模型和量化部署让 AI 功能不再昂贵;工作流侧,一旦团队适应了 AI 辅助的流程,就很难回到过去。

当然,我并不是说投资人的每个判断都会应验,也不是让大家把这句话当成技术决策的充分依据。作为工程师,我们要做的是把握其中可以被验证、被拆解的部分。AI 市场是否被高估或低估,短期内没有人能打包票,但“AI 应用的工程化需求将持续增长”,这是可以从技术趋势和历史经验中得出的一致判断。

3. 被低估的到底是什么:三个技术判断

“AI 市场被低估”这句话说出来很容易,但如果不拆开看,很容易被理解成一句正确的废话。我认为,这句话背后真正有价值的,是以下三个技术判断。

3.1 被低估的不是聊天,而是工作流重构

绝大多数人接触 AI,是从聊天机器人开始的。但聊天只是入口,AI 真正高价值的部分,是把大模型、Agent、工具调用接入现有业务系统。比如 Java 生态中出现了 Spring AI 这类框架,就是把模型能力以 Spring 的方式注入到企业应用里;Python 生态里有大量工具处理文档、数据库和运维平台;前端开发工具链也在快速接入 AI。这个趋势意味着,AI 不只是少数算法工程师的玩具,而是每一位应用开发者的基础设施。

一旦 AI 被嵌入到业务流程中,它的价值就不再是“回答一个有趣的问题”,而是直接参与生产决策、代码审查、故障排查、客服处理、内容生成等高频操作。工作流一旦被重构,回退成本会变得很高,这种不可逆性会推动需求曲线持续向上,而不是一次性的项目采购。

3.2 被低估的是推理成本下降的速度

很多人判断 AI 是否有规模化价值时,用的还是“大模型调用很贵”的旧标尺。事实上,模型量化、蒸馏、MoE 架构、专用推理芯片、缓存和本地部署方案的发展,正在让单位智能的成本快速下降。成本下降带来的不只是预算节省,而是打开了全新的场景边界。

过去,让一个 AI 去分析全部日志、生成全部测试用例、审查每一段代码,在成本上不划算;当成本降到足够低时,企业会开始尝试“让 AI 先跑一遍”。这种“先跑一遍”的习惯一旦建立,就会产生大量新的工程需求。这也是为什么我始终认为,AI 应用开发的前景比很多人想象的更大,关键不在于模型能力,而在于成本结构已经到了爆发的临界点。

3.3 被低估的是 AI 工程实践的复杂度

第三个判断,可能是对开发者最重要的。模型能力增长很快,但工程能力的成熟度远远落后于模型。我经常看到团队把模型选型做得很好,却在数据清洗、切块策略、Prompt 评测、链路追踪、效果回归这些环节上反复踩坑。

市场低估的,正是 AI 工程实践这个环节的复杂度和价值。许多团队以为“接入模型 API 就算完成 AI 功能”,结果一上线就发现回答不可控、无法解释、不能评测、出错后难回滚。这些问题需要一个完整的技术栈来解决,而不是靠换一个更强模型就能绕过。

下面的表总结了常见认知与工程现实的差异:

常见认知工程现实
AI 应用 = 调用大模型 API生产级应用需要数据管道、链路追踪、权限、评测、灰度
模型能力强,回答质量自然高回答质量取决于检索、上下文、Prompt、评测闭环
AI 开发门槛非常低生产级门槛很高,调试与回归成本被严重低估
只要选对模型就成功数据治理、版本管理和回滚机制同样决定成败

这三个判断放在一起,结论就很清晰了:AI 被低估,最终体现在应用层的工程量被低估。而这正是普通开发者和企业级团队最值得投入的方向。

4. 从市场回到工程:AI 应用开发最缺的是什么

既然 AI 市场的工程量被低估,那问题就来了:当前 AI 应用开发到底最缺什么?

先给出一个明确判断:缺的不是模型,而是“高质量交付 AI 系统的工程能力”。很多人以为 AI 应用开发就是“调 Prompt 再加个接口”,实际上,真正像样的 AI 应用开发,是一个完整软件工程问题。

一个生产级 AI 应用,至少要经历这样的链路:需求定义、数据准备、模型选择、实验评估、部署上线、监控反馈。在传统软件开发中,前几步已经相对成熟,但在 AI 应用里,数据准备和实验评估的复杂度会被放大。比如一个企业内部知识库问答项目,你首先要想清楚:文档格式怎么处理?质量如何保证?切块多大合适?检索结果如何排序?模型回答如何评测?知识更新后索引怎么同步?回答错了如何追溯?

这些问题没有一件可以靠“模型能力”自动解决。它们需要的恰恰是 AI 工程实践:评测数据集建设、Prompt 版本管理、RAG 检索调优、Agent 工具编排、模型部署与降级方案。这些能力,是模型公司不会替你做的,也是应用开发者的核心竞争力。

另一个被低估的特点是:AI 编程工具的普及,并没有让高级工程师贬值,反而让资深工程师的价值更突出。因为 AI 生成代码之后,审查、调试、边界确认、架构把控,都需要有经验的人来完成。同样的 AI 编程提示词,新手和专家写出来的结果完全不同。也就是说,AI 市场被低估,意味着“能把 AI 落到生产环境”的工程师会更稀缺。

所以,如果你想切入这个方向,最稳的起点不是去研究模型训练,而是先掌握 AI 应用的工程链路。RAG 因为是结合了数据、检索、生成、评测的典型场景,几乎可以看作 AI 应用开发的第一课。

5. AI 应用开发第一课:RAG 的概念与边界

5.1 为什么需要 RAG:大模型会“胡说”

大模型的知识来自训练数据,而训练数据有截止时间,也不可能覆盖企业内部资料。直接让模型回答一个企业内部的、训练时没见过的问题,它要么答不上来,要么会一本正经地编一个答案。这种现象在行业里叫“模型幻觉”,是 AI 落地中最常见也最危险的问题之一。

5.2 RAG 是什么

RAG(Retrieval-Augmented Generation,检索增强生成)的整体思路非常直观:先从一个知识库中检索出和问题最相关的资料,再把这些资料连同问题一起交给大模型,让它基于这些资料来回答。

把它理解成一场“开卷考试”就好理解得多。闭卷模式下,模型只能靠记忆作答,遇到没见过的内容就会编;开卷模式下,我们把相关资料放在桌面上,约束模型“根据桌面上的资料答题”,既能回答得更准确,又能在出错时追溯到来源。一个基础的 RAG 流程包括五个关键环节:

  1. 加载文档,把企业内部资料读入系统;
  2. 分块,把长文本切成合适长度的片段,同时保留一定重叠;
  3. 向量化,用嵌入模型把每个片段转换成向量;
  4. 向量存储,把向量写入向量数据库,例如 Chroma、Milvus、Qdrant;
  5. 检索与生成,用户提问时先检索相关片段,再构造 Prompt 交给大模型生成答案。

在这个过程中,最难的不是调用模型,而是切块策略、检索质量、Prompt 设计和评测闭环。

5.3 RAG 和长上下文窗口怎么选

现在很多模型支持很长的上下文窗口,有人会问:既然一次能塞几百万字,为什么还要做 RAG?

这是一个很实际的问题。长上下文适合处理单份超长文档,比如完整的代码仓库或整本报告;但它的成本会随长度快速上升,而且当资料特别长时,模型对中间内容的关注度会下降,容易出现“信息被淹没”的问题。RAG 则是先把最相关的片段挑出来,只把这些片段送进模型,成本更低,还更容易保证来源可追溯。

维度RAG长上下文直接输入
调用成本只送检索后的少量片段,成本低全量输入,成本随长度增长
准确性来源依赖切块和检索质量依赖模型对长文的注意力
更新方式只更新索引库即可,不需要改模型需要替换上下文,容易丢失信息
可追溯性可以返回来源文档追溯比较困难
适合场景企业知识库、FAQ、客服、运维问答单份超长文档分析、代码仓理解

5.4 什么时候不要用 RAG

RAG 不是万能的。如果业务问题需要跨多个文档进行多步推理,比如“根据近三个月所有项目的报表,找到成本最高的三个项目并分析原因”,单纯 RAG 可能不够,需要结合 Agent 做多轮检索、工具调用和中间计算。如果问题主要涉及结构化表格的大量计算,应该由数据库或代码解释器完成,而不是让模型去读纯文本。理解边界,才能选对技术方案。

6. 环境准备与前置条件

在开始项目之前,先把环境准备好。本文示例采用 Python 3.9 以上的版本,使用到的核心工具包括:

  • OpenAI 兼容的模型服务:可以是云厂商提供的 API,也可以是本地部署 AI 模型。只要服务支持 OpenAI 协议,代码逻辑基本不用改。
  • Chroma:轻量级向量数据库,适合做本地原型验证。
  • SentenceTransformer:负责把文本转换成向量,示例中使用 BAAI/bge-small-zh-v1.5,这是一个在中文场景下常用的小型嵌入模型。
  • Python 依赖管理:直接使用 pip 安装所需包。

项目目录结构如下:

rag-demo/ ├── docs/ │ └── sample.txt ├── .env ├── requirements.txt └── rag_demo.py

先创建requirements.txt

# requirements.txt openai chromadb python-dotenv sentence-transformers

版本请以实际项目安装结果为准,本文重点演示完整思路。建议用一个干净的环境(虚拟环境)来安装,避免和系统依赖冲突。

创建.env文件,用于保存模型服务的访问配置:

# .env # 请替换成你自己的 API Key 和接口地址 OPENAI_API_KEY=sk-your-key-change-me OPENAI_BASE_URL=https://your-openai-compatible-endpoint/v1 LLM_MODEL=your-model-name

要注意,这里的关键是配置一个“OpenAI 兼容”的服务端点。国内云厂商的模型服务、企业内网的模型网关、本地部署的模型服务,只要协议兼容,都可以直接替换。不要把你的真实密钥提交到代码仓库,这一点在生产环境尤其重要。

7. 完整示例:用 RAG 搭建一个本地知识库问答工具

接下来,我们用一个最小可运行的项目,把 RAG 完整流程跑通。为了让示例贴近真实场景,我准备了一份企业运维手册的片段作为知识库内容。

7.1 准备测试文档

创建docs/sample.txt,内容如下:

本手册用于帮助运维团队快速处理服务器负载异常。 1. 当 CPU 使用率持续 5 分钟超过 80% 时,应先查看进程列表,确定占用最高的进程。 2. 如果进程属于业务应用,优先考虑临时扩容,同时检查应用日志中的慢查询。 3. 如果进程属于日志处理任务,观察任务队列积压情况,必要时降低日志处理并发。 4. 禁止直接 kill 生产进程,必须先确认进程归属和影响范围。 5. 操作完成后,需要在值班系统中登记变更时间和影响说明。

在实际项目中,这份文档可以替换为产品说明书、FAQ、内部制度、法律条款等任意知识源。

7.2 编写 RAG 核心代码

创建rag_demo.py

# rag_demo.py import os from typing import List from dotenv import load_dotenv from openai import OpenAI import chromadb from chromadb.utils import embedding_functions load_dotenv() # 使用 OpenAI 兼容协议访问模型服务 llm_client = OpenAI( api_key=os.getenv("OPENAI_API_KEY"), base_url=os.getenv("OPENAI_BASE_URL"), ) MODEL_NAME = os.getenv("LLM_MODEL", "your-model-name") def load_text(path: str) -> str: """读取文本文件""" with open(path, "r", encoding="utf-8") as f: return f.read() def split_text(text: str, chunk_size: int = 300, overlap: int = 50) -> List[str]: """ 简单的分块函数:按段落合并,超过 chunk_size 就切分。 生产环境建议使用语义切分或递归字符切分器。 """ paragraphs = [p.strip() for p in text.split("\n") if p.strip()] chunks = [] current = "" for para in paragraphs: if len(current) + len(para) > chunk_size and current: chunks.append(current) current = para else: current += para if current: chunks.append(current) return chunks def ingest(collection, docs_dir: str): """把目录下的所有 txt 文档写入向量库""" for file_name in os.listdir(docs_dir): if not file_name.endswith(".txt"): continue path = os.path.join(docs_dir, file_name) text = load_text(path) chunks = split_text(text) ids = [f"{file_name}-{i}" for i in range(len(chunks))] collection.add( documents=chunks, ids=ids, metadatas=[{"source": file_name} for _ in chunks], ) print(f"[ingest] {file_name}: {len(chunks)} chunks") def ask(collection, question: str, top_k: int = 3) -> str: """检索相关片段,构造 Prompt 并让大模型生成答案""" results = collection.query(query_texts=[question], n_results=top_k) contexts = results["documents"][0] # 把检索到的资料拼进 Prompt,并明确要求模型不要编造 context = "\n\n".join(contexts) prompt = f"""根据以下资料回答问题。 资料: {context} 问题:{question} 要求: 1. 如果资料中没有答案,直接说明“资料中未找到相关内容”,不要编造。 2. 回答时尽量引用资料中的信息,并说明来自哪个文件。 """ resp = llm_client.chat.completions.create( model=MODEL_NAME, messages=[{"role": "user", "content": prompt}], temperature=0.3, ) return resp.choices[0].message.content if __name__ == "__main__": # 初始化 Chroma 向量库 chroma_client = chromadb.PersistentClient(path="./chroma_data") embedding_func = embedding_functions.SentenceTransformerEmbeddingFunction( model_name="BAAI/bge-small-zh-v1.5" ) collection = chroma_client.get_or_create_collection( name="knowledge_base", embedding_function=embedding_func, metadata={"hnsw:space": "cosine"}, ) # 写入本地文档 ingest(collection, "./docs") # 交互式问答 while True: question = input("请输入问题(输入 exit 退出):").strip() if question.lower() == "exit": break if not question: continue answer = ask(collection, question) print("\n答案:") print(answer) print("-" * 40)

这里有几个关键点值得展开。

第一,split_text是 RAG 的起点。如果文档被切成整段整段的大块,检索时容易把无关内容一起带进来;如果切得太碎,又会丢失上下文。示例中的overlap参数,是为了让相邻片段之间有部分重叠,避免关键句落在切分边界上。

第二,collection.add会把文本、ID 和来源信息一起写入向量库。后续检索返回的results会包含文档片段,我们可以直接拼装成上下文。

第三,Prompt 中明确要求模型在资料不足时不要编造。这是缓解模型幻觉最基础、也最有效的一招。生产环境还可以进一步要求模型输出引用来源,甚至用 JSON 格式返回结构化结果。

7.3 运行与验证

依次执行下面的命令:

# 1. 安装依赖 pip install -r requirements.txt # 2. 准备目录和测试文档 mkdir -p docs # 把上面的文档内容保存为 docs/sample.txt # 3. 运行脚本 python rag_demo.py

首次运行SentenceTransformerEmbeddingFunction时需要下载中文嵌入模型,请保持网络连接可访问模型源,或者提前下载好模型并配置缓存目录。启动后,如果看到类似下面的输出,说明入库成功:

[ingest] sample.txt: 5 chunks 请输入问题(输入 exit 退出):

输入一个关于知识库内容的问题,例如:

生产进程 CPU 过高时,可以直接 kill 吗?

预期输出接近下面的内容(实际文本会因模型和 Prompt 不同而略有差异):

答案: 根据运维手册的信息,不能直接 kill 生产进程。应先通过进程列表确定占用最高的进程,确认进程归属和影响范围,必要时临时扩容或降低日志并发,操作后需要在值班系统登记变更说明。

判断运行成功的标准有三个:一是没有报错;二是问题能在本地知识库中找到相关片段;三是生成的回答内容符合知识库原文,没有明显编造。

如果回答不理想,优先检查检索结果是否相关,可以临时把检索到的片段打印出来,确认top_k是否太小、切块是否合理,然后再调整 Prompt 和模型温度参数。

8. 常见问题与排查思路

在跑 RAG 项目时,下面几个问题出现频率最高,这里整理成一张排查表,方便对照处理。

问题现象可能原因排查方式解决方案
运行时提示嵌入模型下载失败网络环境无法访问模型源,或模型缓存缺失检查报错信息中的 URL,确认下载失败位置提前下载模型并设置缓存目录,或更换可访问的模型

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询