← 全部极客知识库

大模型通识 / 大模型应用开发入门

15. 交给别人运行——配置、启动与部署边界

原文备份 · 第 17 / 19 篇 · 查看极客时间原知识库 ↗

本篇目录 · 9 节

来源:大模型应用开发入门

你已经能在自己的电脑上使用笔记助手:打开页面,生成复习卡,保存计划,退出再打开也能找回。现在把项目文件夹发给朋友,对方却问:“该运行哪个文件?为什么找不到Flask?这个config要不要覆盖?你的历史怎么也在里面?”

这些问题不需要更强的模型,需要把程序从“我知道怎么用”整理成“别人能按说明运行”。本篇交付一个独立的源码包、一套启动入口和一份可以直接放进项目的README。另一个人从新目录开始,不依赖你的虚拟环境、密钥和运行数据,也能完成一次离线演示。

同时,我们会划清一个边界:让朋友在自己的电脑上运行,和把你的服务公开到互联网,是两件不同的事。前者本篇会实际验证;后者需要理解新增的运行与权限责任,不能靠修改一个监听地址就宣布完成。

下载本篇代码 · 独立运行说明 · 上一篇:SQLite会话与计划

核实日期:2026年10月4日。代码沿用Python 3.11+、openai 3.24.0和Flask 3.1.3,实测Python 3.11.8。网页、数据库和模型调用主体保持第14篇行为,新增run_local.py与package_project.py。演示不读取真实API密钥、不调用付费API;安装依赖会连接软件包服务,与模型调用不同。

一、发出去之前,把文件分成三类

一个运行过的项目目录同时装着代码、环境和个人数据。压缩整个文件夹,往往把它们混在一起。先看每类文件的用途:

类别 本项目例子 如何交付
可复用源码与公开样例 Python文件、HTML模板、requirements.txt、config.example.json、两份教学笔记 放进源码包,供接收者重新运行
本机环境与个人配置 .venv、config.json 接收者重建环境,由模板生成自己的配置
已产生的工作数据 data、records、tool-records、plans等 本人单独备份,不作为通用源码发送

.venv中包含本机安装的解释器路径和依赖。它不是一份适合直接拷给另一台电脑的“软件绿色版”。Python官方建议在新位置重新创建虚拟环境,而不是搬运已有环境。Python venv文档

data/session.key也不该和公开代码一起发出。它虽然不是DeepSeek密钥,却负责签署浏览器会话身份。data还包含笔记全文快照、绝对路径、答案和计划。上篇讨论的备份,是为本人保留这些状态;本篇的源码交付,目的是让别人得到一个干净起点。

.gitignore仍有价值,但它只影响Git对文件的跟踪,不会阻止你用系统压缩工具把文件压进去。因此我们加一个明确的打包入口,不让它递归收集整个运行目录。

二、把“首次启动”变成一条清楚的路线

下载本篇ZIP,解压后进入lesson-15目录。不要覆盖第14篇已经运行过的目录。下面假定机器已经装有Python 3.11或以上版本;先运行python3 --version,Windows可运行py -3 --version确认。版本不符时先安装合适版本,不在系统Python里混装依赖。

macOS/Linux:

python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python -m pip check
.venv/bin/python run_local.py init
.venv/bin/python run_local.py check
.venv/bin/python run_local.py serve

Windows PowerShell:

py -3 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe -m pip check
.\.venv\Scripts\python.exe run_local.py init
.\.venv\Scripts\python.exe run_local.py check
.\.venv\Scripts\python.exe run_local.py serve

每一行成功后再继续。我们直接指定虚拟环境中的Python,所以不用先激活环境,也不用为了这份教程修改PowerShell脚本执行策略。python -m pip把安装动作绑定到你选中的解释器,减少“安装在一个Python里,运行时却用了另一个”的混乱。

这里有两种检查。pip check检查已安装软件包声明的依赖是否相容,正常可看到No broken requirements found.;它不检查笔记目录或项目配置。pip check文档

