记录和修改请求¶
StreamOptions 提供三个请求回调:OnRequest 读取即将发送的请求,RewriteRequest 修改序列化后的请求体,OnResponse 读取 HTTP 状态和响应头。
示例记录请求方法、地址、请求体大小、响应状态、请求 ID 和耗时,不记录提示词正文或凭证。每次 SDK 请求尝试都会调用这些回调,因此重试也会产生记录。
运行前准备¶
完整程序¶
package main
import (
"context"
"fmt"
"log"
"net/http"
"time"
"github.com/ktsoator/or/llm"
_ "github.com/ktsoator/or/llm/openai"
)
func main() {
model := llm.GetModel("deepseek", "deepseek-v4-flash")
started := time.Now()
options := llm.StreamOptions{
Headers: map[string]string{"X-Request-ID": "example-123"},
OnRequest: func(method, url string, body []byte) {
log.Printf("llm request method=%s url=%s bytes=%d",
method, url, len(body))
},
OnResponse: func(status int, headers http.Header) {
log.Printf("llm response status=%d request_id=%q elapsed=%s",
status, headers.Get("X-Request-ID"), time.Since(started))
},
}
response, err := llm.Complete(context.Background(), model,
llm.Prompt("Reply with OK."), options)
if err != nil {
log.Fatal(err)
}
fmt.Println(response.Text())
}
回调的执行时机¶
示例使用 OnRequest 观察序列化请求、用 RewriteRequest 返回替换后的请求体,并在 OnResponse 中读取状态码和响应头。三个回调都会对每次 SDK 尝试执行;精确签名、返回行为和调用约束统一见请求选项。
RewriteRequest 用于补充类型化选项尚未支持的模型服务字段。优先使用 StreamOptions、协议选项、Model.Compatibility、请求头或提供方覆盖;这些方式更容易校验和维护。
日志与性能边界¶
- 请求体可能包含提示词、图片、工具定义和工具参数。只记录大小或脱敏后的结构,不要记录原始字节。
- URL 和响应头可能包含租户信息或凭证。导出日志和指标前使用允许列表筛选字段。
- 回调在请求路径中同步执行。慢速日志或遥测写入应交给应用自己的缓冲队列。
- 一次逻辑请求可能因 SDK 重试触发多组回调。需要区分时,由应用记录尝试序号。
llm不提供日志器、指标导出器或链路追踪后端;回调需要接入应用现有的可观测系统。