AI Agent Framework - 通用设计模式

目标: 将 MPP Insight Agent 的设计抽象为通用框架,可复用于其他领域(如炒股、客服、运维等)


框架概述

这是一个基于 LLM Function Calling 的自主 AI Agent 框架,核心特点:

  • 🧠 自主决策: Agent 根据用户问题自主选择工具和执行策略
  • 🔄 迭代执行: 支持多轮工具调用,根据结果动态调整
  • 🔧 工具化架构: 可插拔的工具系统,易于扩展
  • 💾 上下文记忆: 跨轮次记住关键信息,支持连续对话
  • 🛡️ 策略控制: 基于规则的权限控制,危险操作需确认

核心架构(三层设计)

┌─────────────────────────────────────────────────────────┐
│              Layer 1: 交互层 (CLI/Web/API)              │
│  - 用户输入/输出                                         │
│  - 会话管理                                              │
│  - 特殊命令处理 (help, exit, /clear, /history)         │
└────────────────────┬────────────────────────────────────┘
                     │
┌────────────────────▼────────────────────────────────────┐
│              Layer 2: Agent 引擎                         │
│  - Function Calling 循环                                │
│  - LLM 调用和响应处理                                   │
│  - 工具执行管理                                         │
│  - 上下文记忆 (SessionContext)                          │
│  - 对话历史压缩 (LLM-based Summarization)               │
│  - 策略引擎集成 (PolicyEngine)                          │
└────────┬───────────────────────────────┬────────────────┘
         │                               │
┌────────▼──────────┐          ┌────────▼────────────────┐
│  ToolManager      │          │   LLM API               │
│  - 工具注册       │          │   - OpenAI              │
│  - 工具发现       │          │   - Qwen                │
│  - 工具执行       │          │   - 兼容 API            │
└────────┬──────────┘          └─────────────────────────┘
         │
┌────────▼──────────────────────────────────────────────┐
│              Layer 3: 工具层 (Tools)                    │
│  - Tool Interface (统一接口)                           │
│  - 具体工具实现 (log_query, db_query, api_call, etc.) │
│  - 外部服务集成 (SLS, DB, API Gateway, etc.)          │
└────────────────────────────────────────────────────────┘

核心组件详解

1. Agent 引擎 (pkg/agent/agent.go)

职责: Function Calling 循环控制器

核心数据结构:

type Agent struct {
    toolManager         *ToolManager      // 工具管理器
    policyEngine        *PolicyEngine     // 策略引擎
    llmAPI              string            // LLM API 地址
    llmAPIKey           string            // LLM API Key
    llmModel            string            // 模型名称
    systemPrompt        string            // System Prompt
    httpClient          *http.Client      // HTTP 客户端
    maxIterations       int               // 最大迭代次数
    sessionContext      *SessionContext   // 会话上下文
    conversationHistory []Message         // 对话历史
}

type Message struct {
    Role       string     // system, user, assistant, tool
    Content    string     // 消息内容
    ToolCalls  []ToolCall // 工具调用(assistant 消息)
    ToolCallID string     // 工具调用 ID(tool 消息)
}

核心方法:

// Run 执行一次用户请求(支持多轮迭代)
func (a *Agent) Run(userQuestion string) (*RunResponse, error)

// callLLM 调用 LLM API(带工具定义)
func (a *Agent) callLLM(messages []Message) (*LLMResponse, error)

// truncateHistory 压缩对话历史(LLM-based)
func (a *Agent) truncateHistory(messages []Message) []Message

Function Calling 循环:

用户问题 → 构建消息历史 → 调用 LLM
    ↓                           ↓
    ←─────────────────── 返回答案 (finish_reason=stop)
    ↓
    ←─────────────────── 工具调用请求 (tool_calls)
    ↓
执行工具 → 添加工具结果到消息 → 继续调用 LLM
    ↓
重复直到:
  - LLM 返回最终答案 (stop)
  - 达到最大迭代次数

2. 工具系统 (pkg/tools/)