run_local.py check则检查本项目的启动条件。它会显示解释器、项目目录、网页数据目录、两个直接依赖的版本和非秘密配置。第一次正常运行时,应看到“数据库尚未创建;首次serve将初始化”,最后是:

本地启动检查通过;未读取API Key、未调用API、未测试端口或网络可达性。

再运行serve,终端应显示本机地址http://127.0.0.1:8765。打开页面,顶部仍是“离线演示 · 不请求模型”。从默认两份笔记生成卡片,填写一个复习日期、20分钟,预览并确认计划。预期结果与上篇相同:卡片为validated_needs_review,计划显示“计划已保存”。

在另一个终端、同一项目目录执行.venv/bin/python inspect_db.py,Windows用.\.venv\Scripts\python.exe inspect_db.py。全新目录只做一次流程,应有一个会话、一个操作和一个计划;刷新页面不增加操作数。至此,对方不需要API账户也可以验证应用安装和主要流程。

三、init、check、serve分别做什么

把几个命令合成一个入口,不是为了隐藏错误,而是让各阶段职责清楚。

init仅在缺少config.json时,从config.example.json创建它。如果文件已经存在,就提示保留,绝不覆盖。它不创建数据库、会话密钥或虚拟环境。你第二次执行init看到“保留已有config.json”,属于正常结果。

核心代码是独占创建:

    try:
        with target.open("xb") as f:
            f.write(content)
    except FileExistsError:
        print("保留已有config.json;请继续运行check。")
        return False

x表示文件存在就失败,而不是打开后清空。这个小选择可以避免一条初始化命令把读者刚调整过的配置抹掉。已有文件是否有效,由下一步check判断。

check检查当前解释器、两个直接依赖版本及导入、配置字段、可选笔记、数据位置的写权限,以及已有数据库和会话密钥的基本状态。为了验证写权限,它会创建并清理一个临时目录;不会创建新数据库或重写已有数据库。已有数据库却缺少session.key时,它会要求检查备份,避免启动过程中生成新密钥导致旧会话失效。

它不是无所不能的“健康认证”。它不会联网试密钥,不检查账户余额,不确认模型名在服务端可用,不逐份解析笔记内容,也不预占端口。笔记长度和检索规则仍在预览时检查;端口是否可绑定由真正启动时决定。

serve先运行同一检查,通过后用当前Python解释器启动已有web_app.py。因此虚拟环境不会在中途被换掉。默认启动离线模式;只有显式加入--live,才进入终端隐藏输入Key的流程。原有web_app.py仍可直接使用,但交付给初学者时推荐这个带前置检查的入口。

再次打开项目时,不需要重建环境或重新安装,只执行:

.venv/bin/python run_local.py serve

Windows仍替换成对应解释器路径。停止服务用原终端的Ctrl+C;终端结束、电脑休眠或关机后,服务不会继续可靠运行。本课没有后台守护、自动重启和开机启动。

四、配置放在哪里,哪些东西不要放进去

模板只有三个字段:

{
  "model": "deepseek-flash",
  "max_tokens": 1024,
  "timeout_seconds": 60
}

模型名必须是非空字符串;输出预算限制为1—4096,超时为1—120,二者必须是整数。这里的范围是本课程为了控制实验规模设定的限制,不是DeepSeek服务的完整上限。

配置按照脚本所在目录定位,不按终端恰好在哪个目录决定。因此从其他目录运行脚本,仍会使用它旁边的config.json和data。检查命令把实际路径打印出来,帮助你发现是否启动了旧副本。

本项目没有自动读取.env,也没有把环境变量作为隐藏的配置覆盖层。更不接受在config.json里追加api_key。把Key写进一个程序根本不读取的位置,既不能修好认证问题,又增加误分享的可能性。

本课继续使用官方https://api.deepseek.com地址和deepseek-flash模型标识;本日官方入门文档仍列出这个地址与名称。DeepSeek官方接入说明

如果你决定进行可能计费的真实验证,先停止离线服务,再运行:

.venv/bin/python run_local.py serve --live

