在机器人应用场景中,人机对话正变得越来越重要------从服务机器人接待引导,到工业设备语音控制,再到家庭陪护机器人闲聊陪伴。传统的关键词匹配方案早已无法满足需求,而调用云端大模型又存在延迟、断网风险和隐私泄露问题。
有没有一种方案,既拥有大模型的自然语言理解能力,又能完全在本地运行,保护用户隐私?
答案就是:Ollama + ROS2。
本文介绍的 ollama_ros_chat 功能包,正是这样一套解决方案。它将本地部署的 DeepSeek-R1 等大语言模型无缝集成到 ROS2 系统中,通过服务通信和话题通信两种方式,为机器人提供安全、低延迟、可离线工作的智能对话能力。
一、功能定位与设计思路
1.1 为什么选择本地大模型?
目前主流的机器人语音交互方案有两种:
| 方案 | 优点 | 缺点 |
|---|---|---|
| 云端 API(如 ChatGPT、通义千问) | 模型强大,无需本地算力 | 依赖网络,延迟高,数据上传有隐私风险 |
| 本地模型(Ollama + DeepSeek) | 数据不出门,离线可用,低延迟 | 需要本地 GPU/CPU 算力 |
ollama_ros_chat 选择了后者,核心设计原则是:
-
隐私优先
:所有对话数据在机器人本地处理,不上传云端
-
ROS2 原生
:使用标准的 ROS2 话题和服务接口,易于集成
-
灵活切换
:既支持本地 Ollama 模型,也支持在线 API(如通义千问)
-
轻量部署
:通过 launch 文件一键启动,无需修改代码即可切换模型
1.2 整体架构

