dify

package module
v1.5.1-rc.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 3, 2025 License: MIT Imports: 3 Imported by: 0

README

dify-sdk-go

dify SDK的go语言版本(dify版本 >= 1.1.3,低版本未测试) 使用go官方自带库构建,无任何三方库依赖 囊括dify应用的所有接口

Dify应用类型

Dify一共有5种应用类型,具体如下:

应用类型 名称 类型
对话型应用 聊天助手 Chatbot
对话型应用 Agent Agent
文本生成型应用 文本生成 Completion
工作流编排对话型应用 Chatflow Chatflow
Workflow应用 工作流 Workflow
应用接口与SDK函数对应关系

每种应用类型拥有的API接口并不完全相同,下表列出了Dify每种应用的Api接口和在SDK中对应的函数关系。

功能 SDK函数 Chatbot/Agent Completion Chatflow Workflow Dify接口
发送对话消息 Run/RunBlock 1 1 POST/chat-messages
发送消息 Run/RunBlock 1 POST/completion-messages
执行workflow Run/RunBlock 1 POST/workflows/run
--
停止响应 Stop 1 1 POST/chat-messages/:task_id/stop
停止响应 Stop 1 POST/completion-messages/:task_id/stop
停止响应 Stop 1 POST/workflows/tasks/:task_id/stop
--
上传文件 UploadFile 1 1 1 1 POST/files/upload
获取应用基本信息 AppInfo 1 1 1 1 GET/info
获取应用参数 AppParameter 1 1 1 1 GET/parameters
获取应用WebApp设置 AppSite 1 1 1 1 GET/site
--
获取workflow执行情况 Status 1 GET/workflows/run/:workflow_id
消息反馈(点赞) MsgFeedback 1 1 1 POST/messages/:message_id/feedbacks
获取APP的消息点赞和反馈 AppFeedback 1 1 1 GET/app/feedbacks
获取下一轮建议问题列表 SuggestQuestionList 1 1 GET/messages/{message_id}/suggested
获取会话历史消息 History/HistoryPro 1 1 GET/messages
获取workflow日志 Logs 1 GET/workflows/logs
获取会话列表 ConversationList/ConversationListPro 1 1 GET/conversations
删除会话 ConversationDel 1 1 DELETE/conversations/:conversation_id
会话重命名 ConversationRename 1 1 POST/conversations/:conversation_id/name
获取对话变量 ConversationVars 1 1 GET/conversations/:conversation_id/variables
语音转文字 AudioToText 1 1 POST/audio-to-text
文字转语音 TextToAudio 1 1 1 POST/text-to-audio
获取应用Meta信息 AppMeta 1 1 GET/meta
获取标注列表 AnnotationList 1 1 GET/apps/annotations
创建标注 AnnotationCreate 1 1 POST/apps/annotations
更新标注 AnnotationUpdate 1 1 PUT/apps/annotations/{annotation_id}
删除标注 AnnotationDel 1 1 DELETE/apps/annotations/{annotation_id}
标注回复初始设置 AnnotationReplySetting 1 1 POST/apps/annotation-reply/{action}
查询标注回复初始设置任务状态 AnnotationReplySettingJobStatus 1 1 GET/apps/annotation-reply/{action}/status/{job_id}
--
创建Client

Client的配置定义在dify.ClientConfig这个结构体中:

type ClientConfig struct {
	ApiServer string        // [必填]API服务器 eg: http://your.domain.com/v1 注意是包括/v1的
	ApiKey    string        // [必填]API密钥
	User      string        // 用户标识 部分接口需要传入用户标识,这里设置后,调用接口时user字段可留空
	Debug     bool          // 是否打印原始请求及响应
	Timeout   time.Duration // 超时时间,默认300秒
	Transport *http.Transport
}
NewClient(config ClientConfig) (*base.Client, error) 

ClientConfig有两个必填参数ApiServer和ApiKey,由于很多接口都需要传入User参数,所以建议在创建客户端时同时把User的值也设置了,这样后面使用时,遇到User参数的地方可以传入空字符串。 其他参数可以根据需要进行设置,所以我们可以这样构建一个客户端:

        client,err:=dify.NewClient(dify.ClientConfig{
		ApiServer: "http://your.domain/v1", // 注意这里是包括/v1的
		ApiKey:    "your-api-key",
		User: "demo-client",
	})
	if err != nil {
		log.Fatalf("Error creating client: %v", err)
	}

客户端创建后,根据你应用的类型,调用XxxApp函数,然后就可以调用应用拥有的具体功能函数了

  • 如果是 聊天助手 Chatbot 类型,则是 client.ChatbotApp()
  • 如果是 Agent 类型,则是 client.AgentApp()
  • 如果是 文本生成 Completion 类型,则是 client.CompletionApp()
  • 如果是 Chatflow 类型,则是 client.ChatflowApp()
  • 如果是 工作流 Workflow 类型,则是 client.WorkflowApp()

需要注意的是,对于流式调用,这里提供了三种结果的输出方式:

  • 方式一:将SSE Event事件解析为一个大而全的结构体,再通过channel输出 优点是输出是固定的结构体,但这个结构体字段很多,很多字段会是空值,使用时不方便判断哪些字段是有用的,哪些是没用的 调用示例:eventCh := client.AgentApp().Run(ctx, types.ChatRequest{}).ParseToStructCh()
  • 方式二:将SSE Event事件中的输出以文本字符串方式,通过channel提供出来 优点是只输出最终文本内容,其他内容不输出,使用最简单 调用示例:eventCh := client.AgentApp().Run(ctx, types.ChatRequest{}).SimplePrint()
  • 方式三:将SSE Event按事件类型,解析为具体的结构体,然后通过channel提供 优点是不同的event事件类型,对应不同的结构体,更加精准,但是使用前需要做类型断言 如:msg.Data.(*types.EventMessage) 调用示例:eventCh := client.AgentApp().Run(ctx, types.ChatRequest{}).ParseToEventCh()
