Skip to content

Day 1:文档解析Pipeline——读得懂,才分析得了

今天做什么

项目二的主题是高性能文档分析。用户上传一份文档,Agent 自动提取关键信息、分析要点、生成摘要。今天先把文档"读进去"——搭建解析 Pipeline。

代码

bash
mkdir doc_analyzer && cd doc_analyzer
go mod init doc_analyzer
go
package main

import (
    "fmt"
    "os"
    "strings"
)

// ===== 文档解析 Pipeline =====
type Document struct {
    Name     string
    Format   string
    Content  string
    Sections []Section
}

type Section struct {
    Title   string
    Content string
}

// 步���1:识别文档格式
func detectFormat(filename string) string {
    switch {
    case strings.HasSuffix(filename, ".md"):
        return "markdown"
    case strings.HasSuffix(filename, ".txt"):
        return "text"
    case strings.HasSuffix(filename, ".pdf"):
        return "pdf"
    default:
        return "unknown"
    }
}

// 步骤2:提取文本
func extractText(filename, format string) (string, error) {
    data, err := os.ReadFile(filename)
    if err != nil {
        return "", fmt.Errorf("读取文件失败: %w", err)
    }
    return string(data), nil
}

// 步骤3:按段落切割(以空行或 # 标题为界)
func splitSections(content string) []Section {
    var sections []Section
    lines := strings.Split(content, "\n")
    var current Section

    for _, line := range lines {
        // # 开头的是章节标题
        if strings.HasPrefix(strings.TrimSpace(line), "#") {
            if current.Content != "" {
                sections = append(sections, current)
            }
            current = Section{
                Title: strings.TrimLeft(line, "# "),
            }
        } else if strings.TrimSpace(line) == "" {
            if current.Content != "" {
                sections = append(sections, current)
                current = Section{}
            }
        } else {
            if current.Content != "" {
                current.Content += "\n"
            }
            current.Content += line
        }
    }
    if current.Content != "" {
        sections = append(sections, current)
    }
    return sections
}

// 完整 Pipeline
func parseDocument(filename string) (*Document, error) {
    format := detectFormat(filename)
    content, err := extractText(filename, format)
    if err != nil {
        return nil, err
    }
    sections := splitSections(content)

    return &Document{
        Name:     filename,
        Format:   format,
        Content:  content,
        Sections: sections,
    }, nil
}

func main() {
    doc, err := parseDocument("sample.md")
    if err != nil {
        fmt.Println("❌", err)
        return
    }
    fmt.Printf("文档:%s (%s)\n", doc.Name, doc.Format)
    fmt.Printf("共 %d 个章节:\n", len(doc.Sections))
    for _, s := range doc.Sections {
        fmt.Printf("  📄 %s (%d 字)\n", s.Title, len([]rune(s.Content)))
    }
}

运行

bash
echo "# 公司年报
2025年度业绩总览。

## 营收分析
全年营收12亿元,同比增长23%。

## 成本结构
研发成本占比45%,运营成本30%。
" > sample.md

go run main.go

明天的预告

文档读进去了,明天用 Eino Chain 把解析、分析、总结串成一条链——让文档"自己说话"。


Day 1 完成。Pipeline 跑通了。