Tool 接口 (tool_interface.go):

type Tool interface {
    GetName() string                                    // 工具名称
    GetDescription() string                             // 工具描述
    IsEnabled() bool                                    // 是否启用
    Execute(params map[string]interface{}) (interface{}, error) // 执行工具
    GetToolDefinition() ToolDefinition                  // OpenAI Function Calling 格式
    ShouldConfirm(params map[string]interface{}) ConfirmationDetails // 是否需要确认
}

type ToolDefinition struct {
    Name        string                 // 工具名称
    Description string                 // 工具描述
    Parameters  map[string]interface{} // JSON Schema 格式参数定义
}

ToolManager (工具管理器):

type ToolManager struct {
    tools map[string]Tool
}

func (tm *ToolManager) RegisterTool(tool Tool)           // 注册工具
func (tm *ToolManager) GetToolDefinitions() []ToolDefinition // 获取所有工具定义
func (tm *ToolManager) ExecuteTool(name string, params map[string]interface{}) (interface{}, error) // 执行工具

工具实现示例 (log_query/log_query.go):

type LogQueryTool struct {
    tools.BaseTool
    slsClient *SLSClient
}

func (t *LogQueryTool) GetToolDefinition() ToolDefinition {
    return ToolDefinition{
        Name:        "log_query",
        Description: "Query system logs from SLS",
        Parameters: map[string]interface{}{
            "type": "object",
            "properties": map[string]interface{}{
                "logstore": map[string]interface{}{
                    "type": "string",
                    "description": "Logstore name (e.g., mpp-schedule-trace)",
                },
                "query": map[string]interface{}{
                    "type": "string",
                    "description": "Query condition (SLS syntax)",
                },
                // ... 更多参数
            },
            "required": []string{"logstore", "query"},
        },
    }
}

func (t *LogQueryTool) Execute(params map[string]interface{}) (interface{}, error) {
    // 1. 解析参数
    // 2. 调用外部服务 (SLS)
    // 3. 返回结果
}

3. 会话上下文 (pkg/agent/session_context.go)

职责: 跨轮次记住关键信息,避免重复查询

核心数据结构:

type SessionContext struct {
    Products     map[string]bool // 产品线 (如 mps, mediaai)
    EngineModels map[string]bool // 引擎模型 (如 VideoTranscode)
    TaskIDs      map[string]bool // 任务 ID
    UserIDs      map[string]bool // 用户 ID
    Logstores    map[string]bool // 已查询的 logstore
}

核心方法:

// 从工具结果中提取上下文
func (sc *SessionContext) ExtractFromToolResult(toolName string, result interface{})

// 从用户输入中提取上下文
func (sc *SessionContext) ExtractFromUserInput(input string)

// 生成上下文提示(注入到 System Prompt)
func (sc *SessionContext) GetContextPrompt() string

工作原理:

  1. 每次工具执行成功后,自动提取关键标识符(正则匹配)
  2. 将提取的信息注入到下一轮的 System Prompt 中
  3. LLM 在后续查询中优先使用这些信息进行过滤

4. 策略引擎 (pkg/policy/policy_engine.go)

职责: 控制工具执行权限,危险操作需用户确认

核心数据结构:

type PolicyEngine struct {
    rules           []PolicyRule
    defaultDecision PolicyDecision
    nonInteractive  bool
}

type PolicyRule struct {
    ToolName    string         // 工具名称
    ArgsPattern *regexp.Regexp // 参数匹配模式
    Decision    PolicyDecision // 决策 (Allow/Deny/AskUser)
    Priority    int            // 优先级
}

type PolicyDecision int
const (
    PolicyAllow   PolicyDecision = iota // 直接允许
    PolicyDeny                           // 直接拒绝
    PolicyAskUser                        // 询问用户
)

使用示例:

// 只读工具 - 直接允许
policyEngine.AddRule(PolicyRule{
    ToolName:    "log_query",
    Decision:    PolicyAllow,
    Priority:    50,
})

