在 Blades 框架中,中间件是一种强大的机制,用于实现横切关注点(如日志、监控、认证、限流等)。它的设计允许在 Agent 的执行流程中注入额外行为,而无需修改核心逻辑。中间件以”洋葱模型”的函数链形式工作,提供了高度灵活的流程控制和功能增强。在本文档中将指导完成一个简单的日志中间件实现示例。
中间件定义如下:
type Handler interface { Handle(context.Context, *Invocation) Generator[*Message, error]}type Middleware func(Handler) HandlerMiddleware 是一个函数,它接受一个 Handler 作为参数,并返回一个 Handler。创建Middleware示例如下所示:
func Logging() blades.Middleware { return func(next blades.Handler) blades.Handler { // `blades.Handler` is a interface,we need use `blades.HandleFunc` to implement it. return blades.HandleFunc(func(ctx context.Context, req *blades.Invocation) blades.Generator[*blades.Message, error] { log.Println("----🚀--- Incoming request ----🚀---") log.Println("Request:", req.Message) return next.Handle(ctx, req) }) }}type Logging struct { next blades.Handler}
// NewLogging creates a new Logging middleware.func NewLogging(next blades.Handler) blades.Handler { return &Logging{next}}
func (m *Logging) onError(start time.Time, agent blades.AgentContext, invocation *blades.Invocation, err error) { log.Printf("logging: model(%s) prompt(%s) failed after %s: %v", agent.Model(), invocation.Message.String(), time.Since(start), err)}
func (m *Logging) onSuccess(start time.Time, agent blades.AgentContext, invocation *blades.Invocation, output *blades.Message) { log.Printf("logging: model(%s) prompt(%s) succeeded after %s: %s", agent.Model(), invocation.Message.String(), time.Since(start), output.String())}
func (m *Logging) Handle(ctx context.Context, invocation *blades.Invocation) blades.Generator[*blades.Message, error] { return func(yield func(*blades.Message, error) bool) { start := time.Now() agent, ok := blades.FromAgentContext(ctx) if !ok { yield(nil, blades.ErrNoAgentContext) return } streaming := m.next.Handle(ctx, invocation) for msg, err := range streaming { if err != nil { m.onError(start, agent, invocation, err) } else { m.onSuccess(start, agent, invocation, msg) } if !yield(msg, err) { break } } }}// Create a blades agent with logging middlewareagent := blades.NewAgent( "Example Agent", blades.WithModel("gpt-5"), blades.WithInstructions("You are a helpful assistant."), blades.WithProvider(openai.NewChatProvider()), blades.WithMiddleware(Logging()), // Use the logging middleware)// Create a promptinput := blades.UserMessage("What is the capital of France?")// Run the agentoutput, err := agent.Run(context.Background(), input)if err != nil { log.Fatal(err)}
log.Println(output.Text())// Create multiple middlewaresagent := blades.NewAgent( "Chained Middleware Agent", blades.WithModel("gpt-5"), blades.WithProvider(openai.NewChatProvider()), // Chain multiple middlewares blades.WithMiddleware( Logging(), Tracing(), Metrics(), ),)这种设计使得中间件可以方便地添加各种功能,同时保持代码的清晰和可维护性。