llm

package
v1.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 10, 2026 License: Apache-2.0 Imports: 30 Imported by: 0

README

llm — Eino LLM 高级封装库

基于 Eino 框架的生产级 LLM 工具调用与 Agent 封装库。本 README 旨在为 AI 编程助手提供完整的上下文索引。

🌟 核心特性

  • 多协议统一路由:一键切换 OpenAI / Claude / DeepSeek / Gemini / Ollama / Moonshot(Kimi) 等模型协议。
  • React Agent 增强:内置工具调用循环、自动重试、死循环检测。
  • StructTool:基于 Go 结构体标签(tag)自动生成 JSON Schema,支持嵌套结构、枚举值。
  • 可观测性:开箱即用的 Langfuse 和 Slog 集成。
  • 运行时动态控制:支持请求级别的模型替换、工具替换、参数调整。
  • 流式完整支持:从推理到工具调用再到最终回答的全链路流式。

🚀 快速开始

1. 初始化模型配置
cfg := llm.ModelConfig{
    Protocol: llm.OPENAI, // 或 llm.CLAUDE, llm.OLLAMA ...
    BaseURL:  "https://api.openai.com/v1", // 可选
    APIKey:   "sk-xxx",
    Model:    "gpt-4o",
}
2. 定义工具 (推荐 StructTool)

使用 struct 定义参数,自动生成 Schema:

type WeatherArgs struct {
    City string `json:"city" desc:"查询城市" required:"true"`
    Unit string `json:"unit" desc:"温度单位" enum:"celsius,fahrenheit"`
}

// 创建工具
weatherTool := llm.NewStructTool("get_weather", "查询天气", func(ctx context.Context, args *WeatherArgs) (string, error) {
    return fmt.Sprintf("%s 的天气是 晴, 25%s", args.City, args.Unit), nil
})
3. 创建 Agent 并运行
agent, _ := llm.NewAgent(ctx, llm.AgentConfig{
    ModelConfig:    cfg,
    InvokableTools: []llm.InvokableTool{weatherTool}, // 自动适配
    SystemPrompt:   "你是一个有用的助手。",
})

// 运行 (Generate)
msg, _ := agent.Generate(ctx, []*schema.Message{
    schema.UserMessage("海淀区天气如何?"),
})
fmt.Println(msg.Content)

🛠 高级功能

1. 可观测性 (Observability)

支持 Langfuse 链路追踪和标准日志记录。

// 初始化 Langfuse
lfHandler, flush, _ := llm.NewLangfuseHandler(&llm.LangfuseConfig{...})
defer flush()

// 初始化日志 (slog)
logHandler := llm.NewLogHandler(slog.Default())

// 注入 Agent
agent, _ := llm.NewAgent(ctx, llm.AgentConfig{
    // ...
    Callbacks: []callbacks.Handler{lfHandler, logHandler},
})
2. 强制工具调用与重试 (ToolChoice & Retry)
forced := schema.ToolChoiceForced
agent, _ := llm.NewAgent(ctx, llm.AgentConfig{
    // ...
    ToolChoice: &forced, // 强制模型必须调用工具
    MaxRetries: 3,       // 如果工具报错,自动重试 3 次
})
3. 工具结果直接返回 (Direct Return)

某些场景下(如搜索),工具执行后不需要模型再通过 LLM 总结,直接返回工具结果可节省 Token:

agent, _ := llm.NewAgent(ctx, llm.AgentConfig{
    // ...
    ToolReturnDirectly: map[string]struct{}{
        "search_tool": {}, // 执行完 search_tool 后立即结束对话并返回结果
    },
})
4. 运行时动态控制 (Runtime Options)

GenerateStream 时动态修改行为,不影响 Agent 实例。

import "github.com/cloudwego/eino/flow/agent"

// 场景 A: 临时更换模型 (例如降级到 3.5)
agent.Generate(ctx, input, agent.WithChatModel(gpt35Model))

// 场景 B: 调整温度
agent.Generate(ctx, input, agent.WithChatModelOptions(model.WithTemperature(0.1)))

