news 2026/10/14 11:53:16

局域网自建AI Agent平台:Docker部署本地大模型与编排服务实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
局域网自建AI Agent平台:Docker部署本地大模型与编排服务实战

1. 为什么要在局域网里自建 AI Agent 平台

1.1 从"调用云端 API"到"把模型搬进机房"的转变

过去一年,我身边不少做企业内部工具的朋友都经历了同一个心路历程:一开始图省事,直接调用公有云的大模型接口,写几行代码就能跑通对话。但真到了要落地到业务场景里,问题就一个接一个冒出来——数据不能出内网、调用量一大成本失控、网络抖动导致响应超时、敏感业务日志不敢往外部传。尤其是做制造业、医疗信息化、金融后台这类对数据边界极其敏感的行业,把原始业务数据送到公网模型上,本身就是一道过不去的坎。

于是"局域网自建 AI Agent 平台"这个需求就变得非常实在。所谓 AI Agent,不是简单的聊天机器人,而是能调用工具、读写本地文件、查询内部数据库、按流程执行多步任务的智能体。它需要一个能稳定运行模型推理服务、能挂载工具链、能管理会话与记忆的运行时环境。而 Docker 恰好是承载这套运行时最省心的方式——镜像一次构建,到处运行,依赖全打包,环境不污染宿主机。

这篇内容要聊的,就是怎么用 Docker 把一套本地大模型推理服务加上 Agent 编排层,部署到一台普通的局域网服务器上,让内网里的同事通过浏览器或内网 API 就能用上自己的 AI Agent。整套方案不依赖任何外部网络,模型权重、对话记录、工具调用全部留在你自己的机器里。

1.2 这套方案适合谁,能解决什么问题

先说清楚适用人群。如果你是完全没碰过 Linux 和命令行的纯小白,这篇会让你有点吃力,但跟着步骤走也能跑起来;如果你是有一定运维或后端基础的开发者,那基本可以当作一份可复现的部署手册来用。典型的使用场景包括:

  • 团队内部想有一个统一的 AI 助手入口,但不想每个人都去申请外部账号;
  • 需要让模型读取内网文档、知识库,做私有化的问答;
  • 想研究 Agent 的工具调用机制,需要一个可以随便折腾、不怕搞坏线上环境的沙箱;
  • 预算有限,只有一台带独立显卡或者内存够大的普通服务器。

它解决的核心问题就三个字:可控性。模型在哪跑、数据存哪、谁能访问、调用多少次,全部由你自己说了算。下面我会从整体架构讲到具体落地,把每一步的取舍逻辑都摊开说。

2. 整体架构设计与方案选型思路

2.1 三层结构:推理层、编排层、接入层

一套完整的局域网 AI Agent 平台,我习惯把它拆成三层来看,这样排查问题和做扩展的时候思路会清晰很多。

推理层负责真正跑大模型,对外暴露一个兼容 OpenAI 格式的 HTTP 接口。这一层的关键是选一个推理引擎,把模型权重加载进显存或内存,然后高效地处理并发请求。常见的选择有基于 llama.cpp 的轻量方案、vLLM 这类高吞吐方案,以及 Ollama 这种开箱即用的封装。局域网自建场景下,我一般推荐 Ollama 或者 vLLM,前者胜在简单,后者胜在并发性能。

编排层是 Agent 的大脑,负责接收用户输入、决定要不要调用工具、维护多轮对话的上下文、把工具执行结果再喂回模型。这一层通常是一个 Python 服务,用 FastAPI 之类的框架写,内部对接推理层的接口。它还要管理"记忆"——短期的是当前会话的上下文窗口,长期的可能落到向量数据库里做检索增强。

接入层就是用户看到的东西,可以是一个网页聊天界面,也可以是内网其他系统调用的 REST 接口。这一层要做的是鉴权、限流、会话隔离,保证不同用户的对话不会串。

三层之间通过 Docker 网络互联,各自是独立的容器。这样做的好处是任何一层要升级或替换,都不会牵动其他两层。比如你哪天想把推理引擎从 Ollama 换成 vLLM,只要接口格式保持一致,编排层几乎不用改。

2.2 为什么用 Docker 而不是直接装宿主机

有人会问,就一台服务器,直接 pip install 装上去不就行了,何必套一层 Docker?我踩过的坑告诉我,Docker 在这里的价值远超"多一层封装"的成本。