// 危险操作 - 需要确认
cancelJobsPattern := regexp.MustCompile(`"action"\s*:\s*"cancel_jobs"`)
policyEngine.AddRule(PolicyRule{
    ToolName:    "api_gateway",
    ArgsPattern: cancelJobsPattern,
    Decision:    PolicyAskUser,
    Priority:    100,
})

5. 对话历史压缩 (agent.go 中的 truncateHistory)

问题: 长对话会导致 token 超限和响应变慢

解决方案: LLM-based Summarization(灵感来自 Gemini CLI)

策略:

[system] + [old messages] + [recent messages]
           ↓ (压缩)
[system] + [LLM summary] + [recent messages]

实现:

func (a *Agent) truncateHistory(messages []Message) []Message {
    if len(messages) < compressionThreshold {
        return messages // 不需要压缩
    }

    // 1. 保留 system message
    systemMsg := messages[0]

    // 2. 找到安全分割点(避免破坏 tool/tool_calls 配对)
    splitIndex := a.findSafeSplitPoint(messages)

    // 3. 使用 LLM 总结中间消息
    summary := a.summarizeMessagesWithLLM(messages[1:splitIndex])

    // 4. 构建压缩后的历史
    compressed := []Message{
        systemMsg,
        {Role: "user", Content: "📝 历史对话摘要:\n" + summary},
        {Role: "assistant", Content: "好的,我已了解之前的对话内容"},
        ...messages[splitIndex:], // 保留最近的消息
    }

    return compressed
}

总结 Prompt (State Manager 模式):

你是一个状态管理器,负责将对话历史压缩为结构化的状态快照。

生成 <state_snapshot> XML 对象,包含:
- <overall_goal>: 用户的高层目标
- <key_knowledge>: 关键事实、发现和约束
- <data_source_state>: 已查询的数据源及结果
- <ruled_out>: 已排除的可能性(避免重复查询)
- <recent_findings>: 最近的重要发现

要求:
- 信息密度极高
- 省略无关的对话填充词
- 保留所有关键细节
- 总字数控制在 400 字以内

6. System Prompt 设计 (docs-for-ai/log_analyzer_system_prompt.md)

核心原则:

  1. 主动使用工具: 永远不要说"我无法查询"
  2. 上下文记忆: 利用 SessionContext 中的信息
  3. 简洁输出: 避免冗余解释
  4. 安全优先: 危险操作前解释影响
  5. 迭代分析: 根据结果决定下一步

结构:

# System Prompt

## 当前时间信息
{{CURRENT_TIME}} (动态注入)

## 核心原则
- 主动使用工具
- 上下文记忆
- 简洁输出
- ...

## 工作流程
### 工作流 1: 故障诊断
1. 理解问题
2. 收集信息(多层查询策略)
3. 分析根因
4. 提供方案

### 工作流 2: 数据查询
...

## 可用工具
### log_query
- 功能: 查询日志
- 参数: logstore, query, start_time, end_time
- 示例: ...

### api_gateway
...

## 输出格式
### 📋 问题摘要
### 🔍 分析过程
### 💡 根因分析
### ✅ 解决方案

## 会话上下文(动态注入)⭐
**已知产品线**: mps, mediaai
**已知引擎模型**: VideoTranscode
**使用建议**: 查询时优先使用这些信息过滤

如何复用此框架构建炒股 Agent

步骤 1: 定义领域工具

炒股领域需要的工具:

// 1. 股票行情查询工具
type StockQuoteTool struct {
    tools.BaseTool
    apiClient *StockAPIClient
}

func (t *StockQuoteTool) GetToolDefinition() ToolDefinition {
    return ToolDefinition{
        Name:        "stock_quote",
        Description: "Query real-time stock quotes and historical data",
        Parameters: map[string]interface{}{
            "type": "object",
            "properties": map[string]interface{}{
                "symbol": {
                    "type": "string",
                    "description": "Stock symbol (e.g., AAPL, 600519.SH)",
                },
                "period": {
                    "type": "string",
                    "enum": []string{"1d", "5d", "1m", "3m", "1y"},
                    "description": "Time period",
                },
            },
            "required": []string{"symbol"},
        },
    }
}

