Golang Ollama LangChain智能体

我正在尝试用Golang结合Ollama和LangChain开发一个智能体,但在集成过程中遇到了一些问题。具体来说,不知道如何正确配置LangChain的链式调用与Ollama的本地模型交互,特别是在处理异步响应时经常出现超时错误。有没有熟悉这套技术栈的朋友能分享一下最佳实践?比如如何优化模型调用流程、处理上下文维护,或者有现成的示例代码可以参考?

2 回复

Golang结合Ollama与LangChain可构建高效AI智能体。利用LangChain编排流程,Ollama部署本地模型,Golang提供高性能后端。适合开发RAG、对话机器人等应用,兼顾效率与可控性。

更多关于Golang Ollama LangChain智能体的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang中构建基于Ollama和LangChain的智能体,可以实现本地化AI应用开发。以下是核心实现方案:

1. 环境准备

// go.mod
module ollama-langchain-agent

go 1.21

require (
    github.com/ollama/ollama v0.1.0
    github.com/sashabaranov/go-openai v1.14.0
)

2. 核心智能体结构

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "time"
)

type OllamaAgent struct {
    baseURL    string
    model      string
    httpClient *http.Client
}

func NewOllamaAgent(baseURL, model string) *OllamaAgent {
    return &OllamaAgent{
        baseURL:    baseURL,
        model:      model,
        httpClient: &http.Client{Timeout: 30 * time.Second},
    }
}

type ChatRequest struct {
    Model    string    `json:"model"`
    Messages []Message `json:"messages"`
    Stream   bool      `json:"stream"`
}

type Message struct {
    Role    string `json:"role"`
    Content string `json:"content"`
}

type ChatResponse struct {
    Message Message `json:"message"`
    Done    bool    `json:"done"`
}

3. 对话处理实现

func (oa *OllamaAgent) Chat(ctx context.Context, prompt string) (string, error) {
    messages := []Message{
        {
            Role:    "user",
            Content: prompt,
        },
    }
    
    reqBody := ChatRequest{
        Model:    oa.model,
        Messages: messages,
        Stream:   false,
    }
    
    jsonData, err := json.Marshal(reqBody)
    if err != nil {
        return "", fmt.Errorf("marshal request failed: %v", err)
    }
    
    url := fmt.Sprintf("%s/api/chat", oa.baseURL)
    resp, err := oa.httpClient.Post(url, "application/json", bytes.NewReader(jsonData))
    if err != nil {
        return "", fmt.Errorf("API request failed: %v", err)
    }
    defer resp.Body.Close()
    
    var chatResp ChatResponse
    if err := json.NewDecoder(resp.Body).Decode(&chatResp); err != nil {
        return "", fmt.Errorf("decode response failed: %v", err)
    }
    
    return chatResp.Message.Content, nil
}

4. LangChain风格的工具链集成

type Tool interface {
    Name() string
    Description() string
    Execute(input string) (string, error)
}

type CalculatorTool struct{}

func (c *CalculatorTool) Name() string {
    return "calculator"
}

func (c *CalculatorTool) Description() string {
    return "Performs basic arithmetic calculations"
}

func (c *CalculatorTool) Execute(input string) (string, error) {
    // 简化的计算器实现
    // 实际应用中可以使用表达式解析库
    return "Calculation result for: " + input, nil
}

type Agent struct {
    ollamaAgent *OllamaAgent
    tools       map[string]Tool
}

func NewAgent(ollamaURL, model string) *Agent {
    agent := &Agent{
        ollamaAgent: NewOllamaAgent(ollamaURL, model),
        tools:       make(map[string]Tool),
    }
    
    // 注册工具
    agent.RegisterTool(&CalculatorTool{})
    
    return agent
}

func (a *Agent) RegisterTool(tool Tool) {
    a.tools[tool.Name()] = tool
}

5. 智能体执行流程

func (a *Agent) Run(ctx context.Context, query string) (string, error) {
    // 1. 分析用户意图
    analysisPrompt := fmt.Sprintf(`分析用户查询"%s",判断是否需要使用工具。可用工具:%v`, 
        query, a.getToolDescriptions())
    
    analysis, err := a.ollamaAgent.Chat(ctx, analysisPrompt)
    if err != nil {
        return "", err
    }
    
    // 2. 根据分析结果执行相应操作
    if a.needsTool(analysis) {
        toolName := a.extractToolName(analysis)
        if tool, exists := a.tools[toolName]; exists {
            return tool.Execute(query)
        }
    }
    
    // 3. 直接使用Ollama回答
    return a.ollamaAgent.Chat(ctx, query)
}

func (a *Agent) getToolDescriptions() string {
    var descs []string
    for _, tool := range a.tools {
        descs = append(descs, fmt.Sprintf("%s: %s", tool.Name(), tool.Description()))
    }
    return strings.Join(descs, "; ")
}

6. 使用示例

func main() {
    // 启动Ollama服务(确保ollama服务正在运行)
    agent := NewAgent("http://localhost:11434", "llama2")
    
    ctx := context.Background()
    
    // 执行查询
    result, err := agent.Run(ctx, "计算一下25乘以4等于多少?")
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Println("智能体回复:", result)
}

关键特性

  1. 本地化部署:使用Ollama在本地运行大语言模型
  2. 工具集成:支持扩展各种功能工具
  3. 链式调用:模仿LangChain的智能体工作流程
  4. 错误处理:完善的错误处理和超时控制

这种架构可以轻松扩展更多工具和功能,构建强大的本地AI应用。

回到顶部