第一是依赖隔离。推理引擎对 CUDA 版本、Python 版本、系统库版本极其挑剔,而 Agent 编排层可能又依赖另一套 Python 包。直接装在宿主机上,两边的依赖很容易打架,升级一个搞崩另一个。容器化之后各管各的,互不干扰。

第二是可复现。你今天在这台机器上跑通了,明天换一台配置类似的机器,只要 Docker 和驱动装好,docker compose up一敲就起来了,不用重新回忆当初装了哪些包、改了哪些配置。

第三是资源可控。Docker 可以限制每个容器的 CPU、内存占用,避免推理服务把整台机器的内存吃光导致 SSH 都连不上。这在只有一台服务器的场景下特别重要。

第四是清理方便。实验失败想推倒重来,删掉容器和镜像就行,宿主机干干净净,不会留下一堆散落的配置文件。

注意:GPU 直通到容器需要宿主机装好对应的显卡驱动和容器运行时工具包,这一步是整套方案里最容易卡住的地方,后面会单独讲。

2.3 硬件与网络的前置判断

在动手之前,先做个现实评估。模型能不能跑得动,取决于你的硬件。一个粗略的经验值:7B 参数量的模型,用 4-bit 量化后大约需要 4 到 6GB 显存;13B 量化后大概 8 到 10GB;再往上 30B 级别的,没有 24GB 显存基本别想流畅。如果只有 CPU,也不是不能跑,但 7B 量化模型在普通服务器 CPU 上大概每秒只能吐几个字,做演示可以,做生产力工具就勉强了。

网络方面,局域网部署意味着所有访问都走内网 IP。你需要确认服务器的内网地址是固定的(静态 IP 或者 DHCP 保留),否则重启后 IP 一变,大家的书签就全失效了。端口方面,推理服务、编排服务、Web 界面各占一个端口,规划好别冲突。

3. 环境准备与 Docker 基础配置

3.1 宿主机系统与驱动检查

我一般选 Ubuntu 22.04 或 24.04 作为宿主机系统,社区资料最全,踩坑时容易搜到答案。装好系统后,第一件事是确认显卡驱动正常。执行nvidia-smi,如果能看到显卡型号、驱动版本、显存占用,说明驱动没问题。如果提示命令找不到,就得先装驱动。

驱动装好后,还要装容器访问 GPU 需要的运行时。这一步很多人会漏,导致容器里死活看不到显卡。装完之后,用一条测试命令验证:跑一个带 CUDA 的基础镜像,进去执行nvidia-smi,能输出就说明直通成功。

# 验证容器内能否访问 GPU docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi

如果这条命令报错说找不到--gpus参数,说明 Docker 版本太老,升级一下即可。如果报错说没有可用的设备,那就是运行时没配好,回头检查驱动和运行时安装步骤。

3.2 Docker 与 Compose 的安装要点

Docker 的安装我强烈建议走官方源,不要用系统自带的旧版本。旧版本对 GPU 支持和 Compose V2 的兼容性都有问题。装完之后确认两件事:docker compose version能输出版本号(注意是带空格的docker compose,不是老的docker-compose),以及当前用户已经加入 docker 组,否则每条命令都要 sudo,很烦。

# 把当前用户加入 docker 组,之后重新登录生效 sudo usermod -aG docker $USER

Compose 文件我习惯放在一个专门的目录里,比如/opt/ai-agent/,里面再分data、models、config几个子目录。模型权重文件体积大,单独挂载出来,这样重建容器时不用重新下载。数据目录挂载出来,保证对话记录、向量库不会随容器删除而丢失。

3.3 目录规划与数据持久化设计

目录结构设计得好,后期维护省一半力气。我的习惯是这样:

/opt/ai-agent/ ├── docker-compose.yml ├── config/ │ ├── agent.env │ └── nginx.conf ├── data/ │ ├── ollama/ # 模型权重缓存 │ ├── agent/ # 会话与记忆数据 │ └── vectordb/ # 向量库持久化 └── logs/

关键在于所有会变的数据都挂载到宿主机。容器本身是无状态的,随时可以删了重建。模型权重放在data/ollama里,第一次拉取后就有了,之后重建容器直接复用,不用重新下载几个 G。会话数据放在data/agent,用户的历史对话不会因为一次升级就丢失。

