Day 2:Eino Chain链式处理——让文档自己说话
今天做什么
用 Eino Chain 把文档处理的三个步骤串成流水线:提取 → 分析 → 总结。
代码
go
package main
import (
"context"
"fmt"
"strings"
"github.com/cloudwego/eino/components/model"
"github.com/cloudwego/eino/compose"
"github.com/cloudwego/eino/schema"
)
// ===== 分析 Chain =====
func buildAnalysisChain(ctx context.Context) (*compose.Runnable[[]*schema.Message, *schema.Message], error) {
// 创建模型(先用 Mock)
llm := &MockChatModel{}
// Chain 步骤1:提取关键信息
extractPrompt := `请从以下文档中提取3-5个核心要点,每个要点一句话:
文档内容:
{document}`
// Chain 步骤2:分析每个要点
analyzePrompt := `基于以下要点,分析该文档反映的趋势和问题:
要点:
{extracted}`
// Chain 步骤3:生成总结
summaryPrompt := `你是一个专业的文档分析师。请基于分析结果,用2-3句话给出一份总结:
分析:
{analysis}`
// 用 Eino Chain 串起来
chain := compose.NewChain[map[string]any, *schema.Message]().
AppendLambda(extractKeyPoints(llm, extractPrompt)).
AppendLambda(analyzePoints(llm, analyzePrompt)).
AppendLambda(generateSummary(llm, summaryPrompt)).
AppendChatModel(llm) // 最后让 LLM 润色
return chain.Compile(ctx)
}
func extractKeyPoints(model ChatModel, promptTemplate string) compose.Lambda {
return func(ctx context.Context, input map[string]any) (map[string]any, error) {
doc := input["document"].(string)
prompt := strings.Replace(promptTemplate, "{document}", doc, 1)
result, err := model.Generate(ctx, []*schema.Message{
schema.UserMessage(prompt),
})
if err != nil {
return nil, err
}
return map[string]any{"extracted": result.Content}, nil
}
}
// 类似实现 analyzePoints 和 generateSummary ...
func main() {
ctx := context.Background()
chain, err := buildAnalysisChain(ctx)
if err != nil {
panic(err)
}
doc := `2025年Q1财报:营收5.2亿元,同比增长18%。
研发投入1.1亿元,占营收21%。AI业务营收增长最快,同比+45%。`
result, err := chain.Invoke(ctx, map[string]any{
"document": doc,
})
fmt.Println("📊 分析结果:\n", result.Content)
}运行
bash
go run main.go你学到了什么
- Eino Chain 把多个步骤串成流水线——每一步的输出自动成为下一步的输入。
- Lambda 节点:
compose.Lambda让你在 Chain 里插入自定义逻辑。 - Mock 先行:先用 Mock LLM 跑通流程,再切换真实模型。
明天的预告
一台机器处理一份文档没问题——但如果是 50 份文档呢?明天发挥 Go 的并发优势:goroutine 同时分析 50 份文档。
Day 2 完成。Chain 跑通了。