// 场景 C: 获取中间状态 (Result Event Stream)
logOpt, future := agent.WithMessageFuture()
go func() {
    defer future.Close()
    stream, _ := future.GetMessageStreams()
    for { msg, _ := stream.Recv(); fmt.Println("中间状态:", msg) }
}()
agent.Generate(ctx, input, logOpt)

📦 架构说明

llm 包是对 CloudWeGo Eino 框架的 Opinionated 封装:

  • Model: 实现了 eino/components/model 接口。
  • Agent: 封装了 eino/flow/agent/react
  • Tool: 提供了 StructTooleino/components/tool 的适配器。

如需更复杂的编排(如多 Agent 协作),可使用 agent.ExportGraph() 导出底层 Graph 节点,嵌入到 Eino 的 Graph 中。

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ToolChoiceForced = schema.ToolChoiceForced

ToolChoiceForced 是一个便捷变量,避免每次都声明指针。

Functions

func CombineTools added in v1.1.0

func CombineTools(args ...interface{}) []tool.BaseTool

CombineTools 合并单个工具或工具列表。 支持 tool.BaseTool 和 []tool.BaseTool 类型。 对于不支持的类型,会打印警告并忽略。

func NewLangfuseHandler added in v1.1.0

func NewLangfuseHandler(cfg *LangfuseConfig) (callbacks.Handler, func(), error)

NewLangfuseHandler 创建一个 Langfuse 回调处理器。 返回的 flush 函数应该在程序退出前调用,确保所有 Trace 上报完成。

func NewLogHandler added in v1.1.0

func NewLogHandler(logger *slog.Logger) callbacks.Handler

NewLogHandler 创建一个基于 slog 的日志回调处理器。 它会记录组件的输入、输出、耗时和 Token 消耗(如果有)。

func NewMCPTools added in v1.1.0

func NewMCPTools(ctx context.Context, cfg MCPConfig) ([]tool.BaseTool, func() error, error)

NewMCPTools 创建 MCP Client 并加载工具。 返回工具列表和清理函数。清理函数用于关闭 Client。 注意:Client 的底层运行依赖于内部创建的 Context,该 Context 会在调用 cleanup 时取消。 传入的 ctx 仅用于初始化过程(握手超时控制)。

func NewModel added in v1.1.0

NewModel 根据 Protocol 创建对应的 eino-ext ToolCallingChatModel。

Types

type Agent added in v1.1.0

type Agent struct {
	// contains filtered or unexported fields
}

Agent 封装 Eino ReactAgent,提供简化的高层 API。

func NewAgent added in v1.1.0

func NewAgent(ctx context.Context, cfg AgentConfig) (*Agent, error)

NewAgent 创建一个 Agent。

使用示例:

// 场景 1: 纯对话
agent, _ := llm.NewAgent(ctx, llm.AgentConfig{ModelConfig: cfg})
msg, _ := agent.Generate(ctx, messages)

// 场景 2: 强制调工具 → 结果回模型 → 模型决策
forced := schema.ToolChoiceForced
agent, _ := llm.NewAgent(ctx, llm.AgentConfig{
    ModelConfig:    cfg,
    InvokableTools: []llm.InvokableTool{myTool},
    ToolChoice:     &forced,
})

// 场景 3: 强制调工具 → 直接拿结果
agent, _ := llm.NewAgent(ctx, llm.AgentConfig{
    ModelConfig:        cfg,
    InvokableTools:     []llm.InvokableTool{myTool},
    ToolChoice:         &forced,
    ToolReturnDirectly: map[string]struct{}{"my_tool": {}},
})

func (*Agent) ExportGraph added in v1.1.0

func (a *Agent) ExportGraph() (compose.AnyGraph, []compose.GraphAddNodeOpt)

ExportGraph 导出底层 Graph,用于嵌入更大的编排图。

func (*Agent) Generate added in v1.1.0

func (a *Agent) Generate(ctx context.Context, messages []*schema.Message, opts ...agent.AgentOption) (*schema.Message, error)

Generate 非流式调用 Agent。 模型会自动处理工具调用循环,直到返回最终答案。