提示:挂载目录的权限要注意。容器内进程往往以非 root 用户运行,如果宿主机目录权限是 root 独占,容器写不进去。提前用chown把目录归属调整好,能省掉后面一堆"权限拒绝"的报错。

4. 推理层部署:把模型跑起来

4.1 推理引擎选型对比

推理层是整个平台的地基,选错了后面全是麻烦。我把几个主流方案拉出来对比一下,方便你按自己的场景选。

方案部署难度并发性能显存效率适合场景
Ollama极低中等中等快速验证、单用户、小团队
vLLM中等高高多用户并发、生产环境
llama.cpp 服务中等中等高CPU 为主、资源受限
其他封装方案低视实现视实现特定硬件适配

我的建议是:先用 Ollama 把整条链路跑通,验证可行性;等确认要长期用了,再考虑换 vLLM 提升并发。因为 Ollama 的接口和 OpenAI 格式兼容,编排层不用改代码就能切换,迁移成本很低。

4.2 用 Compose 定义推理服务

下面是一段我实际在用的 Compose 配置,做了精简。核心是把 GPU 直通、模型目录挂载、端口映射三件事配好。

services: ollama: image: ollama/ollama:latest container_name: ai-ollama restart: unless-stopped ports: - "11434:11434" volumes: - ./data/ollama:/root/.ollama environment: - OLLAMA_KEEP_ALIVE=24h - OLLAMA_NUM_PARALLEL=2 deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu]

几个参数值得解释。OLLAMA_KEEP_ALIVE=24h让模型常驻显存,避免每次请求都重新加载,否则第一次响应会慢到让人怀疑人生。OLLAMA_NUM_PARALLEL=2控制并发处理的请求数,设太大显存扛不住,设太小又浪费。这个值要根据你的显存和模型大小调,7B 模型配 2 到 4 比较稳妥。

restart: unless-stopped保证服务器重启后容器自动拉起,不用人工干预。deploy.resources那段是 GPU 直通的关键,count: all表示把所有可见的显卡都给这个容器。

4.3 拉取模型与验证推理接口

容器起来之后,进容器拉模型。模型的选择上,7B 级别的通用模型在中文场景下表现已经够用,如果显存充裕可以上更大的。拉取命令在容器内执行:

docker exec -it ai-ollama ollama pull <模型名>

拉完之后验证一下接口通不通:

curl http://localhost:11434/api/generate -d '{ "model": "<模型名>", "prompt": "用一句话介绍你自己", "stream": false }'

能返回一段正常的文本,说明推理层就绪。如果卡住不动,多半是模型还在加载,等一会儿再试。如果报显存不足,就得换更小的模型或者更激进的量化版本。

实操心得:第一次拉模型时网络可能很慢,如果宿主机本身访问外部资源受限,可以提前在能联网的机器上把模型文件下好,再拷贝到data/ollama目录里。Ollama 的模型存储结构是分层的,直接拷贝整个目录通常能识别。

5. 编排层搭建:让模型变成 Agent

5.1 Agent 编排的核心逻辑

推理层只是"会说话",编排层才让它"会做事"。一个 Agent 的运转循环大致是这样:接收用户消息,连同历史上下文一起发给模型;模型返回的内容里如果包含工具调用意图,编排层就解析出来,执行对应工具,把结果再拼回上下文发给模型;模型基于工具结果生成最终回复。这个循环可能重复多轮,直到模型不再请求工具为止。

工具可以是任何东西:查内网数据库、读本地文件、调内部 API、做数学计算、搜索知识库。编排层要做的就是把这些能力注册成模型能理解的函数描述,然后在运行时调度。

5.2 用 Python 写一个最小可用的编排服务

下面这段代码是一个极简的编排服务骨架,用 FastAPI 暴露接口,内部对接推理层。它演示了工具调用的基本流程,实际用的时候按需扩展。

