那天早上接到同事反馈,说OpenCode对接本地Ollama服务时工具调用完全失效。控制台没有任何错误日志,但就是无法触发预期的工具调用行为。作为团队里负责AI集成这块的老手,我第一反应就是检查最基础的连接配置。
打开项目配置文件,确认了几个关键点:
排查心得:当集成出现问题却没有明确报错时,首先要排除基础配置问题。建议用curl直接测试API端点,比依赖SDK更直接。
在确认基础配置无误后,我开始检查请求内容。通过拦截实际发送的HTTP请求,发现了一个关键现象:当prompt内容较长时,服务端返回的响应中会丢失tool_calls字段。以下是当时记录的测试数据:
| Prompt长度 | 是否返回tool_calls | 响应状态码 |
|---|---|---|
| 1200 tokens | 是 | 200 |
| 3800 tokens | 否 | 200 |
| 4500 tokens | 否 | 200 |
这个现象让我意识到可能是上下文窗口的限制。查阅Ollama的文档发现,不同模型确实有各自的上下文长度限制。比如llama2默认是4096 tokens,而我们在配置OpenCode时没有显式设置这个参数。
大型语言模型的上下文窗口就像是一个固定大小的"记忆黑板"。当我们的prompt+response的总token数超过这个限制时,模型会采取两种处理方式:
Ollama采用的是第二种方式,这就是为什么我们没有收到错误提示,但工具调用功能却失效了——包含工具定义的那部分上下文被截断了。
技术细节:模型在处理请求时,实际可用的上下文窗口 = 总限制 - 预留空间(用于生成响应)。以llama2-7b为例:
最终的修复方案需要从三个层面进行配置:
在初始化OpenCode客户端时显式设置max_tokens参数:
python复制client = OpenCodeClient(
api_key="your_key",
base_url="http://localhost:11434",
max_tokens=3500 # 预留安全边界
)
启动Ollama服务时指定更大的上下文窗口(如果硬件支持):
bash复制ollama run llama2 --num_ctx 6144
我们重构了prompt模板,采用以下优化手段:
优化后的prompt模板示例:
text复制[工具]
名称:查询天气
描述:获取当前天气情况
参数:location(string)
[示例]
用户: 上海天气怎样?
AI: <invoke>查询天气<args>{"location":"上海"}</args></invoke>
为确保问题彻底解决,我们建立了三层验证机制:
python复制def test_tool_call_with_long_prompt():
long_prompt = "test" * 1000 + "<请调用查询天气工具>"
response = client.generate(long_prompt)
assert "tool_calls" in response
这次排查给我上了重要一课,总结几个关键经验:
所有AI服务集成必须明确三要素:
推荐的工具包配置检查清单:
性能权衡建议:
最后分享一个实用命令,可以实时查看Ollama模型的上下文使用情况:
bash复制ollama logs -f | grep "context"