
手头有一份上百页的技术文档要整理成结构化摘要还有一堆业务日志需要跨文件找线索我在本地把这套流程全部跑通了。核心思路很直接用 Ollama 把开源大模型装到自己机器上再通过一个内部代号叫 openclaw 的调度管道把长文档切块、检索、重新组装最终实现了看似“无限 tokens”的长文本处理能力——说“看似”是因为单次输入窗口永远是有限的但通过分段缓存和检索拼接整个系统能吞下任意长度的内容。这篇文章就把从安装到跑通的全过程拆开讲适合那些不想把所有数据交给云端、又希望低成本处理超长文本的开发者参考。1. 为什么我最终把长文本任务压回了本地云端之外的真实考量1.1 我反复纠结的三件事在动手之前我其实纠结了蛮久。市面上按 token 计费的云端接口很方便把 PDF 一塞几千行代码就能拿到摘要但有三件事始终绕不过去。第一是成本体感。短文档还好一旦碰到几十万字的长文本每次请求都在烧钱。测试阶段你可能反复修改策略、调 prompt一次全量重跑就是一笔不小的开销。我做过一个粗糙对比同样是处理 50 万字符的文档集走云端接口跑五轮调试花费已经够我买一块不错的二手显卡了。本地部署是一次性投入后面不管怎么折腾都是电费而已。第二是数据边界。有些文档虽然不算什么国家级机密但客户或同事并不希望它出现在第三方服务器上。哪怕云端厂商承诺“数据不出租户”一旦进入线上服务你的内容就脱离了可控范围。对很多团队来说这一条直接劝退。第三是调试自由。云端接口最大的问题是你只能黑盒调用上下文被截断了系统提示被忽略了某个参数为什么没生效你只能靠猜。而本地模型你能看到完整日志随时改采样参数甚至能自己改 prompt 模板、控制检索逻辑。这种掌控感对做技术方案的人来说太重要了。所以结论很明确核心诉求是“在可控环境下长期、反复地处理长文本”而不是“快速跑一次演示”。前者天然适合本地部署。1.2 一张表看清本地部署的边界当然本地部署不是银弹。我把云端和本地的差异整理成一张表方便你判断自己适不适合走这条路对比维度云端按量计费本地 Ollama 部署初始成本低按调用付费中高需准备内存/显卡长文本反复调试成本累加明显边际成本趋近于零数据私密性受服务商约束数据完全留在本机模型可替换性取决于平台任意切换开源模型上下文策略自由度受限可自定义分段、检索、压缩逻辑部署与维护零维护需要自己管环境、管理端口和进程响应速度受网络影响受本机硬件约束看完你应该能理解本地部署省的不是“一次处理”的钱而是“反复折腾”的钱。我最后选择本地是因为我要在不计次数的前提下不断调整长文本处理策略本地模式下我的试错成本几乎为零。如果你的场景是偶尔跑一次、文档量小云端的便利性仍然有优势。2. 环境初始化Ollama 的安装与模型落盘我踩过的三个细节2.1 安装与启动Ollama 的安装本身很简单官网给了一条命令支持 Windows、macOS 和主流 Linux 发行版。我是在一台 Linux 服务器上操作的安装命令大概是这样的curl -fsSL https://ollama.com/install.sh | sh装完后先确认服务状态ollama list ollama serveollama serve会启动一个本地 HTTP 服务默认监听 11434 端口。这一步常被忽略——很多人装完直接ollama run发现能用就以为服务已经常驻了其实ollama run会自动拉起一个临时服务。如果你后面要写代码调用 API务必确保 serve 进程一直在跑。我在真实部署中更推荐把 Ollama 注册成系统服务让它开机自启。Linux 下安装脚本通常已经自动配置好了 systemd 服务你可以用systemctl status ollama检查。没有 systemd 的发行版就老老实实写个守护进程否则一旦服务器重启你的调用链会从第一环开始崩。2.2 模型拉取与量化位宽的真实取舍接下来是拉模型。我选的是一款 7B 档位的开源中文对话模型量化版本用的是 Q4_K_M。为什么选这个组合而不是无脑上最大模型这里有一个非常实际的平衡问题。先说量化。模型权重的精度越低占用的内存越少但推理质量会有轻微损失。Q8 精度损失几乎可忽略但体积大Q4 速度更快、更省内存长文本场景下质量下降通常也能接受。我用 Q4_K_M是因为它在大幅降低内存压力的同时对中文理解能力的削弱在长文本摘要这个任务上几乎看不出来。而 7B 这个档位是我反复测试后的结论它是“普通家用机器能跑流畅”和“输出质量可用”之间的甜点区。你要是有一张 24G 显存的显卡直接上 13B 甚至 30B 档位会更舒服如果像我一样只有 16G 内存加一块普通显卡7B 量化版是目前最稳的选择。拉取模型用ollama pull 模型名:7b-q4_K_M注意模型名和量化标签写错是很常见的报错来源一定先ollama list看看实际拉下来的名字。2.3 常见安装失败的排查安装和启动这一关我遇到三个值得记录的问题。第一个是端口被占用。11434 端口被其他服务占着ollama serve会直接起不来。排查方式很简单netstat -tlnp | grep 11434有结果就换端口或用OLLAMA_HOST0.0.0.0:11435 ollama serve指定新端口。不过后续所有 API 调用地址都要跟着变建议还是直接清理占用进程。第二个是模型加载速度异常慢。第一次ollama run时模型文件要落盘和解压等几分钟很正常但如果每次都等几十秒多半是磁盘 IO 太慢或者模型放在机械硬盘上了。让 Ollama 把模型目录放到 SSD或者用OLLAMA_MODELS环境变量指定路径能明显改善。第三个是显存不够导致自动退出。小显存机器跑大模型进程起来后立刻被系统杀掉的情况很常见。解决办法有两个方向换更小的量化版模型或者让模型部分跑在 CPU 上。Ollama 默认会利用所有可用显存显存不足时自动退让到 CPU但这个退让过程偶尔会引发响应速度骤降。我的习惯是先用ollama run快速测一下确认能稳定对话再进入下一环节。3. 把上下文“撑大”而不是硬塞本地无限 tokens 的工程方案3.1 先破除“无限”的误解“真无限 tokens”这个说法必须先把预期拉回到现实没有任何现役模型能在一次前向推断里输入数学意义上的无限长度。你看到的各种“无限上下文”产品本质上都是工程方案——把一次塞不下的内容拆开按需取用让模型始终只在“当前工作集”内做推理而这个工作集之外的内容通过缓存和检索延续记忆。我用了一个生活类比来理解这事你不会把整本百科全书一次性摊开在桌面上读而是先看目录找到相关章节把对应几页抽出来细读。“无限 tokens”就是“书架无限大”而不是“桌面无限大”。本地部署在这方面有一个天然优势一切都可以自定义。膨胀的检索索引、分段策略、缓存目录全都在你机器上你完全清楚每一条数据去了哪里。云端方案虽然也能做类似的事但高度封装的接口往往让你无法精细控制分段粒度。3.2 分段、检索、组装一条可落地的长文本管道我的具体做法是搭了一条三段式管道内部代号叫 openclaw 的雏形就是从这里开始的。第一段是切分。把长文档按固定字符数切成块块之间保留少量重叠。切分时有两个关键参数块大小和重叠大小。块太大单次送入模型还是容易爆窗口块太小语义被切碎检索效果差。我实测下来中文文档按 800 到 1200 字切分比较稳重叠 100 到 200 字能让跨块被切断的句子有足够上下文兜底。第二段是检索。为每一块生成向量表示用户提问时把问题向量化计算相似度取出最相关的几个块。这一步不需要特别复杂的系统Ollama 本身就支持向量嵌入模型我直接用它生成了每块的向量存在一个本地文件里。没有用重型向量数据库因为单机处理几十 MB 的文档文件级别的扫描完全够用。第三段是组装。把检索出来的前几块按原始顺序拼接连同用户问题一起交给生成模型让它输出最终答案。这样单次推理的输入长度被严格控制在模型上下文窗口范围内但数据集的整体规模已经完全不设限了。3.3 参数实测记录与调整下面是我在真实测试里记录的一组参数你可以直接抄作业参数我的设置备注块大小1000 字符中文场景稳定块重叠150 字符避免断句丢语义单次参考块数3 到 5 块超出后答案开始发散生成最大 tokens2048摘要任务够用温度0.3事实类任务偏低上下文窗口8192覆盖检索块问题历史我测试了一个接近 2000 页的文档集按照上述配置总处理时长主要花在切分和生成上检索部分因为向量文件不大基本是毫秒级。输出质量最明显的提升来自温度调低——从默认的 0.7 调到 0.3 之后编造内容的比例肉眼可见地下降。这里还要提醒一个容易翻车的地方上下文窗口不是设得越大越好。窗口越大推理占用的内存越多速度越慢响应时间可能成倍上涨。本地部署的优势是你可以随时改但不要把钱和算力花在永远用不到的巨大窗口上。合理的做法是让窗口略大于“检索块拼起来的总长度”留出余量给问题和输出即可。4. 跑通内部代号 openclaw本地模型接入业务调用的完整链路4.1 openclaw 是什么先解释一下openclaw 并不是一个现成的开源项目而是我给整套本地任务调度管道起的内部代号。它做的事情是把 Ollama 模型从“命令行玩具”变成“可被业务逻辑调用的服务”——接收外部请求自动完成检索、组装、调用模型、返回结果的全过程。你可以把它理解成一个轻量的中间层名字不重要重要的是它解决了“命令行聊天和业务系统之间那条鸿沟”。单纯用ollama run在终端里聊天当然也能验证模型能力但真实价值在于程序化调用写一个 Python 脚本读入文档构建索引接收用户问题返回答案。openclaw 就是这层胶水。4.2 调用本地的正确姿势Ollama 本身就提供 OpenAI 兼容的 HTTP API地址是http://localhost:11434/v1/chat/completions这意味着你不需要额外引入复杂的 SDK直接用标准的 HTTP 请求就能接入。我写了一个最小可用版调用脚本结构如下import requests def chat_with_local(prompt, historyNone): messages history or [] messages.append({role: user, content: prompt}) resp requests.post( http://localhost:11434/v1/chat/completions, json{ model: 本地模型名:7b-q4_K_M, messages: messages, temperature: 0.3, max_tokens: 2048, }, timeout120, ) resp.raise_for_status() data resp.json() return data[choices][0][message][content]把检索模块和生成模块接起来之后openclaw 的完整流程就变成了接收问题向量化问题在本地索引里检索最高相关的若干文本块拼接文本块与对话历史把组装好的消息发送给 Ollama拿到结果后返回给调用方。整个链路里Ollama 只是其中一环真正体现工程价值的是步骤 2 到 4 的组装策略。这套设计让我后续替换模型时不需要改动任何业务代码只是换一个model字段而已。4.3 测试、报错与收尾心得跑通之后我做了三轮测试。第一轮是单文档摘要用的是一份约 30 万字符的行业报告第二轮是跨文档问答把五份相关文档混在一起提问第三轮是多轮对话让模型在连续对话中保持对前面内容的记忆。三轮跑下来整体效果符合预期但也有几个问题必须记下来。第一个问题是超时。默认不设置 timeout 时长文档生成超过一两分钟HTTP 客户端可能先崩溃。我的解决方式是把timeout明确设置为 120 秒并在业务侧做好异步化处理。这算是我最想让你避开的坑——本地模型速度远没有云端那么快超时设置不合理的调度层会在长文本任务上频繁失败。第二个问题是内存交换。当多个请求同时进来显存和内存压力会叠加。我在实际测试中并发 3 个请求时机器开始出现明显卡顿进程一度被系统 OOM killer 杀掉。解决方向有两个加内存或限制并发。我最后选择了限制并发在 openclaw 里加了一个简单的队列保证同一时刻只有一个生成任务在跑。效果立竿见影响应时间和成功率都稳住了。第三个问题是长期运行的稳定性。服务跑了两天后我发现 Ollama 进程的显存占用有上涨趋势。后来定位到是多次推理后上下文保留导致缓存膨胀。我的处理策略是周期性重启模型实例同时把无关的会话历史及时清掉。在长期服务的场景下这几乎是必做的一步。最后分享一条经验先小规模验证整个链路再上真实数据。我最初直接用 2000 页文档集测试结果切分代码里一个小 bug 导致有几万块文本被重复生成向量磁盘直接吃满。换成小规模验证后五分钟就能跑完一轮测试bug 定位速度快得多。这个习惯让我后面节省了大量时间。本地部署这件事最迷人的地方是它把模糊的“人工智能能力”变成了可测量、可调整、可掌控的工程问题。只要你想清楚自己的数据处理边界再耐心调一遍参数这套方案完全可以在你自己的机器上稳定复刻。