// 2. 技术指标计算工具
type TechnicalIndicatorTool struct {
    tools.BaseTool
}

func (t *TechnicalIndicatorTool) GetToolDefinition() ToolDefinition {
    return ToolDefinition{
        Name:        "technical_indicator",
        Description: "Calculate technical indicators (MA, MACD, RSI, etc.)",
        Parameters: map[string]interface{}{
            "type": "object",
            "properties": map[string]interface{}{
                "symbol": {"type": "string"},
                "indicator": {
                    "type": "string",
                    "enum": []string{"MA", "MACD", "RSI", "BOLL", "KDJ"},
                },
                "params": {
                    "type": "object",
                    "description": "Indicator parameters (e.g., {period: 20})",
                },
            },
            "required": []string{"symbol", "indicator"},
        },
    }
}

// 3. 财务数据查询工具
type FinancialDataTool struct {
    tools.BaseTool
}

// 4. 新闻舆情分析工具
type NewsAnalysisTool struct {
    tools.BaseTool
}

// 5. 交易执行工具(危险操作)
type TradingTool struct {
    tools.BaseTool
}

func (t *TradingTool) ShouldConfirm(params map[string]interface{}) ConfirmationDetails {
    action := params["action"].(string)
    if action == "buy" || action == "sell" {
        return ConfirmationDetails{
            ShouldConfirm: true,
            Prompt:        fmt.Sprintf("确认执行交易: %s %s %d 股?", action, params["symbol"], params["quantity"]),
            Impact:        "此操作将直接影响您的账户资金",
        }
    }
    return ConfirmationDetails{ShouldConfirm: false}
}

步骤 2: 定义 SessionContext(炒股领域)

type StockSessionContext struct {
    mu sync.RWMutex

    // 关注的股票
    WatchedSymbols map[string]bool // 用户关注的股票代码

    // 交易策略
    ActiveStrategies map[string]bool // 当前激活的策略

    // 持仓信息
    Holdings map[string]int // 股票代码 -> 持仓数量

    // 市场环境
    MarketTrend string // "bull", "bear", "sideways"

    // 风险偏好
    RiskLevel string // "conservative", "moderate", "aggressive"
}

func (sc *StockSessionContext) ExtractFromToolResult(toolName string, result interface{}) {
    resultStr := fmt.Sprintf("%v", result)

    // 提取股票代码
    symbolPattern := regexp.MustCompile(`"symbol"\s*:\s*"([A-Z0-9.]+)"`)
    if matches := symbolPattern.FindAllStringSubmatch(resultStr, -1); matches != nil {
        for _, match := range matches {
            sc.WatchedSymbols[match[1]] = true
        }
    }

    // 提取市场趋势
    if strings.Contains(resultStr, "bull market") {
        sc.MarketTrend = "bull"
    } else if strings.Contains(resultStr, "bear market") {
        sc.MarketTrend = "bear"
    }
}

func (sc *StockSessionContext) GetContextPrompt() string {
    var parts []string

    if len(sc.WatchedSymbols) > 0 {
        symbols := make([]string, 0, len(sc.WatchedSymbols))
        for s := range sc.WatchedSymbols {
            symbols = append(symbols, s)
        }
        parts = append(parts, fmt.Sprintf("**关注股票**: %s", strings.Join(symbols, ", ")))
    }

    if sc.MarketTrend != "" {
        parts = append(parts, fmt.Sprintf("**市场趋势**: %s", sc.MarketTrend))
    }

    if len(parts) == 0 {
        return ""
    }

    return "\n\n## 会话上下文(已记住的信息)⭐\n\n" + strings.Join(parts, "\n") + "\n\n" +
        "**使用建议**:\n" +
        "- 分析时优先关注已记住的股票\n" +
        "- 根据市场趋势调整策略建议\n"
}

步骤 3: 配置策略引擎(炒股领域)