Windows运行.\.venv\Scripts\python.exe run_local.py serve --live。Key由本人在终端输入,页面不接收Key,重启后需要重新输入。预览仍不请求模型;点击真实生成时,选中的笔记片段和问题会发送到API。关闭思考、非流式JSON、单次尝试等规则沿用前篇。

默认示例能启动,只证明本地依赖和演示路径可用。真实Key是否有效、网络是否可达、账户能否支付以及模型输出是否合格,需要另行验证,不能从离线成功推出来。

五、固定版本,为什么还不能说“任何机器上完全一样”

requirements.txt把直接使用的SDK和Flask固定到本篇测试过的版本,启动检查也会拒绝不同版本。这是为了让跟课过程可复现,不表示其他版本必定不能运行;自行升级后需要重新验证,不能只改检查提示就宣布兼容。

这两个库还依赖其他包。当前文件没有逐个固定全部间接依赖,也没有提供包文件哈希,因此它不是一份完整锁文件。在不同安装时间、Python版本和操作系统上,间接依赖或可用二进制包仍可能变化。更严格的重复安装可进一步固定全部依赖、核对哈希或准备适合目标平台的安装包,但也要承担更新维护工作。pip重复安装说明

本篇采取适合入门的做法:固定关键版本,使用隔离环境,用pip check与应用检查发现问题,再从全新目录验证真实启动流程。不要把自己电脑上混用多个项目的环境直接pip freeze成清单发给别人,那会把与本项目无关的依赖一并带进去。

当你需要升级,先复制一份干净源码、重建环境验证,再决定迁移原数据。第14篇数据库有版本号,本篇没有改变结构;但这不意味着未来任意版本代码都能打开同一份库。

六、生成一份不含个人历史的源码包

在当前项目目录运行:

.venv/bin/python package_project.py --output ../notes-assistant-source.zip

Windows PowerShell:

.\.venv\Scripts\python.exe package_project.py --output ..\notes-assistant-source.zip

命令会把源码ZIP写到项目的上一级目录。输出父目录必须已存在;如果目标ZIP已经存在,程序拒绝覆盖,你可以改成notes-assistant-source-v2.zip等新名字。

正常结果是“已生成37文件源码包”。打开ZIP查看,应有顶层目录notes-assistant,下面是代码、README、模板、固定依赖和教学样例。它不应包含data、config.json、.venv、.env、请求日志,也不包含你另外放进sample-notes的私人笔记。

打包器使用代码中的FILES白名单。只有列出的相对路径才会被读取;缺少必要文件、路径中有符号链接时会停止。两份教学笔记还会核对原始哈希,若你已经把rag.md改成自己的内容,也会拒绝打包。此时应另取干净的教学副本,不要为了通过检查覆盖自己已经写好的笔记。

这个机制有明确范围:如果你把秘密手写进清单内的Python源码或README,白名单不会识别它。打包前仍需审阅自己修改过的文件。反过来,如果你新增了一个必要Python模块,打包器也不会自动认识它;需要审阅后补进FILES,再做解压验证。

源码包也不是数据备份。自己的历史、会话密钥和计划仍在原data中,按照上篇停服备份整目录。不要因为生成了源码ZIP,就删除原项目。

七、用“接收者的方式”再运行一次

不要在仍有旧配置、旧数据库和旧环境的目录里证明包能用。真正的检查应从源码包解压后的目录开始:

  1. 停止原服务,保留原文件。
  2. 把刚生成的ZIP解压到另一个位置,例如一个新的测试文件夹。
  3. 进入其中的notes-assistant目录,按第二节重建.venv、安装依赖、执行init与check。
  4. 启动离线网页,首页应没有原来的历史,也不应要求输入Key。
  5. 用默认样例生成卡片、确认一份计划,运行inspect_db.py独立核对,再停服重启检查恢复。

新副本有自己的数据库和会话签名密钥。浏览器访问新副本时可能获得新的会话Cookie;不要同时运行新旧两份,再指望切换端口能隔离Cookie。验证旧数据是否还在,应回到对应目录用只读检查核对,而不是仅凭浏览器首页判断。