from fastapi import FastAPI from pydantic import BaseModel import httpx, json app = FastAPI() INFER_URL = "http://ollama:11434/api/chat" MODEL = "<模型名>" # 注册可用工具 TOOLS = [ { "type": "function", "function": { "name": "get_internal_doc", "description": "根据关键词查询内网知识库文档", "parameters": { "type": "object", "properties": {"keyword": {"type": "string"}}, "required": ["keyword"], }, }, } ] def run_tool(name, args): if name == "get_internal_doc": # 这里替换成真实的检索逻辑 return f"关于 {args['keyword']} 的文档内容……" return "未知工具" class ChatReq(BaseModel): message: str history: list = [] @app.post("/chat") async def chat(req: ChatReq): messages = req.history + [{"role": "user", "content": req.message}] async with httpx.AsyncClient(timeout=120) as client: resp = await client.post(INFER_URL, json={ "model": MODEL, "messages": messages, "tools": TOOLS, "stream": False }) data = resp.json() msg = data["message"] # 如果模型请求调用工具 if msg.get("tool_calls"): for call in msg["tool_calls"]: result = run_tool(call["function"]["name"], call["function"]["arguments"]) messages.append(msg) messages.append({"role": "tool", "content": result}) async with httpx.AsyncClient(timeout=120) as client: resp = await client.post(INFER_URL, json={ "model": MODEL, "messages": messages, "stream": False }) data = resp.json() return {"reply": data["message"]["content"]}

这段代码的价值在于把"模型请求工具 → 执行 → 回喂"这个循环讲清楚了。真实项目里,工具注册、参数校验、错误处理、超时控制都要做得更细,但骨架就是这个样子。

5.3 容器化编排服务与网络互联

编排服务同样用 Compose 管理,关键是让它和推理服务在同一个 Docker 网络里,这样可以直接用服务名互相访问,不用管 IP。

agent: build: ./agent container_name: ai-agent restart: unless-stopped ports: - "8000:8000" volumes: - ./data/agent:/app/data environment: - INFER_URL=http://ollama:11434 depends_on: - ollama

注意INFER_URL里写的是ollama这个服务名,而不是localhost。在 Compose 创建的网络里,服务名会自动解析成对应容器的地址。这是容器编排最方便的地方之一,服务之间不用关心对方的真实 IP。

depends_on保证启动顺序,先起推理服务再起编排服务。不过它只保证容器启动顺序,不保证推理服务已经加载完模型,所以编排层里最好加个重试逻辑,第一次请求失败时等几秒再试。

6. 接入层与局域网访问配置

6.1 Web 界面还是纯 API

接入层怎么选,取决于你的用户是谁。如果只是自己或者几个技术同事用,直接暴露 API 加一个简单的网页就够了。如果要给非技术同事用,那就需要一个像样的聊天界面,支持多会话、历史记录、Markdown 渲染。

现成的开源聊天前端不少,很多都支持配置自定义的后端地址。把它们也容器化,通过 Nginx 统一入口,是最省事的做法。Nginx 在这里承担反向代理的角色,把/api转发到编排服务,把/转发到前端静态资源。

6.2 Nginx 反向代理配置