func createStockPolicyEngine() *policy.PolicyEngine {
    policyEngine := policy.NewPolicyEngine(policy.PolicyEngineConfig{
        DefaultDecision: policy.PolicyAskUser,
        NonInteractive:  false,
    })

    // 只读工具 - 直接允许
    policyEngine.AddRule(policy.PolicyRule{
        ToolName:    "stock_quote",
        Decision:    policy.PolicyAllow,
        Priority:    50,
        Description: "股票行情查询(只读,直接允许)",
    })

    policyEngine.AddRule(policy.PolicyRule{
        ToolName:    "technical_indicator",
        Decision:    policy.PolicyAllow,
        Priority:    50,
        Description: "技术指标计算(只读,直接允许)",
    })

    policyEngine.AddRule(policy.PolicyRule{
        ToolName:    "financial_data",
        Decision:    policy.PolicyAllow,
        Priority:    50,
        Description: "财务数据查询(只读,直接允许)",
    })

    // 交易操作 - 需要确认
    buyPattern := regexp.MustCompile(`"action"\s*:\s*"buy"`)
    policyEngine.AddRule(policy.PolicyRule{
        ToolName:    "trading",
        ArgsPattern: buyPattern,
        Decision:    policy.PolicyAskUser,
        Priority:    100,
        Description: "买入操作(需要用户确认)",
    })

    sellPattern := regexp.MustCompile(`"action"\s*:\s*"sell"`)
    policyEngine.AddRule(policy.PolicyRule{
        ToolName:    "trading",
        ArgsPattern: sellPattern,
        Decision:    policy.PolicyAskUser,
        Priority:    100,
        Description: "卖出操作(需要用户确认)",
    })

    // 大额交易 - 额外确认
    largeAmountPattern := regexp.MustCompile(`"amount"\s*:\s*([0-9]+)`)
    policyEngine.AddRule(policy.PolicyRule{
        ToolName:    "trading",
        ArgsPattern: largeAmountPattern,
        Decision:    policy.PolicyAskUser,
        Priority:    110,
        Description: "大额交易(需要额外确认)",
        CustomCheck: func(params map[string]interface{}) bool {
            amount, ok := params["amount"].(float64)
            return ok && amount > 100000 // 超过 10 万需要确认
        },
    })

    return policyEngine
}

步骤 4: 编写 System Prompt(炒股领域)

# 炒股 AI Agent System Prompt

你是一个专业的股票投资分析助手,擅长技术分析、基本面分析和风险控制。

## 当前时间信息
**当前时间**: {{CURRENT_TIME}}
**交易日**: {{IS_TRADING_DAY}}
**市场状态**: {{MARKET_STATUS}} (开盘/收盘/盘前/盘后)

## 核心原则

### 1. 主动使用工具
- 直接调用可用工具(stock_quote, technical_indicator, financial_data, trading)
- 如果第一次查询结果不够,继续深入查询
- 并行执行独立的查询以提高效率

### 2. 上下文记忆
- 系统会自动记住:
  - 关注的股票代码
  - 市场趋势判断
  - 持仓信息
  - 风险偏好
- 后续分析时优先使用这些信息

### 3. 风险控制优先
- 任何交易建议都要评估风险
- 明确止损位和止盈位
- 考虑仓位管理
- 危险操作前解释影响

### 4. 数据驱动决策
- 基于实时数据和历史数据
- 结合技术指标和基本面
- 避免主观臆断

## 工作流程

### 工作流 1: 股票分析
1. **获取基础数据**
   - 调用 stock_quote 获取实时行情
   - 调用 financial_data 获取财务数据
2. **技术分析**
   - 调用 technical_indicator 计算 MA, MACD, RSI 等
   - 识别支撑位和阻力位
3. **综合判断**
   - 结合技术面和基本面
   - 给出买入/卖出/持有建议
4. **风险评估**
   - 计算风险收益比
   - 设定止损止盈

### 工作流 2: 交易执行
1. **确认交易意图**
   - 明确股票代码、数量、价格