这次练习的价值是找出“只在我电脑上成立”的假设:代码是否依赖旧绝对路径,是否漏打包模板,是否误用全局安装,是否把个人配置当成必需文件。直到新副本从零完成这条链路,再把源码包交给学习伙伴。他是否进行真实API验证,由他自行决定,使用他自己的账户。

八、共享源码和公开服务,差在哪里

共享源码时,每个人运行自己的进程,使用自己的资料和Key。公开服务时,是你的后端长期接受别人的请求;模型费用、数据访问、故障恢复都汇聚到同一个服务上。浏览器中的一个按钮,可能开始消耗你的API额度。

本篇的serve仍调用Flask开发服务器。它适合本地开发教学;即使只有本人长期使用,正式部署也应改用合适的WSGI服务器或托管平台。Flask官方明确区分了开发运行与生产部署,生产环境不等同于“用户很多”。Flask部署文档

WSGI服务器负责长期接收HTTP请求并把它们交给Python应用;它不会自动补出登录、用户配额或业务授权。公开服务至少会改变以下几组设计:

当前教学版 对外服务需要解决的问题
只监听127.0.0.1,本机HTTP 服务入口、HTTPS、可信代理与Cookie配置
随机浏览器会话,无登录找回 可验证用户身份、退出与失效、记录和文件访问权限
所有人可选同一资料目录 用户资料分区、上传限制、授权后读取
单进程,前台运行,Key终端输入 进程管理、密钥注入、更新与异常恢复
本地SQLite和操作文件 持久化磁盘、备份恢复、写入并发与容量管理
单次请求有限制 用户配额、请求速率、总费用控制与可观察的失败记录

这不是让个人项目一开始就搭建复杂基础设施。它是在告诉你,哪一类变化会让现有假设失效。例如,部署平台重新创建实例时若没有持久化磁盘,SQLite文件可能丢失;启多个服务进程时,任务状态和写入竞争需要重新验证;日志若收集完整请求,笔记内容也会进入日志系统。

因此本篇不提供一条“把地址改成0.0.0.0即可上线”的命令,也没有替你购买服务器或公开端口。你已经得到可以交给别人本地学习的包;如果下一步确实需要共同使用一个在线服务,应按具体使用者、资料与费用范围设计那套部署。

九、别人报告“打不开”,先问清失败在哪一层

现象 下一步
找不到Python或版本过低 确认安装与版本,先让版本命令成功
No module named flask/openai 对照check显示的解释器,用同一个Python安装requirements
pip下载失败 检查软件包网络和安装错误;不是DeepSeek密钥的问题
init说已有配置 配置被保留了,接着check;不要默认删掉重建
check报字段或范围错误 对照三字段模板,数值不要写成字符串或布尔值
check通过但网页没起来 查看启动终端;可能端口被占用,用serve --port 8766换空闲端口
页面404、历史不见了 对照项目路径、data路径、Cookie与会话密钥;只读检查数据库
检查提示已有库缺密钥 保留文件,找对应备份;不要用新密钥冒充会话恢复
第一次调用才报认证、额度或网络错误 本地检查没验证远端,按第8篇分类处理,不自动无限重试
打包拒绝修改后的样例 用干净教学副本,保留自己的笔记,不绕过内容边界

失败时保留终端中有用的错误类型和步骤。给别人反馈问题前,去掉Key、笔记全文和个人路径等不必要内容。只说“模型不行”会把安装、应用和模型三种不同问题混在一起。

本篇完成112项离线回归,覆盖前篇97项行为及15项启动/打包边界;并用全新虚拟环境安装依赖、从导出的源码包重新运行。网页业务流程未改,离线验证不代表API可用或Windows实机通过。

最后做一个判断练习:把.venv一并打包是不是最省心?通常不是,应在接收者电脑重建。check通过是否意味着Key余额充足?不是,它没有连接模型。新源码包没有旧计划是不是数据丢失?不是,这正是干净交付的预期,旧数据应保留在原目录和备份中。

下一篇将用一组可重复的验收场景检查整个助手,再讨论把它迁移为自己的项目时,应该先改需求、资料、工具还是模型接口。