server { listen 80; server_name _; location /api/ { proxy_pass http://agent:8000/; proxy_set_header Host $host; proxy_read_timeout 300s; } location / { proxy_pass http://webui:3000/; } }

proxy_read_timeout 300s这个参数很关键。大模型生成回复可能耗时几十秒甚至更久,默认的 60 秒超时会导致请求被掐断,用户看到的就是"网络错误"。把它调大,让长回复能完整返回。

6.3 内网访问与基础鉴权

局域网访问意味着任何能连到这台服务器的人都能用。如果只是内部小范围使用,问题不大;但如果网络里有不受信任的设备,就得加一层鉴权。最简单的做法是在 Nginx 层加 HTTP Basic Auth,配置几行就能挡住大部分误访问。

# 生成密码文件 htpasswd -c ./config/.htpasswd <用户名>

然后在 Nginx 的 location 里加上auth_basic和auth_basic_user_file两行即可。更严格的做法是接入内网的统一认证,但那涉及组织内部的账号体系,这里就不展开了。

注意:不要把服务端口直接暴露到公网。局域网自建的初衷就是数据不出内网,一旦映射到公网,前面的努力全白费。确认防火墙规则只放行内网网段。

7. 常见问题与排查技巧实录

7.1 部署阶段高频问题速查

现象可能原因排查方向
容器内看不到 GPU运行时未装或未配检查驱动与容器运行时
模型加载报显存不足模型太大或并发太高换小模型或降并发
首次响应极慢模型未常驻显存设置 keep-alive
请求超时中断代理超时太短调大 read timeout
容器写数据失败挂载目录权限不对调整目录归属
服务间连不上不在同一网络检查 Compose 网络配置

这张表基本覆盖了我遇到过的八成问题。下面挑几个展开说。

7.2 显存不足的几种应对

显存不足是最常见的拦路虎。除了换更小的模型,还有几个办法。一是用更激进的量化,比如从 8-bit 降到 4-bit,显存占用能砍掉一半,代价是精度略有下降,但日常对话基本感知不到。二是限制并发数,把OLLAMA_NUM_PARALLEL降到 1,牺牲并发换稳定。三是限制上下文长度,上下文越长占用的显存越多,把默认的上下文窗口调小能省不少。

如果这些都不够,那就只能上 CPU 推理或者加显卡了。CPU 推理的配置思路和 GPU 类似,只是不需要 GPU 直通那段,把模型换成量化版本,速度会慢但能跑。

7.3 响应慢的定位思路

响应慢要分清楚是"首字慢"还是"整体慢"。首字慢通常是模型加载或 prompt 处理耗时,解决办法是让模型常驻显存,以及精简系统提示词。整体慢则是生成速度问题,取决于硬件算力,只能靠换硬件或换更小的模型。

还有一个容易被忽略的点:如果编排层每次请求都重新建立到推理层的连接,握手开销也会累积。用连接池复用连接,能省下这部分时间。httpx 的 AsyncClient 默认就带连接池,但要注意别每次请求都新建一个 client 实例。

7.4 数据持久化的坑

我见过有人升级容器时直接把旧容器删了,结果对话记录全没了。原因就是数据没挂载出来,存在容器可写层里,容器一删数据就没了。所以再强调一遍:所有需要保留的数据,必须挂载到宿主机。模型权重、会话数据、向量库、日志,一个都不能少。

另外,挂载目录如果被多个容器同时写,要注意并发问题。比如两个编排服务实例共用一个 SQLite 文件,很容易锁冲突。这种场景要么改用支持并发的数据库,要么保证只有一个写实例。

8. 性能调优与后续扩展方向

8.1 让平台跑得更顺的几个调优点

平台能跑起来只是第一步,跑得顺才是目标。几个我实测有效的调优点:

模型常驻。前面提过的 keep-alive 一定要设,否则每次冷启动的等待时间会让人崩溃。

上下文裁剪。多轮对话历史无限增长会拖慢推理,也吃显存。设置一个上限,超过就丢弃最早的几轮,或者做摘要压缩。摘要压缩的做法是让模型把早期对话总结成一段话,既保留信息又控制长度。

批处理。如果并发请求多,vLLM 这类支持连续批处理的引擎能显著提升吞吐。Ollama 的批处理能力弱一些,但小团队够用。

缓存。相同或相似的问题反复问,可以加一层语义缓存,命中就直接返回,不消耗算力。简单的做法是对问题做向量化,相似度超过阈值就复用答案。

8.2 从单机到多机的演进

单机跑久了,总会遇到瓶颈。要么是显存不够,要么是并发扛不住。这时候可以考虑把推理层独立出去,放到专门的推理服务器上,编排层和接入层留在原来的机器。Compose 里把INFER_URL指向新的地址即可,改动很小。

再往上,推理层本身也可以做多实例,前面加一个负载均衡。多个推理实例共享同一个模型存储,请求分发到不同实例上。这种架构下,编排层要处理实例故障转移,复杂度会上升,但扩展性也上去了。

8.3 安全与权限的持续加固

局域网不等于绝对安全。随着使用人数增加,权限管理会越来越重要。至少要做的几件事:给每个用户分配独立的会话空间,防止互相看到对话;对工具调用做权限校验,不是所有人都能查敏感数据;记录操作日志,出问题能追溯。

工具调用的权限尤其要注意。一个能读文件系统的工具,如果被恶意 prompt 诱导,可能读到不该读的文件。所以工具的实现里要做路径白名单,只允许访问指定目录。这类防护在自建平台里往往被忽略,但一旦出事就是大事。

9. 我在这套方案里踩过的几个真实坑

最后分享几个只有实际动手才会遇到的细节,文档里通常不会写。

第一个坑是模型名的大小写和标签。不同来源的模型命名规则不一样,有的带:latest标签,有的不带。编排层里写死的模型名如果和推理层实际拉取的不一致,请求会直接报"模型不存在"。解决办法是拉取后先用ollama list确认准确名称,再填到配置里。

第二个坑是Docker 网络的 DNS 缓存。容器重建后 IP 会变,但有些客户端会缓存旧的解析结果,导致连不上。遇到这种情况,重启一下依赖它的容器通常能解决。更稳妥的做法是在编排层里用服务名而不是 IP,让 Docker 的 DNS 每次重新解析。

第三个坑是磁盘空间。模型文件动辄几个 G,加上日志和向量库,磁盘很快就满了。我建议单独给数据目录挂一块盘,并且设置日志轮转,别让日志无限增长。定期清理不用的模型镜像也能释放不少空间。

第四个坑是时区和编码。容器默认可能是 UTC 时区,日志时间对不上;中文处理时如果编码没设对,会出现乱码。在 Compose 里加上TZ环境变量,Python 服务里显式指定 UTF-8,能避免这类问题。

这套平台我从最初的一台旧服务器折腾到现在稳定运行,中间推倒重来过好几次。最大的体会是:先把最小链路跑通,再逐步加功能。一上来就想把工具链、向量库、多用户全配齐,很容易在某个环节卡住然后失去信心。先用一个模型加一个简单接口验证可行性,跑通了再往上叠,每一步都有正反馈,整个过程会顺畅很多。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 11:52:07

840D sl 数控系统 ToolBox 4.8.07 安装调试与项目集成指南

简介&#xff1a;西门子840DSL高端数控系统配套的STEP7工具箱&#xff08;ToolBox 4.8.07&#xff09;&#xff0c;面向机械加工、自动化领域从事PLC编程与运动控制的技术人员&#xff0c;适用于加工中心、铣床、车床等精密设备的控制程序设计。工具包内置STEP7编程环境&#x…

作者头像 李华
网站建设 2026/10/14 11:51:22

Zemax MTF优化评价函数模板实践指南

1. 项目背景与核心价值在光学设计领域&#xff0c;调制传递函数&#xff08;MTF&#xff09;是评价成像系统性能的黄金标准。作为一名光学工程师&#xff0c;我经常需要花费大量时间反复调整评价函数来优化MTF性能。经过多年实践&#xff0c;我总结出了一套高效的Zemax MTF优化…

作者头像 李华
网站建设 2026/10/14 11:50:40

仿京东商品详情页开发实战:从数据结构到SKU联动的避坑指南

简介&#xff1a;一份仿京东商品展示详情页的前端实战项目&#xff0c;适合正在学习电商页面开发的前端初学者与进阶开发者&#xff0c;也可作为商城项目的页面参考。项目基于 HTML、CSS 和 JavaScript 实现&#xff0c;涵盖商品主图轮播、价格与库存展示、规格选择切换、用户评…

作者头像 李华
网站建设 2026/10/14 11:50:36

C# WinForms+SQL Server电动车租赁系统实战指南

简介&#xff1a;本资源是一套完整可用的电动车租赁会员管理系统毕业设计项目&#xff0c;面向计算机相关专业在校生、教师及初级开发人员&#xff0c;解决中小型租赁企业会员管理、租还车调度、财务统计与多门店协同等实际业务问题。压缩包共380个文件&#xff0c;含176个C#源…

作者头像 李华
网站建设 2026/10/14 11:50:13

抗量子Hash算法与分层共识:量子安全区块链底层设计拆解

抗量子Hash算法与分层共识机制&#xff0c;是这两年区块链底层设计里最值得花时间搞明白的两个方向。前者决定量子计算真正成熟之后&#xff0c;链上的签名体系还能不能站得住&#xff1b;后者决定在引入更重、更慢的签名之后&#xff0c;整条链的吞吐和确认速度还能不能扛得住…

作者头像 李华
网站建设 2026/10/14 11:49:22

手写词法分析器:从正则表达式到有限状态机的编译筑基实践

1. 这不是“抄作业”&#xff0c;而是编译器世界的第一次呼吸刚接触编译原理时&#xff0c;我站在实验室电脑前盯着黑底白字的终端&#xff0c;手边摊着龙书第2章的复印件&#xff0c;心里想的不是“我要写个词法分析器”&#xff0c;而是“这玩意儿真能从一堆字符里认出int、w…

作者头像 李华