2. **风险检查**
   - 检查仓位比例
   - 评估市场环境
3. **执行交易**
   - 调用 trading 工具
   - 系统会自动弹出确认对话框
4. **跟踪反馈**
   - 记录交易到会话上下文
   - 后续分析时考虑持仓

## 可用工具

### stock_quote
- 功能: 查询实时行情和历史数据
- 参数: symbol (股票代码), period (时间周期)
- 示例: `{"symbol": "AAPL", "period": "1m"}`

### technical_indicator
- 功能: 计算技术指标
- 参数: symbol, indicator (MA/MACD/RSI/BOLL/KDJ), params
- 示例: `{"symbol": "AAPL", "indicator": "MA", "params": {"period": 20}}`

### financial_data
- 功能: 查询财务数据
- 参数: symbol, data_type (income/balance/cashflow)
- 示例: `{"symbol": "AAPL", "data_type": "income"}`

### trading
- 功能: 执行交易(需要确认)
- 参数: action (buy/sell), symbol, quantity, price
- 示例: `{"action": "buy", "symbol": "AAPL", "quantity": 100, "price": 150.0}`

## 输出格式

### 📊 股票分析报告
- **股票代码**: AAPL
- **当前价格**: $150.00 (+2.5%)
- **技术指标**:
  - MA20: $148.00 (价格在均线上方,多头趋势)
  - RSI: 65 (中性偏强)
  - MACD: 金叉形成
- **基本面**:
  - PE: 25.5
  - 营收增长: +15% YoY
- **综合评分**: 7.5/10

### 💡 投资建议
- **操作建议**: 买入
- **目标价位**: $160.00
- **止损位**: $145.00
- **风险收益比**: 1:2
- **仓位建议**: 不超过总资金的 20%

### ⚠️ 风险提示
- 市场波动风险
- 行业政策风险
- 个股特定风险

## 会话上下文(动态注入)⭐
**关注股票**: AAPL, TSLA, NVDA
**市场趋势**: bull
**风险偏好**: moderate
**使用建议**: 分析时优先关注已记住的股票,根据市场趋势调整策略

步骤 5: 主程序入口(炒股领域)

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"

    "stock-agent/pkg/agent"
    "stock-agent/pkg/policy"
    "stock-agent/pkg/tools"
    "stock-agent/pkg/tools/stock_quote"
    "stock-agent/pkg/tools/technical_indicator"
    "stock-agent/pkg/tools/financial_data"
    "stock-agent/pkg/tools/trading"
)

func main() {
    fmt.Println("╔═══════════════════════════════════════════════════════╗")
    fmt.Println("║     Stock AI Agent - 智能炒股助手                    ║")
    fmt.Println("╚═══════════════════════════════════════════════════════╝")

    // 1. 创建工具管理器
    toolManager := tools.NewToolManager()

    // 2. 注册工具
    toolManager.RegisterTool(stock_quote.NewStockQuoteTool(stock_quote.Config{
        Enabled: true,
        APIKey:  os.Getenv("STOCK_API_KEY"),
        Timeout: 30,
    }))

    toolManager.RegisterTool(technical_indicator.NewTechnicalIndicatorTool(technical_indicator.Config{
        Enabled: true,
        Timeout: 30,
    }))

    toolManager.RegisterTool(financial_data.NewFinancialDataTool(financial_data.Config{
        Enabled: true,
        APIKey:  os.Getenv("FINANCIAL_API_KEY"),
        Timeout: 30,
    }))

    toolManager.RegisterTool(trading.NewTradingTool(trading.Config{
        Enabled:    true,
        BrokerAPI:  os.Getenv("BROKER_API"),
        BrokerKey:  os.Getenv("BROKER_KEY"),
        Timeout:    30,
    }))

    // 3. 创建策略引擎
    policyEngine := createStockPolicyEngine()

    // 4. 加载 System Prompt
    systemPrompt := loadSystemPrompt()

    // 5. 创建 Agent
    agentInstance := agent.NewAgent(agent.Config{
        ToolManager:   toolManager,
        PolicyEngine:  policyEngine,
        LLMAPI:        os.Getenv("LLM_API"),
        LLMAPIKey:     os.Getenv("LLM_API_KEY"),
        LLMModel:      "gpt-4",
        SystemPrompt:  systemPrompt,
        LLMTimeout:    60,
        MaxIterations: 10,
    })

    // 6. 交互循环
    scanner := bufio.NewScanner(os.Stdin)
    for {
        fmt.Print("\n💬 你的问题: ")
        if !scanner.Scan() {
            break
        }

        question := strings.TrimSpace(scanner.Text())
        if question == "exit" || question == "quit" {
            fmt.Println("👋 再见!")
            break
        }

        // 运行 Agent
        resp, err := agentInstance.Run(question)
        if err != nil {
            fmt.Printf("❌ 执行失败: %v\n", err)
            continue
        }

        // 显示结果
        fmt.Println("\n" + strings.Repeat("─", 60))
        fmt.Println(resp.Answer)
        fmt.Println()
    }
}