-
客户端节点
:接收用户输入(文本或语音转文字),发送请求
-
服务端节点
:调用 Ollama API,与大模型交互,返回响应
-
通信方式
:支持 ROS2 Service(同步请求-响应)和 Topic(异步发布-订阅)
二、快速上手:两种通信方式的使用
2.1 环境准备
在使用功能包之前,需要确保机器人端已安装:
安装 Ollama
curl -fsSL https://ollama.com/install.sh | sh
拉取 DeepSeek-R1 模型(约 4.7GB)
ollama pull deepseek-r1:7b
安装 Python 依赖
pip3 install requests
2.2 服务通信模式(推荐新手)
服务通信采用同步请求-响应模式,适合一问一答的简单场景。
启动服务端(一个终端):
ros2 run ollama_ros_chat chat_service
终端会输出当前可用的模型列表和已选择的模型。
启动客户端(另一个终端):
ros2 run ollama_ros_chat chat_client
然后在客户端终端输入问题,等待模型推理完成后即可看到回复。
2.3 话题通信模式
话题通信采用异步发布-订阅模式,适合需要持续对话或流式输出的场景。
启动话题服务端:
ros2 run ollama_ros_chat topic_server
启动话题客户端:
ros2 run ollama_ros_chat topic_client
两者的区别在于:服务通信每次请求会阻塞直到收到回复;话题通信可以同时处理多个请求,且支持更灵活的消息流。
2.4 一键启动:使用 launch 文件
为了避免每次手动启动两个节点,功能包提供了 launch 文件:
ros2 launch ollama_ros_chat ollama_ros_chat.launch.py
该 launch 文件会同时启动服务端和客户端,并支持参数配置(见下文)。
三、进阶配置:切换模型与参数调优
3.1 本地模型 vs 在线 API
功能包支持两种后端,通过修改 base_url 和 api_key 即可切换。
本地 Ollama 配置(默认):
base_url: "[http://localhost:11434/v1\](http://localhost:11434/v1)"
api_key: "ollama" # 本地任意字符串即可
use_model: "deepseek-r1" # 或留空自动选择第一个
阿里云通义千问在线配置:
base_url: "[https://dashscope.aliyuncs.com/compatible-mode/v1\](https://dashscope.aliyuncs.com/compatible-mode/v1)"
api_key: "sk-你的真实API密钥"
use_model: "qwen-plus" # 或 deepseek-r1 等
⚠️ 注意:通过 launch 文件启动时,修改参数需要在
.launch.py中设置;如果直接运行 node,则需要在 Python 代码中修改默认值。
3.2 关键参数调优
功能包暴露了以下可调参数,直接影响对话效果:
| 参数 | 类型 | 说明 | 推荐值 |
|---|---|---|---|
temperature |
float | 控制回复的随机性,0 最确定,1 最多样 | 0.7(创意对话)/ 0.2(精确问答) |
stream |
bool | 是否流式输出(逐字显示) | True(用户体验好) |
history_length |
int | 保留的对话历史消息数量 | 5~10(节省内存) |
timeout |
int | 服务端响应超时时间(秒) | 30(复杂问题需要更久) |
在服务端代码中修改超时时间的位置如下:
ollama_service.py 中
client = OpenAI(base_url=self.base_url, api_key=self.api_key, timeout=60) # 改为60秒
3.3 服务通信超时处理
由于大模型推理耗时较长(尤其是 7B 模型在 CPU 上可能超过 30 秒),服务通信容易触发超时。功能包已内置超时捕获机制,当读取超时时会显示 Read timeout。用户可以适当调大 timeout 参数,或在客户端实现重试逻辑。
四、技术细节与二次开发
4.1 节点与通信接口
功能包在 setup.py 中定义了四个可执行节点:
'console_scripts': [
'topic_server = ollama_ros_chat.ollama_topic_server:main',
'topic_client = ollama_ros_chat.ollama_topic_client:main',
'chat_service = ollama_ros_chat.ollama_service:main',
'chat_client = ollama_ros_chat.ollama_client:main',
] 通信接口 (ROS2 消息类型为自定义的 String):
| 通信类型 | 客户端请求话题/服务 | 服务端响应话题/服务 |
|---|---|---|
| 话题通信 | /chat_message |
/chat_response |
| 服务通信 | /chat_service |
/chat_service (同一个服务) |
4.2 将对话能力集成到自己的机器人
假设你已经有了一个语音识别节点(输出文本)和一个语音合成节点(输入文本),集成步骤如下:
-
启动
ollama_ros_chat的服务端(后台运行)
-
在你的语音识别节点中,添加一个服务客户端
伪代码示例
from std_srvs.srv import Trigger
from rclpy.callback_groups import MutuallyExclusiveCallbackGroup
client = self.create_client(Trigger, '/chat_service')
while not client.wait_for_service(timeout_sec=1.0):
self.get_logger().info('等待对话服务...')
req = Trigger.Request()
req.data = recognized_text # 语音识别的结果
future = client.call_async(req)
在回调中获取响应并发送给语音合成
- 处理响应:服务端返回的响应字符串可以直接送入 TTS 节点播报。
4.3 性能优化建议
-
硬件加速
:如果机器人配备 NVIDIA GPU,安装
ollama的 CUDA 版本,推理速度可提升 5~10 倍。 -
模型量化
:DeepSeek-R1 提供 4-bit 量化版本(约 2.5GB),精度损失不大但速度更快。
-
预热机制
:首次请求会触发模型加载(耗时 5~10 秒),建议在机器人启动时发送一个空请求进行预热。
五、ROS1 版本说明
功能包同时提供了 ROS1 版本(ollama_chat_ros),使用方式类似,仅启动命令不同:
ROS1 启动服务端
rosrun ollama_chat_ros chat_service.py
ROS1 启动客户端
rosrun ollama_chat_ros chat_client.py
使用 launch 文件
roslaunch ollama_chat_ros ollama_chat_ros.launch
注意 ROS1 需要先运行 roscore,且话题/服务名称与 ROS2 版本保持一致,方便后续迁移。
资源链接:
功能包仓库:
ollama_ros_chat(请联系作者获取)Ollama 官网:https://ollama.com
DeepSeek-R1 模型:https://deepseek.com