func (*Agent) Stream added in v1.1.0

func (a *Agent) Stream(ctx context.Context, messages []*schema.Message, opts ...agent.AgentOption) (*schema.StreamReader[*schema.Message], error)

Stream 流式调用 Agent。 完整支持流式 tool call:模型推理 → 工具调用 → 再推理,全程流式。

type AgentConfig added in v1.1.0

type AgentConfig struct {
	// ModelConfig 用于通过 NewModel 创建模型实例。
	// 与 Model 二选一,若同时提供则 Model 优先。
	ModelConfig ModelConfig

	// Model 直接传入已创建的模型实例。
	Model model.ToolCallingChatModel

	// Tools 使用 Eino 标准工具接口。
	Tools []tool.BaseTool

	// InvokableTools 使用简化工具接口(内部自动适配为 Eino 标准接口)。
	// 与 Tools 可同时使用,两者合并。
	InvokableTools []InvokableTool

	// SystemPrompt 通过 MessageModifier 在每轮调用前注入。
	// 与 MessageModifier 二选一,若同时提供则 MessageModifier 优先。
	SystemPrompt string

	// MessageModifier 在每轮调用模型前修改消息列表。
	MessageModifier MessageModifier

	// MessageRewriter 持久化修改消息历史(跨轮生效)。
	// 常用于上下文压缩。
	MessageRewriter MessageModifier

	// ToolChoice 控制模型的工具调用行为。
	//   - nil(默认):模型自行决定是否调用工具
	//   - schema.ToolChoiceForced:强制模型调用工具
	//     首次调用 + 失败重试期间为 Forced,工具成功后自动切换为 Allowed。
	//   - schema.ToolChoiceForbidden:禁止调用工具
	//   - schema.ToolChoiceAllowed:允许但不强制
	ToolChoice *schema.ToolChoice

	// MaxRetries 工具执行失败时的最大重试次数。
	// 仅在 ToolChoice 为 Forced 时生效。
	// 默认 3。
	MaxRetries int

	// MaxStep Agent 最大运行步长。
	// 每次节点转移为一步;一次循环 = ChatModel + Tools = 2 步。
	// 默认 12(最多 5 次工具调用)。
	MaxStep int

	// ToolReturnDirectly 指定某些工具执行后直接返回结果,不再回模型。
	ToolReturnDirectly map[string]struct{}

	// StreamToolCallChecker 流式场景下判断是否包含 tool call。
	// StreamToolCallChecker 流式场景下判断是否包含 tool call。
	// 默认检查第一个 chunk。对于先输出文本再输出 tool call 的模型(如 Claude)需自定义。
	StreamToolCallChecker func(ctx context.Context, sr *schema.StreamReader[*schema.Message]) (bool, error)

	// Callbacks 是可选的回调处理器列表,用于监控和日志。
	Callbacks []callbacks.Handler
}

AgentConfig 是创建 Agent 的配置。

type InvokableTool added in v1.1.0

type InvokableTool interface {
	Info() *schema.ToolInfo
	Invoke(ctx context.Context, args string) (string, error)
}

InvokableTool 代表一个可执行工具(定义 + 执行能力)。 这是一个简化接口,可通过 ToolAdapter 适配到 Eino 标准 tool.InvokableTool。

type LangfuseConfig added in v1.1.0

type LangfuseConfig struct {
	Host      string
	PublicKey string
	SecretKey string
}

LangfuseConfig 是 Langfuse 的配置。

type MCPConfig added in v1.1.0

type MCPConfig struct {
	Name    string // 此客户端的标识符
	Version string // 客户端版本,默认为 1.0.0

	Protocol MCPProtocol

	// Stdio 特定配置
	Command string
	Args    []string
	Env     []string

	// SSE 特定配置
	BaseURL string

	// 可选:过滤要包含的工具
	// 若为空,则加载所有工具
	ToolWhitelist []string
}

MCPConfig 定义单个 MCP 服务器连接的配置。

type MCPProtocol added in v1.1.0

type MCPProtocol string

