使用 Ollama + Go 实现结构化输出:让本地大模型返回精确 JSON

## 背景

做 AI 应用时,我们经常需要 LLM 返回结构化的数据。OpenAI 的 GPT-4 有 `response_format` 参数可以直接指定 JSON Schema,但 Ollama 作为本地模型,应该怎么实现类似功能?这就是本文要解决的问题。

## 碰到的麻烦

用 Ollama 时,模型会自由发挥,输出格式不固定,解析起来很头疼:

一个典型的场景是:从用户自然语言描述中提取结构化的用户信息。如果用户说”我叫张三,邮箱是 zhangsan@example.com,今年 28 岁”,我们期望得到:

“`json
{
“name”: “张三”,
“email”: “zhangsan@example.com”,
“age”: 28
}
“`

但模型可能返回”姓名:张三\n邮箱:zhangsan@example.com\n年龄:28″或者其他变体。

## 详细步骤

### 1. 环境准备

首先确保已安装 Ollama 并下载了支持中文的模型:

“`bash
# 拉取支持中文的模型
ollama pull qwen2.5:7b

# 验证模型是否正常运行
ollama list
“`

然后初始化 Go 项目:

“`bash
mkdir ollama-structured-output
cd ollama-structured-output
go mod init ollama-structured-output
“`

### 2. 安装依赖

这几个 Go 包是必须的:

“`bash
go get github.com/ollama/ollama-sdk
go get github.com/go-playground/validator/v10
go get github.com/stretchr/testify/assert
“`

`ollama-sdk` 用来调用 Ollama API,`validator` 用来验证提取的数据是否符合我们定义的格式。

### 3. 定义数据结构

使用 Go 的结构体标签定义我们期望的输出格式:

“`go
package main

import (
“encoding/json”
“fmt”
“strings”
)

// UserInfo 代表用户信息结构
type UserInfo struct {
Name string `json:”name” validate:”required”`
Email string `json:”email” validate:”required,email”`
Age int `json:”age” validate:”required,gte=0,lte=150″`
}

// OrderInfo 代表订单信息结构
type OrderInfo struct {
OrderID string `json:”order_id” validate:”required”`
Product string `json:”product” validate:”required”`
Quantity int `json:”quantity” validate:”required,gte=1″`
TotalPrice float64 `json:”total_price” validate:”required,gte=0″`
Status string `json:”status” validate:”required,oneof=pending paid shipped delivered cancelled”`
}
“`

### 4. 创建 Prompt 工程函数

关键在于构建正确的 Prompt,引导模型输出 JSON。完整代码略。核心是:

1. 在 Prompt 中写入 JSON Schema
2. 要求模型只输出 JSON,不要其他文字
3. 用 `num_predict` 限制输出长度
4. 温度设为 0.1 保证输出稳定

### 5. 添加数据验证

用 go-playground/validator 验证提取的数据:

“`go
import “github.com/go-playground/validator/v10”

validator := validator.New()
if err := validator.Struct(&userInfo); err != nil {
// 验证失���
}
“`

### 6. 完整示例

完整代码见 GitHub:https://github.com/example/ollama-structured-output

核心调用:

“`go
var userInfo UserInfo
err := client.ExtractAndValidate(ctx, “qwen2.5:7b”,
“我叫张三,邮箱是 zhangsan@example.com,今年 28 岁”, &userInfo)
if err != nil {
log.Fatal(err)
}
fmt.Printf(“%+v\n”, userInfo)
“`

## 运行示例

“`bash
go run main.go
“`

预期输出:

“`
=== 测试用户信息提取 ===
提取的用户信息:
{
“name”: “张三”,
“email”: “zhangsan@example.com”,
“age”: 28
}
“`

## 总结

本文介绍了在 Go 中调用 Ollama 时如何让模型输出结构化的 JSON 数据。核心思路其实很简单:用正确的 Prompt 引导模型,再加上事后的数据验证。

关键点就几个:
1. 在 Prompt 里写清楚要输出的 JSON Schema
2. 收到回复后提取出 JSON 部分
3. 用 validator 验证数据是否符合预期格式

温度别设太高,0.1 到 0.3 之间比较稳。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