框架优势总结

1. 可复用性

  • 核心 Agent 引擎完全通用,无需修改
  • 只需实现领域特定的 Tool 和 SessionContext
  • System Prompt 可模板化

2. 可扩展性

  • 新增工具只需实现 Tool 接口
  • 工具之间完全解耦
  • 支持动态注册和禁用

3. 安全性

  • 策略引擎统一控制权限
  • 危险操作自动弹出确认
  • 支持细粒度的参数匹配

4. 智能性

  • LLM 自主决策工具调用顺序
  • 上下文记忆避免重复查询
  • 对话历史压缩保持长期记忆

5. 可维护性

  • 清晰的三层架构
  • 统一的接口定义
  • 完善的日志和错误处理

快速开始检查清单

要基于此框架构建新的 Agent,需要完成以下步骤:

  • 定义领域工具 (实现 Tool 接口)

    • 只读工具(查询类)
    • 写入工具(操作类)
    • 工具的 ToolDefinition(OpenAI Function Calling 格式)
  • 定义 SessionContext (领域特定的上下文)

    • 需要记住的关键信息
    • ExtractFromToolResult 实现
    • GetContextPrompt 实现
  • 配置策略引擎 (权限控制)

    • 只读工具 → PolicyAllow
    • 危险操作 → PolicyAskUser
    • 自定义规则(基于参数匹配)
  • 编写 System Prompt (领域知识)

    • 核心原则
    • 工作流程
    • 可用工具说明
    • 输出格式
  • 主程序入口 (集成所有组件)

    • 工具注册
    • Agent 初始化
    • 交互循环
  • 测试和优化

    • 单元测试(工具执行)
    • 集成测试(完整流程)
    • System Prompt 调优

参考实现

完整的 MPP Insight Agent 实现可参考:

  • console/pkg/agent/ - Agent 引擎
  • console/pkg/tools/ - 工具系统
  • console/pkg/policy/ - 策略引擎
  • console/cmd/interactive_agent/ - 主程序

常见问题

Q1: 如何处理工具执行失败?

A: Agent 会自动将错误信息返回给 LLM,LLM 可以:

  • 修正参数重试
  • 尝试其他工具
  • 向用户说明问题

Q2: 如何控制 LLM 的 token 消耗?

A: 使用对话历史压缩(truncateHistory),当消息数超过阈值时自动压缩。

Q3: 如何避免 LLM 重复调用相同工具?

A: 通过 SessionContext 记住已查询的信息,并注入到 System Prompt 中。

Q4: 如何处理并发工具调用?

A: 参考 pkg/agent/todo_parallel_tools.go,实现并行执行独立的工具调用。

Q5: 如何自定义确认对话框?

A: 实现 Tool 的 ShouldConfirm 方法,返回自定义的确认提示和影响说明。


License: MIT
Author: MPP Insight Team
Version: 2.0
Last Updated: 2025-10-22

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