在 Go 中使用 Ollama Web Search API
发布: (2025年12月5日 GMT+8 13:40)
5 min read
原文: Dev.to
Source: Dev.to

入门
Ollama 是否有官方的 Go Web 搜索库?
Ollama 提供了一个适用于任何 Go HTTP 客户端的 REST Web 搜索 API。虽然目前还没有官方的 Go SDK,但你可以使用标准库轻松实现 API 调用。
- 从你的 Ollama 账户 创建一个 API 密钥。
- 将 API 密钥设置为环境变量。
export OLLAMA_API_KEY="your_api_key"
在 Windows PowerShell 中:
$env:OLLAMA_API_KEY = "your_api_key"
想要获取 Ollama 命令和使用方式的完整参考,请参阅 Ollama cheatsheet。
项目设置
创建一个新的 Go 模块:
mkdir ollama-search
cd ollama-search
go mod init ollama-search
基础 Web 搜索
如何在 Go 中使用 Ollama 的 Web 搜索 API 进行身份验证?
在请求头中使用 Authorization 并将你的 API 密钥作为 Bearer token 传入。
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
)
// Request/Response types for web_search
type WebSearchRequest struct {
Query string `json:"query"`
MaxResults int `json:"max_results,omitempty"`
}
type WebSearchResult struct {
Title string `json:"title"`
URL string `json:"url"`
Content string `json:"content"`
}
type WebSearchResponse struct {
Results []WebSearchResult `json:"results"`
}
func webSearch(query string, maxResults int) (*WebSearchResponse, error) {
apiKey := os.Getenv("OLLAMA_API_KEY")
if apiKey == "" {
return nil, fmt.Errorf("OLLAMA_API_KEY environment variable not set")
}
reqBody := WebSearchRequest{
Query: query,
MaxResults: maxResults,
}
jsonData, err := json.Marshal(reqBody)
if err != nil {
return nil, fmt.Errorf("failed to marshal request: %w", err)
}
req, err := http.NewRequest("POST", "https://ollama.com/api/web_search", bytes.NewBuffer(jsonData))
if err != nil {
return nil, fmt.Errorf("failed to create request: %w", err)
}
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("request failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(body))
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("failed to read response: %w", err)
}
var searchResp WebSearchResponse
if err := json.Unmarshal(body, &searchResp); err != nil {
return nil, fmt.Errorf("failed to unmarshal response: %w", err)
}
return &searchResp, nil
}
func truncate(s string, maxLen int) string {
if len(s) = 5 {
fmt.Printf(" ... and %d more\n", len(result.Links)-5)
break
}
fmt.Printf(" - %s\n", link)
}
}
可复用的客户端包
创建一个可复用的 Ollama 客户端包,以获得更简洁的代码。
// ollama/client.go
package ollama
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
)
type Client struct {
apiKey string
httpClient *http.Client
baseURL string
}
func NewClient() (*Client, error) {
apiKey := os.Getenv("OLLAMA_API_KEY")
if apiKey == "" {
return nil, fmt.Errorf("OLLAMA_API_KEY environment variable not set")
}
return &Client{
apiKey: apiKey,
httpClient: &http.Client{
Timeout: 30 * time.Second,
},
baseURL: "https://ollama.com/api",
}, nil
}
// Generic POST helper
func (c *Client) post(endpoint string, payload interface{}, out interface{}) error {
jsonData, err := json.Marshal(payload)
if err != nil {
return fmt.Errorf("marshal error: %w", err)
}
req, err := http.NewRequest("POST", c.baseURL+endpoint, bytes.NewBuffer(jsonData))
if err != nil {
return fmt.Errorf("request creation error: %w", err)
}
req.Header.Set("Authorization", "Bearer "+c.apiKey)
req.Header.Set("Content-Type", "application/json")
resp, err := c.httpClient.Do(req)
if err != nil {
return fmt.Errorf("request error: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(body))
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("read error: %w", err)
}
if err := json.Unmarshal(body, out); err != nil {
return fmt.Errorf("unmarshal error: %w", err)
}
return nil
}
// WebSearch calls the /web_search endpoint
func (c *Client) WebSearch(query string, maxResults int) (*WebSearchResponse, error) {
req := WebSearchRequest{
Query: query,
MaxResults: maxResults,
}
var resp WebSearchResponse
if err := c.post("/web_search", req, &resp); err != nil {
return nil, err
}
return &resp, nil
}
// WebFetch calls the /web_fetch endpoint
func (c *Client) WebFetch(url string) (*WebFetchResponse, error) {
req := WebFetchRequest{URL: url}
var resp WebFetchResponse
if err := c.post("/web_fetch", req, &resp); err != nil {
return nil, err
}
return &resp, nil
}
现在可以在你的应用中使用该客户端:
package main
import (
"fmt"
"log"
"yourmodule/ollama"
)
func main() {
client, err := ollama.NewClient()
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
// 示例:网页搜索
searchRes, err := client.WebSearch("Ollama Go SDK", 3)
if err != nil {
log.Fatalf("Search error: %v", err)
}
for _, r := range searchRes.Results {
fmt.Printf("- %s (%s)\n", r.Title, r.URL)
}
// 示例:获取页面内容
fetchRes, err := client.WebFetch("https://ollama.com")
if err != nil {
log.Fatalf("Fetch error: %v", err)
}
fmt.Printf("\nFetched title: %s\n", fetchRes.Title)
}