一个完整的示例

阻塞式调用示例:

package main

import (
	"context"
	"log"

	"github.com/safejob/dify-sdk-go"
	"github.com/safejob/dify-sdk-go/types"
)

func main() {
	// 构建客户端
	client, err := dify.NewClient(dify.ClientConfig{
		ApiServer: "http://your.domain/v1",
		ApiKey:    "your-api-key",
		User:      "demo-client",
	})
	if err != nil {
		log.Fatalf("Error creating client: %v", err)
	}

	// 获取应用基本信息
	appInfo, err := client.ChatbotApp().AppInfo()
	if err != nil {
		log.Fatalf("Error getting app info: %v", err)
	}
	log.Printf("应用名称:%s 应用描述:%s \n", appInfo.Name, appInfo.Description)

	// 阻塞式调用示例
	ctx := context.Background()
	resp, err := client.ChatbotApp().RunBlock(ctx, types.ChatRequest{
		Query: "请帮我生成五一假期的出行计划",
	})
	if err != nil {
		log.Fatalf("Error running client: %v", err)
	}

	log.Printf("响应结果:\n %s", resp.Answer)
}

流式调用示例:

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/safejob/dify-sdk-go"
	"github.com/safejob/dify-sdk-go/base"
	"github.com/safejob/dify-sdk-go/types"
)

func main() {
	// 构建客户端
	client, err := dify.NewClient(dify.ClientConfig{
		ApiServer: "http://your.domain/v1",
		ApiKey:    "your-api-key",
		User:   "demo-client",
	})
	if err != nil {
		log.Fatalf("Error creating client: %v", err)
	}

	ctx := context.Background()
	input := make(map[string]interface{})
	input["name"] = "张三" // 这里根据实际dify配置,填写需要使用的变量
	request := types.ChatRequest{
		Query:            "帮我构思一个国庆五天的出游计划,尽可能详细一点",
		Inputs:           input,
		ResponseMode:     "",
		User:             "",
		ConversationId:   "",
		Files:            nil,
		AutoGenerateName: nil,
	}

	choise := 1
	switch choise {
	case 1:
		// ParseToStructCh调用示例
		ParseToStructChDemo(ctx, client, request)
	case 2:
		// SimplePrint调用示例
		SimplePrintDemo(ctx, client, request)
	case 3:
		// ParseToEventCh调用示例
		ParseToEventChDemo(ctx, client, request)
	}
}

// ParseToStructCh调用示例
func ParseToStructChDemo(ctx context.Context, client *base.Client, request types.ChatRequest) {
	eventCh := client.AgentApp().Run(ctx, request).ParseToStructCh()
	for {
		select {
		case msg, ok := <-eventCh:
			// 这里的msg是一个大结构体 字段非常多
			if !ok {
				return
			}
			if msg.Event == "error" {
				log.Printf("status=%d code=%s message=%s", msg.Status, msg.Code, msg.Message)
			}
			if msg.Answer != "" {
				fmt.Printf("%s", msg.Answer)
			}
		}
	}
}

// SimplePrint调用示例
func SimplePrintDemo(ctx context.Context, client *base.Client, request types.ChatRequest) {
  eventCh, meta := client.AgentApp().Run(ctx, request).SimplePrint()

  // 方式一
  for msg := range eventCh {
    fmt.Printf("%s", msg)
  }
  fmt.Printf("\n本次会话conversationId=%s taskId=%s\n", meta.ConversationId, meta.TaskId)

  // 方式二
  //for {
  //	select {
  //	case msg, ok := <-eventCh:
  //		if !ok {
  //			fmt.Printf("\n本次会话conversationId=%s taskId=%s\n", meta.ConversationId, meta.TaskId)
  //			return
  //		}
  //		fmt.Printf("%s", msg)
  //	}
  //}
}

// ParseToEventCh调用示例
func ParseToEventChDemo(ctx context.Context, client *base.Client, request types.ChatRequest) {
	eventCh := client.AgentApp().Run(ctx, request).ParseToEventCh()
	for {
		select {
		case msg, ok := <-eventCh:
			// 这里的msg是具体的结构体,需要根据msg.Type的值进行断言
			if !ok {
				return
			}
			switch msg.Type {
			case types.EVENT_AGENT_THOUGHT:
				event := msg.Data.(*types.EventAgentThought)
				fmt.Printf("agent thought: %s", event.Thought)
			case types.EVENT_AGENT_MESSAGE:
				event := msg.Data.(*types.EventAgentMessage)
				fmt.Printf("%s", event.Answer)
			}
		}
	}
}

待完善的功能

1、文字转语音接口(没有模型供调试) 2、语音转文字接口

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewClient

func NewClient(config ClientConfig) (*base.Client, error)

Types

type ClientConfig

type ClientConfig struct {
	ApiServer string        // [必填]API服务器 eg: http://your.domain.com/v1 注意是包括/v1的
	ApiKey    string        // [必填]API密钥
	User      string        // 用户标识 部分接口需要传入用户标识,这里设置后,调用接口时user字段可留空
	Debug     bool          // 是否打印原始请求及响应
	Timeout   time.Duration // 超时时间,默认300秒
	Transport *http.Transport
}

Directories

Path Synopsis
example

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL