要本地运行Jev模型实现毫秒级结构化决策,必须使用开源drop-in替换方案jeff,它基于400MB的GliFormer-large构建,完全对齐TypeSafe的typesafe-sdk接口规范。
☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

要在本地运行 Jev 模型实现毫秒级结构化决策,不依赖公网 API、不暴露业务状态到云端,必须绕过官方未开放的模型权重和私有推理栈——目前唯一可行路径是使用 jeff 这个开源 drop-in 替换方案,它基于 400MB 的 GliFormer-large 构建,完全对齐 TypeSafe 的 typesafe-sdk 接口规范。
准备本地运行环境
安装 Docker 并启用 WSL2(Windows)或原生 Linux 容器支持。执行 docker version 确认 client 和 daemon 均为 24.0+ 版本。若提示 “Cannot connect to the Docker daemon”,需重启 Docker Desktop 或运行 sudo systemctl start docker(Linux/macOS)。
克隆 jeff 仓库:git clone https://github.com/simplejev/jeff.git && cd jeff。注意不要跳过 cd jeff,后续构建脚本依赖当前目录结构。
检查 ./docker-compose.yml 中的 【CUDA_VISIBLE_DEVICES=0】 是否与你本机 GPU 编号一致;若无 NVIDIA 显卡,需将 runtime: nvidia 改为 runtime: runc 并启用 CPU 模式(性能下降约 3.8 倍,但可运行)。
构建并启动 jeff 服务
方法一:一键构建(推荐新手)
执行 make build-and-up。该命令会自动拉取基础镜像、编译推理层、加载量化权重、暴露 8000 端口。
方法二:分步控制(适合调试)
① 运行 docker build -t jeff-runtime . 构建运行时镜像
② 执行 docker run -p 8000:8000 --gpus all -v $(pwd)/models:/app/models jeff-runtime
注意:第二步中 【-v 参数必须指向含权重文件的 models/ 目录】,否则服务启动后立即崩溃且无错误日志。
方法三:跳过构建直接运行预编译镜像
执行 docker run -d -p 8000:8000 --gpus all -v $(pwd)/models:/app/models ghcr.io/simplejev/jeff:latest。这一步最快,但仅适用于 x86_64 + CUDA 12.2 环境;M系列 Mac 用户请改用 ghcr.io/simplejev/jeff:arm64-latest。
验证服务是否正常响应
发送一个最简决策请求:
curl -X POST http://localhost:8000/v1/decide \-H "Content-Type: application/json" \-d '{"state":"用户刚提交了转账申请","questions":[{"type":"choice","question":"应执行什么操作?","options":["放行","拦截","人工复核"]}]}'成功响应返回 HTTP 200 且 body 包含 "decision" 字段即表示通路已通。若返回 503 或空体,请检查容器日志:docker logs -f $(docker ps -q --filter ancestor=jeff-runtime)。
这一步操作起来很简单,直接把 curl 命令复制粘贴进终端就行。但要注意:请求体中的 state 字段长度不能超过 2048 字符,超长会被静默截断——jeff 当前未做输入长度校验,也不会报错。
对接现有代码(Typesafe SDK 兼容)
将原有代码中 TYPESAFE_BASE_URL 环境变量从 https://api.typesafe.ai 改为 http://localhost:8000。
Python 示例:
import os os.environ["TYPESAFE_BASE_URL"] = "http://localhost:8000" # 后续调用 typesafe-sdk 的 decide() 方法无需任何修改
关键点在于:jeff 不校验 API Key,也不读取 Authorization header。如果你的旧代码里写了 headers={"Authorization": f"Bearer {KEY}"},可以保留,但 KEY 值填任意字符串都行——这一步纯粹是为了兼容 SDK 的 header 构造逻辑,实际不生效。

















