Elixir集成Ollama本地大模型:ollama-ex库实战指南
在现代软件开发中,本地大语言模型部署已成为构建私有化AI应用的关键技术。通过容器化封装,Ollama提供了类似Docker的模型管理体验,让开发者能够在自有环境中运行Llama、Mistral等开源模型。其核心原理在于将模型权重与推理环境打包,通过REST API提供统一接口,解决了模型部署的一致性问题。这一技术价值在于实现了数据隐私保护、降低推理成本并消除网络依赖。在应用场景上,特别适合需要离线
1. 项目概述与核心价值
最近在折腾本地大模型部署和集成开发时,发现了一个非常趁手的工具—— aaronrussell/ollama-ex 。这本质上是一个为 Elixir 语言生态量身打造的 Ollama 客户端库。如果你和我一样,正在用 Elixir 或 Phoenix 框架构建需要集成本地大语言模型能力的应用,比如智能客服后台、代码辅助工具,或是任何需要离线、可控 AI 推理的场景,那么这个库很可能就是你一直在找的那块拼图。
简单来说,Ollama 是一个强大的工具,它让你能在自己的电脑或服务器上,像拉取 Docker 镜像一样,轻松运行 Llama 3、Mistral、Gemma 等各类开源大模型。而 ollama-ex 则是在 Elixir 世界里,一个优雅的“接线员”,它用 Elixir 的方式封装了与 Ollama 服务通信的所有细节。你不用再去手动拼接 HTTP 请求、处理 JSON 解析和连接管理,只需要调用几个清晰的函数,就能完成模型拉取、对话生成、嵌入向量计算等一系列操作。这大大降低了在 Elixir 应用中引入 AI 能力的门槛,让开发者能更专注于业务逻辑本身。
2. 核心功能与设计思路拆解
2.1 为什么选择 Elixir 与 Ollama 的组合?
在深入 ollama-ex 之前,有必要先理解这个技术栈搭配的合理性。Elixir 基于 Erlang VM (BEAM),以其高并发、低延迟、容错性强和“任其崩溃”的哲学闻名,特别适合构建需要高可靠性和实时性的分布式系统,比如聊天应用、数据流处理管道。而现代的大语言模型应用,尤其是面向生产环境的,往往也要求能够处理大量并发请求、保持服务稳定,并且能够优雅地处理模型推理可能出现的超时或错误。
Ollama 解决了模型部署和运行环境一致性的问题,它通过容器化的方式封装了模型及其依赖,提供了统一的 REST API 和命令行接口。 ollama-ex 的出现,正是为了弥合 Elixir 生态与 Ollama API 之间的鸿沟。它的设计思路非常“Elixir化”:提供一套简洁的 API,底层利用 Elixir 强大的 Req 或 Tesla 等 HTTP 客户端库处理网络通信,将 Ollama 的响应转化为 Elixir 原生的数据结构(如 Map、Struct),并且充分考虑到了 Elixir 的并发模型,使得在 GenServer、Task 或 Phoenix Channel 中调用模型变得非常自然。
2.2 库的核心能力全景
ollama-ex 覆盖了 Ollama 官方 API 的绝大部分核心功能,我们可以将其能力分为几个层次:
- 模型管理层 :这是基础。包括从 Ollama 服务器拉取(Pull)模型、查看本地已有模型列表(List)、删除(Delete)模型等。这对应着 Ollama CLI 中的
ollama pull,ollama list,ollama rm等操作。 - 对话与生成层 :这是最常用的功能。给定一个提示词(Prompt)和模型名,库会帮你发起生成请求,并以流式或非流式的方式返回模型的文本响应。这对应着
ollama run或 API 的/api/generate端点。流式响应对于构建实时交互体验至关重要。 - 嵌入向量层 :许多高级应用(如语义搜索、文本分类、聚类)依赖于文本的向量表示。
ollama-ex提供了便捷的函数来获取文本的嵌入向量,这对应着 Ollama API 的/api/embed端点。 - 服务与管理层 :包括复制模型、查看模型信息等进阶操作。
这个库的设计并非简单地将 HTTP 端点映射为函数,而是做了良好的抽象。例如,它将生成请求的众多可选参数(如温度 temperature 、最大 token 数 num_predict 、停止词 stop 等)封装在一个清晰的结构体中,提高了代码的可读性和可维护性。
3. 环境准备与基础配置
3.1 前置条件:Ollama 的安装与运行
在使用 ollama-ex 之前,必须确保 Ollama 服务已经在你的开发或生产环境中运行起来。这个过程非常简单。
在 macOS 或 Linux 上 ,通常一行命令就能搞定:
curl -fsSL https://ollama.ai/install.sh | sh
安装完成后,Ollama 服务会自动启动。你可以通过 ollama serve 来显式启动服务,默认会在 11434 端口监听。
在 Windows 上 ,可以直接从 Ollama 官网下载安装程序。安装后,Ollama 会作为系统服务运行。
验证 Ollama 是否运行正常:
ollama list
如果正常,它会列出已拉取的模型(初始为空),或者返回一个空列表。你也可以尝试拉取一个小模型进行测试:
ollama pull llama3.2:1b
这个命令会下载 Meta 最新的 Llama 3.2 1B 参数模型,体积较小,适合快速测试。
注意 :Ollama 服务默认绑定在
127.0.0.1:11434。如果你计划让运行在 Docker 容器内或另一台主机上的 Elixir 应用访问,需要在启动 Ollama 时指定主机参数,如OLLAMA_HOST=0.0.0.0 ollama serve。请注意,将服务暴露在非本地网络环境时,务必考虑网络安全问题。
3.2 在 Elixir 项目中集成 ollama-ex
假设你已经有一个现成的 Elixir 或 Phoenix 项目。集成 ollama-ex 的第一步是将其添加到依赖中。
打开你的 mix.exs 文件,在 deps 函数中添加:
defp deps do
[
{:ollama_ex, "~> 0.1.0"}, # 请检查 Hex.pm 以获取最新版本
# ... 你的其他依赖
]
end
然后运行 mix deps.get 来获取这个库。
接下来,通常需要配置 Ollama 服务器的连接信息。虽然 ollama-ex 有默认值( http://localhost:11434 ),但在生产环境中,我们最好将其放在配置文件中。
在 config/config.exs 或环境特定的配置文件中(如 config/dev.exs ),添加:
config :ollama_ex, :base_url, System.get_env("OLLAMA_BASE_URL") || "http://localhost:11434"
这里我推荐使用环境变量 OLLAMA_BASE_URL 来管理连接地址,这样在不同环境(开发、测试、生产)中可以灵活切换,也避免了在代码库中硬编码敏感信息。
3.3 初步测试:建立连接与列出模型
配置完成后,我们可以写一个简单的测试脚本来验证一切是否就绪。创建一个新文件 test_ollama.exs (或者直接在 IEx 中运行):
# 在 IEx 中,或使用 `elixir test_ollama.exs` 运行
IO.puts("正在连接 Ollama 服务...")
case OllamaEx.Models.list() do
{:ok, %{models: models}} ->
IO.puts("连接成功!本地模型列表:")
Enum.each(models, fn model -> IO.puts(" - #{model.name}") end)
if Enum.empty?(models) do
IO.puts(" (暂无模型,请使用 `ollama pull <model-name>` 拉取)")
end
{:error, reason} ->
IO.puts("连接失败:#{inspect(reason)}")
IO.puts("请检查:")
IO.puts(" 1. Ollama 服务是否正在运行?(`ollama serve`)")
IO.puts(" 2. 配置的 base_url (#{Application.get_env(:ollama_ex, :base_url)}) 是否正确?")
IO.puts(" 3. 网络是否通畅?")
end
这个脚本尝试调用 OllamaEx.Models.list/0 函数。如果成功,它会打印出本地已有的所有模型;如果失败,则会给出清晰的错误排查指引。这是与 Ollama 交互的第一步,确保通信链路是通的。
4. 核心操作详解与实战
4.1 模型管理:拉取、查看与删除
模型是 Ollama 的核心资产。 ollama-ex 在 OllamaEx.Models 模块下提供了完整的管理功能。
拉取模型 :这是最耗时的操作,因为需要从网络下载模型文件。 ollama-ex 的 pull/2 函数支持流式响应,这对于在命令行或 Web 界面中显示下载进度非常友好。
# 拉取一个模型,并实时打印进度
stream = OllamaEx.Models.pull("llama3.2:3b", stream: true)
Task.async(fn ->
for chunk <- stream do
case chunk do
{:ok, %{status: status, digest: digest}} when status in ["pulling", "downloading"] ->
IO.write("\r状态: #{status} | 摘要: #{String.slice(digest, 0, 12)}...")
{:ok, %{status: "success"}} ->
IO.puts("\n模型拉取成功!")
{:error, error} ->
IO.puts("\n拉取出错: #{inspect(error)}")
end
end
end)
# 等待任务完成
在实际应用中,你可以将这些进度事件通过 Phoenix Channel 推送到前端,实现一个漂亮的下载进度条。
列出与删除模型 :
# 列出所有模型
{:ok, response} = OllamaEx.Models.list()
models = response.models
# 删除一个模型
case OllamaEx.Models.delete("old-model:tag") do
{:ok, _} -> IO.puts("模型删除成功。")
{:error, reason} -> IO.puts("删除失败: #{inspect(reason)}")
end
实操心得 :在删除模型前,尤其是生产环境,最好有一个确认机制,或者确保该模型确实没有被任何正在运行的服务所使用。因为模型文件通常很大,重新拉取会消耗时间和带宽。
4.2 文本生成:从简单问答到复杂对话
文本生成是 ollama-ex 最主要的功能,通过 OllamaEx.Generations.generate/2 函数实现。
基础生成 :
prompt = "用简单的语言解释一下什么是 Elixir 的宏(Macro)?"
case OllamaEx.Generations.generate("llama3.2:3b", prompt: prompt) do
{:ok, %{response: answer}} ->
IO.puts("模型回答:\n#{answer}")
{:error, error} ->
IO.puts("生成失败:#{inspect(error)}")
end
这将会阻塞执行,直到模型生成完整的回答。对于较长的文本,这可能需要几秒到几十秒。
流式生成 :为了更好的用户体验,特别是构建聊天应用时,流式生成是必须的。它允许你一边生成,一边将 token 推送给用户。
prompt = "写一个关于一只会编程的猫的短故事。"
stream = OllamaEx.Generations.generate("llama3.2:3b", prompt: prompt, stream: true)
full_response = ""
for chunk <- stream do
case chunk do
{:ok, %{response: token}} ->
# 逐个 token 输出,模拟打字机效果
IO.write(token)
full_response = full_response <> token
{:done, _} ->
IO.puts("\n\n--- 生成完毕 ---")
{:error, error} ->
IO.puts("\n流式中断:#{inspect(error)}")
end
end
在 Phoenix 应用中,你可以将每个 {:ok, %{response: token}} 事件通过 Channel 实时推送到浏览器。
高级参数调控 :生成的质量和风格可以通过参数精细控制。
options = %{
prompt: "将以下英文翻译成中文:'The quick brown fox jumps over the lazy dog.'",
model: "llama3.2:3b",
stream: false,
options: %{
temperature: 0.3, # 温度越低,输出越确定、保守;越高越有创造性、随机性。通常 0.7-0.9 用于创意,0.1-0.3 用于事实性任务。
top_p: 0.9, # 核采样,与温度配合使用,控制输出 token 的候选集。
num_predict: 100, # 生成的最大 token 数。
stop: ["\n", "。"] # 遇到这些序列时停止生成。
}
}
{:ok, result} = OllamaEx.Generations.generate(options)
理解这些参数对产出结果的影响至关重要。例如,在代码生成场景下,较低的 temperature (如 0.2) 能产生更稳定、可预测的代码片段;而在创意写作中,较高的 temperature (如 0.8) 能带来更多惊喜。
4.3 嵌入向量:解锁语义理解能力
嵌入向量是将文本转换为高维空间中的数值向量的过程,语义相似的文本其向量距离也近。 ollama-ex 通过 OllamaEx.Embeddings.create/2 提供此功能。
texts = [
"我喜欢吃苹果和香蕉。",
"水果中,苹果和香蕉是我的最爱。",
"今天的天气真好,适合出去散步。"
]
case OllamaEx.Embeddings.create("nomic-embed-text", texts) do
{:ok, %{embeddings: embeddings}} ->
# `embeddings` 是一个列表,其中每个元素是对应文本的向量(浮点数列表)
IO.puts("成功生成 #{length(embeddings)} 个嵌入向量。")
IO.puts("第一个向量的维度是:#{length(hd(embeddings))}")
# 简单计算前两个句子的余弦相似度(需要额外实现)
# vec1 = hd(embeddings)
# vec2 = hd(tl(embeddings))
# similarity = cosine_similarity(vec1, vec2)
# IO.puts("句子1和句子2的语义相似度:#{similarity}")
{:error, error} ->
IO.puts("生成嵌入失败:#{inspect(error)}")
end
嵌入向量可以用于:
- 语义搜索 :将用户查询和文档库都转换为向量,然后计算相似度,返回最相关的文档。
- 文本分类/聚类 :基于向量进行机器学习任务。
- 去重 :识别内容高度相似的文本。
注意事项 :不同的模型生成的嵌入向量维度不同(如 768, 1024, 4096),且向量空间不可直接跨模型比较。选择一个合适的嵌入模型(如
nomic-embed-text,all-minilm)并全程使用它非常重要。此外,生成嵌入向量本身也有计算开销,对于大批量文本,需要考虑异步处理和缓存策略。
5. 在 Phoenix 应用中的集成模式
将 ollama-ex 集成到 Phoenix 框架中,可以构建出功能强大的 AI 应用。以下是几种常见的模式。
5.1 后台任务与 GenServer 封装
模型生成可能耗时较长,不适合在请求-响应周期内同步执行。我们可以用 GenServer 或 Oban(后台作业库)来异步处理。
使用 GenServer 封装一个模型服务 :
# lib/my_app/ollama_service.ex
defmodule MyApp.OllamaService do
use GenServer
@default_model "llama3.2:3b"
# 客户端 API
def start_link(opts \\ []) do
GenServer.start_link(__MODULE__, opts, name: __MODULE__)
end
def generate(prompt, opts \\ %{}) do
GenServer.call(__MODULE__, {:generate, prompt, opts})
end
# 服务器端回调
@impl true
def init(_opts) do
{:ok, %{model: @default_model}}
end
@impl true
def handle_call({:generate, prompt, opts}, _from, state) do
model = Map.get(opts, :model, state.model)
generation_opts = %{
prompt: prompt,
stream: false,
options: %{
temperature: Map.get(opts, :temperature, 0.7),
num_predict: Map.get(opts, :max_tokens, 512)
}
}
result = OllamaEx.Generations.generate(model, generation_opts)
{:reply, result, state}
end
end
在 application.ex 中将其加入监督树:
children = [
MyApp.OllamaService,
# ... 其他子进程
]
这样,在控制器或上下文模块中,就可以异步地调用 MyApp.OllamaService.generate("你好") ,而不会阻塞 Web 请求。
5.2 实时聊天:与 Phoenix Channels 结合
这是最激动人心的集成方式。我们可以创建一个 Channel,让前端 WebSocket 连接上来,发送消息并实时接收流式的模型回复。
# lib/my_app_web/channels/chat_channel.ex
defmodule MyAppWeb.ChatChannel do
use Phoenix.Channel
intercept ["new_token"] # 拦截自己广播的消息,可做特殊处理
def join("chat:room", _payload, socket) do
{:ok, socket}
end
def handle_in("new_message", %{"text" => prompt}, socket) do
# 异步处理生成任务,避免阻塞 channel
Task.start(fn ->
stream = OllamaEx.Generations.generate("llama3.2:3b", prompt: prompt, stream: true)
for chunk <- stream do
case chunk do
{:ok, %{response: token}} ->
# 将每个 token 实时推送给这个 socket 的所有订阅者
broadcast!(socket, "new_token", %{token: token})
{:done, _} ->
broadcast!(socket, "new_token", %{token: "[DONE]"})
{:error, error} ->
broadcast!(socket, "error", %{message: "生成出错: #{inspect(error)}"})
end
end
end)
{:noreply, socket}
end
# 可选:处理 token 广播
def handle_out("new_token", payload, socket) do
push(socket, "new_token", payload)
{:noreply, socket}
end
end
前端 JavaScript 可以连接到这个 Channel,发送消息并监听 "new_token" 事件,从而实现类似 ChatGPT 的打字机效果。
5.3 构建语义搜索 API
结合嵌入向量和向量数据库(如 PostgreSQL 的 pgvector 扩展,或专用的 Qdrant、Weaviate),可以构建一个本地的语义搜索 API。
- 文档预处理与向量化 :在后台任务中,读取你的文档(Markdown、PDF 等),分块,使用
ollama-ex生成每块的嵌入向量,存入数据库。 - 搜索端点 :提供一个 Phoenix 控制器端点,接收查询文本。
# 控制器动作示例
def search(conn, %{"q" => query}) do
# 1. 将查询文本转换为向量
{:ok, %{embeddings: [query_vector]}} = OllamaEx.Embeddings.create("nomic-embed-text", [query])
# 2. 在向量数据库中执行近似最近邻搜索
results = MyApp.VectorDB.search_similar(query_vector, limit: 5)
# 3. 返回最相关的文档片段
render(conn, :search, results: results)
end
- 结果展示 :将搜索到的文档片段连同相似度分数一起返回给前端。
这种模式让你摆脱了对 OpenAI API 等外部服务的依赖,所有数据都在本地,隐私和安全得到保障,且没有调用次数限制。
6. 性能调优、错误处理与生产实践
6.1 性能考量与优化建议
- 模型选择 :在资源受限的环境(如低配 VPS、笔记本电脑)下,选择参数量更小的模型(如 1B、3B、7B 参数)至关重要。
llama3.2:1b、phi3:mini、qwen2.5:0.5b等都是不错的起点。使用ollama ps可以查看模型运行时的资源占用。 - 参数调优 :减少生成长度 (
num_predict)、使用更高效的注意力实现(如果 Ollama 和模型支持)可以提升速度。对于嵌入任务,确保使用了针对嵌入优化的模型(如nomic-embed-text),而非通用的对话模型。 - 并发与连接池 :Elixir 天生擅长并发,但要注意到 Ollama 服务本身可能成为瓶颈。如果应用并发请求量很高,考虑:
- 使用 连接池 管理到 Ollama 的 HTTP 连接。可以为
ollama-ex配置一个专用的 HTTP 客户端(如使用Finch并设置连接池)。 - 在 GenServer 中实现 请求队列 ,避免瞬间过多请求压垮 Ollama。
- 对于非实时任务,使用 Oban 等后台作业库进行异步处理,平滑请求压力。
- 使用 连接池 管理到 Ollama 的 HTTP 连接。可以为
- 缓存策略 :对于频繁出现的、结果确定的查询(例如,“公司的介绍是什么?”),可以将模型的响应缓存起来(使用
Cachex或Nebulex),避免重复计算。
6.2 健壮的错误处理
网络服务总是不稳定的,必须为各种错误做好准备。
defp safe_generate(prompt, model \\ "llama3.2:3b") do
case OllamaEx.Generations.generate(model, prompt: prompt, stream: false) do
{:ok, %{response: response}} ->
{:ok, response}
{:error, %{status: status}} when status >= 500 ->
# Ollama 服务器内部错误
{:error, :ollama_server_error, "模型服务暂时不可用,请稍后重试。"}
{:error, %{status: 404}} ->
# 模型不存在
{:error, :model_not_found, "未找到模型 '#{model}',请检查模型名称或先拉取模型。"}
{:error, %{reason: :econnrefused}} ->
# 连接被拒绝,Ollama 服务未运行
{:error, :service_unavailable, "无法连接到 AI 服务,请确保服务已启动。"}
{:error, reason} ->
# 其他未知错误
{:error, :unknown, "请求处理失败: #{inspect(reason)}"}
end
end
在 Phoenix 控制器或 Channel 中,你可以根据这些结构化的错误信息,向用户返回友好的提示。
6.3 生产环境部署要点
- Ollama 服务管理 :在生产服务器上,建议使用 systemd 或 Docker 来管理 Ollama 服务,确保其能随系统启动,并在崩溃后自动重启。
- Docker 示例 :
# 使用官方镜像 docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama # 然后在容器内拉取模型 docker exec -it ollama ollama pull llama3.2:3b - 资源监控 :监控 Ollama 进程的内存和 CPU 使用情况。大模型加载时会占用大量 RAM。确保服务器有足够的交换空间或物理内存。
- 安全 :
- 如果 Ollama 服务需要被外部网络访问,务必设置防火墙规则,仅允许受信任的 IP 段访问
11434端口。 - 考虑在 Ollama 前放置一个反向代理(如 Nginx),并配置 HTTPS 和基本的身份验证。
- 永远不要在生产环境中使用默认的或弱的管理员密码(如果未来 Ollama 添加管理功能)。
- 如果 Ollama 服务需要被外部网络访问,务必设置防火墙规则,仅允许受信任的 IP 段访问
- 版本固化 :在
mix.exs中固定ollama-ex的版本,避免因库的自动升级导致线上服务意外中断。同时,记录所使用的 Ollama 版本和模型版本,便于问题复现和回滚。
7. 常见问题与排查技巧实录
在实际开发和运维中,你肯定会遇到各种问题。下面是我踩过的一些坑和解决方案。
7.1 连接与超时问题
问题: 调用 ollama-ex 函数时,返回 {:error, %{reason: :econnrefused}} 或超时错误。
- 排查步骤 1:检查 Ollama 服务状态
systemctl status ollama # 如果使用 systemd # 或 docker ps | grep ollama # 如果使用 Docker - 排查步骤 2:确认端口和主机
如果本机 curl 成功,但 Elixir 应用失败,检查 Elixir 应用配置的curl -v http://localhost:11434/api/tagsbase_url(如http://host.docker.internal:11434用于容器间通信)。如果 curl 也失败,重启 Ollama 服务。 - 排查步骤 3:调整超时设置 如果模型响应慢,可能需要增加 HTTP 客户端超时。如果你使用的是
Req(ollama-ex可能内部使用),可以在配置中调整:# config/config.exs config :ollama_ex, :http_client_opts, [ receive_timeout: 300_000, # 5分钟,用于长文本生成 connect_timeout: 10_000, pool_timeout: 10_000 ]
7.2 模型相关错误
问题: {:error, %{status: 404, body: %{"error" => "model 'xxx' not found"}}}
- 原因与解决 :指定的模型不存在。首先用
ollama list确认本地是否有该模型。如果没有,使用ollama pull <model-name>拉取。注意模型名称严格区分大小写和标签(tag),例如llama3.2:3b和llama3.2:1b是两个不同的模型。
问题: 生成速度异常缓慢,或内存占用飙升。
- 排查 :首先通过
ollama ps查看是哪个模型在运行及其资源占用。可能是模型太大,硬件撑不住。尝试换用更小的模型。此外,检查是否有多个进程在同时调用同一个模型,造成资源竞争。可以考虑用队列串行化请求。
7.3 流式响应中断
问题: 在 Phoenix Channel 中推送流式 token 时,连接偶尔会提前关闭,导致生成不完整。
- 根因 :网络不稳定,或前端页面关闭/刷新。
- 解决 :在 Task 中做好错误捕获,并将 Channel 的推送包装在
rescue中。更健壮的做法是,将长文本生成任务放入 Oban 作业,将最终结果存入数据库,并通过一个独立的轮询或通知机制告知前端任务完成,而非完全依赖长连接的流式推送。
7.4 嵌入式部署的存储问题
问题: 在 Docker 或 Kubernetes 中,Ollama 拉取的模型在容器重启后丢失。
- 解决 :必须将 Ollama 的数据目录(默认
~/.ollama)挂载到宿主机持久化存储卷。
在 Kubernetes 中,使用docker run -d -v /path/on/host:/root/.ollama -p 11434:11434 --name ollama ollama/ollamaPersistentVolumeClaim。
7.5 内容安全与过滤
问题: 如何防止模型生成不受欢迎的内容?
- 方案 :Ollama 本身有一些内置的模型安全机制,但不可完全依赖。必须在应用层(Elixir 后端)添加后处理过滤。
- 使用关键词黑名单进行过滤。
- 集成一个轻量级的文本分类模型,对输出进行二次检查。
- 对于公开应用,设置清晰的内容政策,并建立用户举报和人工审核流程。
- 在调用
ollama-ex的generate函数时,可以通过options中的system参数给模型一个强力的系统提示,约束其行为。例如:
options = %{ model: "llama3.2:3b", prompt: user_input, stream: false, system: "你是一个严谨、专业的助手。请确保你的回答安全、合法,且不包含任何有害或歧视性内容。", options: %{temperature: 0.5} }
将 ollama-ex 集成到你的 Elixir 项目中,就像是给一辆性能卓越的跑车(Elixir/ Phoenix)装上了一颗智能的引擎(本地大模型)。它开启了许多可能性,从简单的自动化脚本到复杂的、保护隐私的 AI 应用。关键在于理解整个技术栈的每个环节——从 Ollama 服务的运维,到 ollama-ex API 的调用方式,再到如何利用 Elixir 的并发模型进行优雅的集成。
更多推荐

所有评论(0)