AI 应用工程师实战:拆解一个知识库助手

发布时间:2026/10/10 2:52:28
AI 应用工程师实战:拆解一个知识库助手
假设你要给一家公司做内部问答助手。员工输入“请假找谁审批”助手从制度文档中找到相关条款给出回答并附上出处。这个需求看起来像聊天框加一个模型接口。真正动手时问题会接连出现新版制度如何替换旧版财务文档能不能被普通员工检索到回答引用了文档为什么内容仍然可能是错的接口超时用户看到什么本系列以这个假设项目为主线逐步做出一个可以检查、评估和部署的知识库助手。第一课先拆清信息流再用一个不联网的 Python 程序观察问题和资料究竟怎样被放到一起。今天不需要购买额度也不会得到真实的模型回答。1. “AI 应用工程师”在这个项目里负责什么这里用“AI 应用工程师”指把模型能力接入实际软件的人不把它当作一个职责已经统一的招聘标准。你需要把用户需求转成输入、数据流程、模型调用和可验证的输出还要处理失败、权限和成本。知识库助手中几类工作有不同的验收方式工作需要回答的问题可以检查的结果定义需求回答哪些问题什么情况应该拒答有范围、有预期答案的样例集整理数据哪份制度有效谁能访问片段带来源、版本和访问规则接入模型请求怎样发送失败怎样返回能记录状态、耗时与用量的调用做应用用户怎样提问、查看出处、继续追问能完成任务的前后端流程做评估检索错了还是回答编了能定位问题的测试与日志你可以从现成模型和托管服务开始不必先训练模型。但使用现成模型并没有替应用处理文档权限、会话状态或质量验收。是否需要微调是后续根据任务和评测结果做的选择。2. 先分清两条流程准备数据与回答问题图 1拟实现的概念架构非已部署系统。灰色连线表示索引供在线检索使用本课只演示人工选取资料后的上下文组装。数据准备流程在文档新增或更新时发生。先解析文本再切分为可处理的片段保留标题、来源、版本和访问权限然后建立检索索引。片段怎样切、用关键词还是向量检索取决于资料与问题的特点。在线回答流程在用户提问时发生。后端验证身份按访问规则选择可用资料检索相关片段再把问题、片段和回答要求一起交给模型。最后将回答和对应来源返回给用户。这两条流程可以独立调试。文档没有解析出来就先查数据准备候选片段里没有答案就先查检索片段已经包含答案回答却增加了不存在的条件再检查生成与校验。直接换模型未必解决前两类问题。在这个设计里API Key 保存在后端。用户登录应用的权限与应用调用模型的密钥是两件事前者决定用户能看什么后者用于访问模型服务。把密钥放进网页代码会让访问网页的人有机会取得它。3. RAG 增加了什么又没有保证什么RAG 是 Retrieval-Augmented Generation通常译为检索增强生成。它把检索到的外部资料用于生成过程。Lewis 等人的原始论文讨论了结合参数记忆与非参数记忆的模型其中非参数记忆使用可检索的文档索引。[1]本系列做的是应用层的检索与生成流程不复现论文中的训练方案。对这个项目来说可以先理解为先找资料再把相关资料作为上下文交给模型回答。拿“请假找谁审批”来说假设资料里只有“请假申请由直属主管审批”。回答“直属主管”并引用该片段符合这条资料回答“直属主管审批后还需 HR 复核”就多出了一项资料没有提供的要求。即使后一个回答也附了正确的来源编号它仍然没有忠实表达原文。因此“有引用”只是提供了核查入口不能单独证明答案正确。系统还要面对其他限制检索可能漏掉关键条款旧版和新版资料可能冲突权限过滤可能配置错误模型可能把文档里的指令当作应执行的要求。降低这些风险需要版本管理、访问控制、输入隔离和持续评测不能只在提示词里写一句“禁止编造”。资料少、问题简单时先人工选择或直接提供少量资料也可以帮助验证需求。不是所有项目一开始都需要向量数据库。是否引入自动检索应看数据规模、更新方式、相关性和可接受的延迟而不是看技术栈是否足够长。4. 本课实验看清一次上下文组装准备 Python 3.10 或以上版本本例仅使用标准库没有第三方依赖。将下面完整代码保存为context_preview.py。两条制度是教学用的虚构资料不对应任何真实公司。importargparseimportjson DOCUMENTS{leave-01:【虚构制度】员工请假须在系统提交申请由直属主管审批。,expense-01:【虚构制度】差旅报销须附发票并在行程结束后提交报销单。,}defbuild_preview(question,source_ids):questionquestion.strip()ifnotquestion:raiseValueError(问题不能为空)ifnotsource_ids:raiseValueError(至少人工选择一份资料)unknownsorted(set(source_ids)-DOCUMENTS.keys())ifunknown:raiseValueError(未知资料编号, .join(unknown))selectedlist(dict.fromkeys(source_ids))context\n.join(f[{key}]{DOCUMENTS[key]}forkeyinselected)return{instruction:仅根据资料回答并引用编号资料不足时说明缺少依据。,question:question,context:context,source_ids:selected,}defmain():parserargparse.ArgumentParser(description离线查看问题与人工选择的资料)parser.add_argument(question)parser.add_argument(--source,actionappend,requiredTrue)argsparser.parse_args()try:previewbuild_preview(args.question,args.source)exceptValueErrorasexc:parser.error(str(exc))print(json.dumps(preview,ensure_asciiFalse,indent2))if__name____main__:main()在脚本所在目录运行。如果你的 Python 命令是python3替换命令中的python即可。python context_preview.py请假找谁审批--sourceleave-01你会得到下面的 JSON。这是本地构造的上下文预览字段由本例自行定义不是可直接发送给任意模型服务的请求格式也不是模型输出。{instruction:仅根据资料回答并引用编号资料不足时说明缺少依据。,question:请假找谁审批,context:[leave-01] 【虚构制度】员工请假须在系统提交申请由直属主管审批。,source_ids:[leave-01]}观察四个字段question是要解决的问题context是提供的依据instruction是回答要求source_ids保留了追溯入口。ensure_asciiFalse让 JSON 中的中文直接显示indent2用于缩进它们改变显示方式不改变资料内容。[2]这里的--source由你手动指定。程序没有理解问题、计算向量或执行检索它也没有联网、调用模型或校验回答。这个边界很重要否则一个上下文拼接脚本容易被误叫成“完整 RAG”。做三个小改动检查信息流第一把--source leave-01改为--source expense-01。你仍能得到合法 JSON但资料已经无法回答请假问题。这说明预览 JSON 能构造成功与资料选对了是两个独立的检查点。第二改问“请假超过三天需要什么手续”仍只选leave-01。资料没有时长规则。在后续加入模型后这应该成为一个“资料不足”的测试样例而不是期待它补出看似合理的制度。本课程序只展示输入不会自动判断问题是否可回答。第三同时传入两份资料。下面是 Bash/zsh 的多行写法在 PowerShell 中把命令写成一行即可python context_preview.py请假找谁审批\--sourceleave-01--sourceexpense-01问题没有变化上下文却加入了无关的报销内容。后续接入模型时这会增加输入长度具体 Token 数和费用取决于模型及服务计费方式。检索阶段应尽量选择足以回答问题的相关资料而不是默认把全部文档放进去。如果没有运行成功先查这里现象本例中优先检查什么找不到context_preview.py是否位于脚本所在目录或是否使用了正确的脚本路径提示必须提供--source命令是否包含资料编号提示未知资料编号编号是否为leave-01或expense-01拼写是否一致提示问题不能为空是否传入了空字符串或只有空格的问题本例不需要密钥。如果看见 401、429 或网络超时检查是否运行了其他联网程序。本文示例命令已在 Python 3.14.5 环境运行这里的制度内容与结果都不构成真实业务评测。5. 后面的课按什么顺序学图 2课程的项目增量规划不是固定工期也不要求一次学完所有框架。阶段做出的东西进入下一阶段前的验收看清信息流本课的离线预览能区分问题、资料、指令与来源接通模型命令行对话能处理认证、超时、错误并记录服务返回的用量做成应用后端与聊天网页密钥留在后端流式输出和会话保存可检查加入检索带来源的知识库回答能观察检索片段验证版本与权限过滤完善评估和部署测试集与可访问服务对未知问题、失败请求和费用有处理记录评估从第一课就开始先记录问题、预期依据和资料不足的情况后续再增加检索、生成与性能测试。图中的最后阶段是完善评估和部署不是到那时才第一次检查效果。对这个项目我建议先用 Python 和 HTTP 请求建立最小链路再按需要引入后端框架、数据库和检索工具。每增加一个组件都说清它解决什么问题以及如何验收。框架可以减少重复开发。学习初期更值得先确认自己能辨认它接收的输入、产生的输出和失败的位置这样换工具时已有的测试仍然有用。6. 第一次动手做到什么就够了完成本课后你应该能运行脚本并解释为什么选错资料仍能生成 JSON为什么引用编号不等于正确答案以及自动检索应该插在哪一步。接着写下三类测试问题资料明确能回答的、资料没有依据的、与资料无关的。每类先准备一个问题并标出预期依据或拒答理由。这份小测试集会跟着项目往后走比先安装一串框架更容易暴露问题。下一课把本地预览改成真实模型调用讲清 API Key、Base URL 和模型名称再处理第一次请求的结果与错误。接口接入示例可使用由我运营的星桥也可以按其他服务的文档配置。本课没有调用任何服务学习路线不依赖某个中转站。参考资料Patrick Lewis 等Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks。本文引用摘要对参数记忆、非参数记忆和检索索引的说明未复现其训练或实验。Python 官方文档json — JSON encoder and decoder。用于核对本例的 JSON 输出参数。