Skip to content

Message Segment and Renderer

MarkChai edited this page Jul 16, 2026 · 2 revisions

消息段与渲染器

框架引入了 MessageSegment 机制,彻底取代传统的 CQ 码字符串拼接,让消息处理类型安全且跨平台。

1. 构造与发送消息

发送复杂混合消息只需构造结构体数组:

msg := []adapter_manager.MessageSegment{
    adapter_manager.At(event.UserID), // @发送者
    adapter_manager.Text(" 这是菜单:\n"), // 文本
    adapter_manager.Image(“https://example.com/menu.png”) , // 图片
}
event.Reply(msg)

从收到的消息中提取图片 URL:

for _, seg := range event.Segments {
    if seg.Type == adapter_manager.SegImage {
        url := seg.GetString(“url”)
        fmt.Println(“提取到图片:”, url)
    }
}

2. 多维度渲染文本

框架默认会将收到的 Segments 渲染为两种文本,存放在 MessageEvent 中:

  • event.PlainText: 仅提取纯文本,适合做指令匹配,避免图片 URL 干扰。
  • event.LLMText: 将非文本元素占位符化(如 [图片:http://xxx]),适合喂给大模型。

3. 自定义渲染器重载 (高级)

如果你觉得默认的 LLMText 格式不符合需求,框架允许你在运行时全局重载渲染器,且下游插件完全无感知

步骤 1:实现渲染器接口

type MySimpleLLMRenderer struct{}

func (r *MySimpleLLMRenderer) Render(segments []adapter_manager.MessageSegment) string {
    var sb strings.Builder
    for _, seg := range segments {
        switch seg.Type {
        case adapter_manager.SegText:
            sb.WriteString(seg.GetString(“text”))
        case adapter_manager.SegImage:
            sb.WriteString(“[一张图片]”) // 极简模式
        }
    }
    return sb.String()
}

步骤 2:在插件 Init 中重载

func (p *MyPlugin) Init(ctx *core.SystemContext) error {
    // 替换默认的 LLM 渲染器
    adapter_manager.RegisterLLMRenderer(&MySimpleLLMRenderer{})
    return nil
}

一旦重载,框架中所有后续消息的 event.LLMText 都会使用你的渲染逻辑。其他业务插件直接读取 event.LLMText 即可,不需要知道是哪个插件重载了它,实现绝对解耦。

Clone this wiki locally