MCPProtocol 定义 MCP 的传输协议。

const (
	MCPProtocolStdio MCPProtocol = "stdio"
	MCPProtocolSSE   MCPProtocol = "sse"
)

type MessageModifier added in v1.1.0

type MessageModifier = react.MessageModifier

MessageModifier 在每轮调用模型前修改消息列表。 常用于注入 system prompt 或上下文压缩。

type ModelConfig added in v1.1.0

type ModelConfig struct {
	Protocol ModelProtocol
	BaseURL  string
	APIKey   string
	Model    string
	Timeout  time.Duration

	MaxTokens   *int
	Temperature *float32
	TopP        *float32
	Stop        []string
}

ModelConfig 是创建模型的统一配置。

type ModelProtocol added in v1.1.0

type ModelProtocol string

ModelProtocol 定义模型厂商协议。

const (
	OPENAI        ModelProtocol = "OPENAI"
	OPENAI_COMPAT ModelProtocol = "OPENAI_COMPAT"
	CLAUDE        ModelProtocol = "CLAUDE"
	CLAUDE_COMPAT ModelProtocol = "CLAUDE_COMPAT"
	ARK           ModelProtocol = "ARK"
	ARKBOT        ModelProtocol = "ARKBOT"
	DEEPSEEK      ModelProtocol = "DEEPSEEK"
	GEMINI        ModelProtocol = "GEMINI"
	OLLAMA        ModelProtocol = "OLLAMA"
	QIANFAN       ModelProtocol = "QIANFAN"
	QWEN          ModelProtocol = "QWEN"
	KIMI          ModelProtocol = "KIMI"
)

type StructTool added in v1.1.0

type StructTool[T any] struct {
	// contains filtered or unexported fields
}

StructTool 是一个泛型工具,用于让模型生成指定结构体。

它利用 Tool Call 的 JSON Schema 约束模型输出格式:

  • 模型按 Schema 生成 JSON 参数
  • Invoke 内部做 json.Unmarshal 校验
  • 成功 → 返回合法 JSON
  • 失败 → 返回 error,触发自动重试

配合 ToolChoiceForced + ToolReturnDirectly 使用,实现「结构化输出提取」:

type JD struct {
    Title        string   `json:"title"`
    Requirements []string `json:"requirements"`
}

tool := llm.NewStructTool[JD]("generate_jd", "生成职位描述")

forced := schema.ToolChoiceForced
agent, _ := llm.NewAgent(ctx, llm.AgentConfig{
    ModelConfig:        cfg,
    InvokableTools:     []llm.InvokableTool{tool},
    ToolChoice:         &forced,
    ToolReturnDirectly: map[string]struct{}{"generate_jd": {}},
    SystemPrompt:       "根据用户需求生成职位描述。",
})

msg, _ := agent.Generate(ctx, messages)
var jd JD
json.Unmarshal([]byte(msg.Content), &jd)

func NewStructTool added in v1.1.0

func NewStructTool[T any](name, desc string) *StructTool[T]

NewStructTool 创建一个结构化输出提取工具。 自动从 T 的 json tag 生成 ToolInfo 的参数定义。

func (*StructTool[T]) Info added in v1.1.0

func (s *StructTool[T]) Info() *schema.ToolInfo

func (*StructTool[T]) Invoke added in v1.1.0

func (s *StructTool[T]) Invoke(_ context.Context, args string) (string, error)

type ToolAdapter added in v1.1.0

type ToolAdapter struct {
	// contains filtered or unexported fields
}

ToolAdapter 将 llm.InvokableTool 适配为 Eino tool.InvokableTool。 用于桥接简化接口与 Eino 标准接口。

func NewToolAdapter added in v1.1.0

func NewToolAdapter(t InvokableTool) *ToolAdapter

NewToolAdapter 创建一个工具适配器。

func (*ToolAdapter) Info added in v1.1.0

func (*ToolAdapter) InvokableRun added in v1.1.0

func (a *ToolAdapter) InvokableRun(ctx context.Context, argumentsInJSON string, _ ...tool.Option) (string, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL