### Run Quickstart Example Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_07_interrupt_resume Navigate to the examples directory and run the Chapter 7 quickstart. Ensure the PROJECT_ROOT is set. ```bash # Set project root directory export PROJECT_ROOT=/path/to/your/project go run ./cmd/ch07 ``` -------------------------------- ### Clone Eino Examples Repository Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_01_chatmodel_and_message Clones the Eino examples repository to get started with the quickstart projects. Ensure you have Git installed. ```bash git clone https://github.com/cloudwego/eino-examples.git cd eino-examples/quickstart/chatwitheino ``` -------------------------------- ### Run Eino Agent Example Source: https://www.cloudwego.io/docs/eino/overview/bytedance_eino_practice Navigate to the agent example directory, load environment variables, and run the Go program to start the Eino Agent. ```bash cd eino-examples/eino_assistant # Load env vars (model info, tracing platform info) source .env # Run from eino_assistant to use the embedded data directory go run cmd/einoagent/*.go ``` -------------------------------- ### Install Eino and Ark Component Source: https://www.cloudwego.io/docs/eino/core_modules/flow_integration_components/react_agent_manual Install the Eino framework and the Ark model component using go get. ```go go get github.com/cloudwego/eino-ext/components/model/openai@latest go get github.com/cloudwego/eino-ext/components/model/ark@latest ``` -------------------------------- ### Run Chapter 5 Example Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_05_middleware Execute the Chapter 5 example using Go. Ensure the PROJECT_ROOT environment variable is set. ```bash # Set project root directory export PROJECT_ROOT=/path/to/your/project go run ./cmd/ch05 ``` -------------------------------- ### Install Local Backend Package Source: https://www.cloudwego.io/docs/eino/core_modules/eino_adk/eino_adk_chatmodelagentmiddleware/filesystem_backend/backend_local_filesystem Use 'go get' to install the local backend package. Ensure your Eino version is compatible. ```go go get github.com/cloudwego/eino-ext/adk/backend/local ``` -------------------------------- ### Install eino and OpenAI Extension Source: https://www.cloudwego.io/docs/eino/core_modules/chain_and_graph_orchestration/chain_graph_introduction Install the necessary eino and OpenAI extension packages using go get. ```go go get github.com/cloudwego/eino-ext/components/model/openai@latest go get github.com/cloudwego/eino@latest ``` -------------------------------- ### Running the Graph Tool Example Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_08_graph_tool Execute the Chapter 8 example using Go. Ensure your project root is set correctly. ```bash # Set project root directory export PROJECT_ROOT=/path/to/your/project go run ./cmd/ch08 ``` -------------------------------- ### Run Chapter 6 Example Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_06_callback_and_trace Navigate to the example directory and run the chapter 6 main program. Ensure PROJECT_ROOT and optional CozeLoop variables are set. ```bash # Set project root directory export PROJECT_ROOT=/path/to/your/project # Optional: configure CozeLoop export COZELOOP_WORKSPACE_ID=your_workspace_id export COZELOOP_API_TOKEN=your_token go run ./cmd/ch06 ``` -------------------------------- ### Full Memory Management Workflow in Go Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_03_memory_and_session A comprehensive snippet demonstrating the complete workflow: initializing the store, creating/getting a session, appending user messages, calling the agent, and saving the assistant's reply. This is a simplified example and requires a full project setup to run. ```go store, err := mem.NewStore[M](msgops.DefaultSessionDir(msgops.KindOf[M]())) if err != nil { log.Fatal(err) } // Create or resume a Session session, err := store.GetOrCreate(sessionID) if err != nil { log.Fatal(err) } // User input userMsg := msgops.NewUser[M](line) if err := session.Append(userMsg); err != nil { log.Fatal(err) } // Call the Agent history := session.GetMessages() events := runner.Run(ctx, msgops.NormalizeMessagesForModelInput(history)) result, err := helpers.PrintAndCollect[M](events, helpers.PrintOptions{}) if err != nil { log.Fatal(err) } // Save assistant reply assistantMsg := msgops.NewAssistant[M](result.AssistantText, nil) if err := session.Append(assistantMsg); err != nil { log.Fatal(err) } ``` -------------------------------- ### Callback Handler Example Source: https://www.cloudwego.io/docs/eino/core_modules/components/tools_node_guide Demonstrates how to create and use a callback handler for tool execution, including handling start, end, and streaming output events. ```go import ( "context" "errors" "io" "fmt" callbackHelper "github.com/cloudwego/eino/utils/callbacks" "github.com/cloudwego/eino/callbacks" "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/components/tool" "github.com/cloudwego/eino/schema" ) // Create callback handler handler := &callbackHelper.ToolCallbackHandler{ OnStart: func(ctx context.Context, info *callbacks.RunInfo, input *tool.CallbackInput) context.Context { fmt.Printf("Starting tool execution, arguments: %s\n", input.ArgumentsInJSON) return ctx }, OnEnd: func(ctx context.Context, info *callbacks.RunInfo, output *tool.CallbackOutput) context.Context { fmt.Printf("Tool execution completed, result: %s\n", output.Response) return ctx }, OnEndWithStreamOutput: func(ctx context.Context, info *callbacks.RunInfo, output *schema.StreamReader[*tool.CallbackOutput]) context.Context { fmt.Println("Tool starting streaming output") go func() { defer output.Close() for { chunk, err := output.Recv() if errors.Is(err, io.EOF) { return } if err != nil { return } fmt.Printf("Received streaming output: %s\n", chunk.Response) } }() return ctx }, } // Use callback handler helper := callbackHelper.NewHandlerHelper(). Tool(handler). Handler() /*** compose a chain * chain := NewChain * chain.appendxxx(). * appendxxx(). * ... **/ // Use at runtime // runnable, err := chain.Compile() // if err != nil { // return err // } // result, err := runnable.Invoke(ctx, input, compose.WithCallbacks(helper)) ``` -------------------------------- ### Run Knowledge Indexing Example Source: https://www.cloudwego.io/docs/eino/overview/bytedance_eino_practice Navigate to the example directory, load environment variables, change to the correct subdirectory, and run the Go program for knowledge indexing. ```bash cd xxx/eino-examples/quickstart/eino_assistant # Load env vars (model info, tracing platform info) source .env # The sample Markdown lives in cmd/knowledgeindexing/eino-docs. # Because the code uses the relative path "eino-docs", run from cmd/knowledgeindexing cd cmd/knowledgeindexing go run main.go ``` -------------------------------- ### Install Agentkit Backend Source: https://www.cloudwego.io/docs/eino/core_modules/eino_adk/eino_adk_chatmodelagentmiddleware/filesystem_backend/backend_ark_agentkit_sandbox Install the Agentkit backend package using go get. ```go go get github.com/cloudwego/eino-ext/adk/backend/agentkit ``` -------------------------------- ### Quick Start: Using AgenticModel with OpenAI and Tools Source: https://www.cloudwego.io/docs/eino/ecosystem_integration/chat_model/agentic_model_openai This example demonstrates how to initialize the AgenticModel with OpenAI configuration, including API key, model ID, and reasoning parameters. It also shows how to define and use tools for function calling. ```go package main import ( "context" "log" "os" "github.com/bytedance/sonic" "github.com/cloudwego/eino-ext/components/model/agenticopenai" "github.com/cloudwego/eino/schema" openaischema "github.com/cloudwego/eino/schema/openai" "github.com/eino-contrib/jsonschema" "github.com/openai/openai-go/v3/responses" "github.com/wk8/go-ordered-map/v2" ) func main() { ctx := context.Background() am, err := agenticopenai.New(ctx, &agenticopenai.Config{ BaseURL: "https://api.agenticopenai.com/v1", Model: os.Getenv("OPENAI_MODEL_ID"), APIKey: os.Getenv("OPENAI_API_KEY"), Reasoning: &responses.ReasoningParam{ Effort: responses.ReasoningEffortLow, Summary: responses.ReasoningSummaryDetailed, }, }) if err != nil { log.Fatalf("failed to create agentic model, err: %v", err) } input := []*schema.AgenticMessage{ schema.UserAgenticMessage("what is the weather like in Beijing"), } am_, err := am.WithTools([]*schema.ToolInfo{ { Name: "get_weather", Desc: "get the weather in a city", ParamsOneOf: schema.NewParamsOneOfByJSONSchema(&jsonschema.Schema{ Type: "object", Properties: orderedmap.New[string, *jsonschema.Schema]( orderedmap.WithInitialData( orderedmap.Pair[string, *jsonschema.Schema]{ Key: "city", Value: &jsonschema.Schema{ Type: "string", Description: "the city to get the weather", }, }, ), ), Required: []string{"city"}, }), }, }) if err != nil { log.Fatalf("failed to create agentic model with tools, err: %v", err) } msg, err := am_.Generate(ctx, input) if err != nil { log.Fatalf("failed to generate, err: %v", err) } meta := msg.ResponseMeta.Extension.(*openaischema.ResponseMetaExtension) log.Printf("request_id: %s\n", meta.ID) respBody, _ := sonic.MarshalIndent(msg, " ", " ") log.Printf(" body: %s\n", string(respBody)) } ``` -------------------------------- ### Running the Quickstart Application Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_11_turnloop Execute the main application to try out the preemption and abort features in your browser. ```bash go run . ``` -------------------------------- ### Clone Eino Examples Repository Source: https://www.cloudwego.io/docs/eino/core_modules/devops/visual_debug_plugin_guide Clone the eino-examples repository to get started with debugging examples. Use either HTTPS or SSH. ```bash git clone https://github.com/cloudwego/eino-examples.git # or git clone git@github.com:cloudwego/eino-examples.git ``` -------------------------------- ### Complete Prompt Implementation Example Source: https://www.cloudwego.io/docs/eino/core_modules/components/chat_template_guide A comprehensive example of a custom prompt implementation, including initialization, option handling, callback management, and the core formatting logic. It shows how to integrate options and callbacks into the prompt's lifecycle. ```go type MyPrompt struct { templates []schema.MessagesTemplate formatType schema.FormatType strictMode bool defaultValues map[string]string } func NewMyPrompt(config *MyPromptConfig) (*MyPrompt, error) { return &MyPrompt{ templates: config.Templates, formatType: config.FormatType, strictMode: config.DefaultStrictMode, defaultValues: config.DefaultValues, }, nil } func (p *MyPrompt) Format(ctx context.Context, vs map[string]any, opts ...prompt.Option) ([]*schema.Message, error) { // 1. Handle Options options := &MyPromptOptions{ StrictMode: p.strictMode, DefaultValues: p.defaultValues, } options = prompt.GetImplSpecificOptions(options, opts...) // 2. Get callback manager cm := callbacks.ManagerFromContext(ctx) // 3. Callback before formatting starts ctx = cm.OnStart(ctx, info, &prompt.CallbackInput{ Variables: vs, Templates: p.templates, }) // 4. Execute formatting logic messages, err := p.doFormat(ctx, vs, options) // 5. Handle errors and completion callback if err != nil { ctx = cm.OnError(ctx, info, err) return nil, err } ctx = cm.OnEnd(ctx, info, &prompt.CallbackOutput{ Result: messages, Templates: p.templates, }) return messages, nil } func (p *MyPrompt) doFormat(ctx context.Context, vs map[string]any, opts *MyPromptOptions) ([]*schema.Message, error) { // Implement your own defined logic return messages, nil } ``` -------------------------------- ### Complete Custom Loader Implementation Example Source: https://www.cloudwego.io/docs/eino/core_modules/components/document_loader_guide A full example of a custom loader, including initialization, loading logic, option handling, and callback integration. ```go import ( "github.com/cloudwego/eino/callbacks" "github.com/cloudwego/eino/components/document" "github.com/cloudwego/eino/schema" ) func NewCustomLoader(config *Config) (*CustomLoader, error) { return &CustomLoader{ timeout: config.DefaultTimeout, retryCount: config.DefaultRetryCount, }, } type CustomLoader struct { timeout time.Duration retryCount int } type Config struct { DefaultTimeout time.Duration DefaultRetryCount int } func (l *CustomLoader) Load(ctx context.Context, src document.Source, opts ...document.LoaderOption) ([]*schema.Document, error) { // 1. Handle options options := &customLoaderOptions{ Timeout: l.timeout, RetryCount: l.retryCount, } options = document.GetLoaderImplSpecificOptions(options, opts...) var err error // 2. Handle errors and call error callback method defer func() { if err != nil { callbacks.OnError(ctx, err) } }() // 3. Callback before loading starts ctx = callbacks.OnStart(ctx, &document.LoaderCallbackInput{ Source: src, }) // 4. Execute loading logic docs, err := l.doLoad(ctx, src, options) if err != nil { return nil, err } ctx = callbacks.OnEnd(ctx, &document.LoaderCallbackOutput{ Source: src, Docs: docs, }) return docs, nil } func (l *CustomLoader) doLoad(ctx context.Context, src document.Source, opts *customLoaderOptions) ([]*schema.Document, error) { // Implement document loading logic // 1. Load document content // 2. Construct Document object, note that important information like document source can be saved in MetaData return []*schema.Document{{Content: "Hello World"}}, } ``` -------------------------------- ### Complete Indexer Implementation Example Source: https://www.cloudwego.io/docs/eino/core_modules/components/indexer_guide A comprehensive example demonstrating the structure of a custom Indexer, including initialization, the Store method with option and callback handling, and the doStore logic for vector generation. ```go package indexer import ( "context" "github.com/infratq/go-sdk/pkg/sdk/embedding" "github.com/infratq/go-sdk/pkg/sdk/indexer" "github.com/infratq/go-sdk/pkg/sdk/schema" "github.com/infratq/go-sdk/pkg/sdk/callbacks" ) type MyIndexerConfig struct { DefaultBatchSize int DefaultEmbedder embedding.Embedder } type MyIndexer struct { batchSize int embedder embedding.Embedder } func NewMyIndexer(config *MyIndexerConfig) (*MyIndexer, error) { return &MyIndexer{ batchSize: config.DefaultBatchSize, embedder: config.DefaultEmbedder, }, nil } func (i *MyIndexer) Store(ctx context.Context, docs []*schema.Document, opts ...indexer.Option) ([]string, error) { // 1. Handle options options := &indexer.Options{} options = indexer.GetCommonOptions(options, opts...) // 2. Get callback manager cm := callbacks.ManagerFromContext(ctx) // 3. Callback before storage starts ctx = cm.OnStart(ctx, info, &indexer.CallbackInput{ Docs: docs, }) // 4. Execute storage logic ids, err := i.doStore(ctx, docs, options) // 5. Handle errors and completion callback if err != nil { ctx = cm.OnError(ctx, info, err) return nil, err } ctx = cm.OnEnd(ctx, info, &indexer.CallbackOutput{ IDs: ids, }) return ids, nil } func (i *MyIndexer) doStore(ctx context.Context, docs []*schema.Document, opts *indexer.Options) ([]string, error) { // Implement document storage logic (pay attention to handling common option parameters) // 1. If Embedding component is set, generate vector representations for documents if opts.Embedding != nil { // Extract document content texts := make([]string, len(docs)) for j, doc := range docs { texts[j] = doc.Content } // Generate vectors vectors, err := opts.Embedding.EmbedStrings(ctx, texts) if err != nil { return nil, err } // Store vectors in document's MetaData for j, doc := range docs { doc.WithVector(vectors[j]) } } // 2. Other custom logic return ids, nil } ``` -------------------------------- ### Running Dev Setup Script Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_04_tool_and_filesystem Execute the development setup script from the Eino root directory to automatically clone necessary repositories. ```bash bash scripts/dev_setup.sh ``` -------------------------------- ### Initialize ReAct Agent Source: https://www.cloudwego.io/docs/eino/core_modules/flow_integration_components/react_agent_manual Initialize a ReAct Agent with a tool-capable chat model and tool configurations. This example demonstrates the basic setup for agent creation. ```go import ( "github.com/cloudwego/eino-ext/components/model/openai" "github.com/cloudwego/eino/components/model" "github.com/cloudwego/eino/components/tool" "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/flow/agent/react" "github.com/cloudwego/eino/schema" ) func main() { // first initialize the required chatModel toolableChatModel, err := openai.NewChatModel(...) // initialize the required tools tools := compose.ToolsNodeConfig{ InvokableTools: []tool.InvokableTool{mytool}, StreamableTools: []tool.StreamableTool{myStreamTool}, } // create agent agent, err := react.NewAgent(ctx, &react.AgentConfig{ ToolCallingModel: toolableChatModel, ToolsConfig: tools, ... }) } ``` -------------------------------- ### Quick Start AgenticModel with ARK Source: https://www.cloudwego.io/docs/eino/ecosystem_integration/chat_model/agentic_model_ark A basic example demonstrating how to initialize and use the AgenticModel with ARK. Ensure ARK_API_KEY and ARK_MODEL_ID environment variables are set. ```go package main import ( "context" "log" "os" "github.com/bytedance/sonic" "github.com/cloudwego/eino-ext/components/model/agenticark" "github.com/cloudwego/eino/schema" ) func main() { ctx := context.Background() // Get ARK_API_KEY and ARK_MODEL_ID: https://www.volcengine.com/docs/82379/1399008 am, err := agenticark.New(ctx, &agenticark.Config{ Model: os.Getenv("ARK_MODEL_ID"), APIKey: os.Getenv("ARK_API_KEY"), }) if err != nil { log.Fatalf("failed to create agentic model, err: %v", err) } input := []*schema.AgenticMessage{ schema.UserAgenticMessage("what is the weather like in Beijing"), } msg, err := am.Generate(ctx, input) if err != nil { log.Fatalf("failed to generate, err: %v", err) } meta := msg.ResponseMeta.Extension.(*agenticark.ResponseMetaExtension) log.Printf("request_id: %s ", meta.ID) respBody, _ := sonic.MarshalIndent(msg, " ", " ") log.Printf(" body: %s ", string(respBody)) } ``` -------------------------------- ### Install Eino ADK Source: https://www.cloudwego.io/docs/eino/core_modules/eino_adk/agent_quickstart Install the Eino ADK using the go get command. It's recommended to use version v0.9.0 or later. ```go go get github.com/cloudwego/eino@latest ``` -------------------------------- ### Run Chat with Eino Example Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_01_chatmodel_and_message Executes the chat example using the Go run command, passing a user query as a command-line argument. This initiates a conversation with the configured chat model. ```bash go run ./cmd/ch01 -- "Explain in one sentence what problem Eino's Component design solves." ``` -------------------------------- ### Eino DevOps Main Function Example Source: https://www.cloudwego.io/docs/eino/core_modules/devops/visual_debug_plugin_guide Example main function demonstrating how to initialize the Eino devops server, register artifacts, and keep the process alive to allow debugging. ```go func main() { ctx := context.Background() // Init eino devops server err := devops.Init(ctx) if err != nil { logs.Errorf("[eino dev] init failed, err=%v", err) return } // Register chain, graph and state_graph for demo use chain.RegisterSimpleChain(ctx) graph.RegisterSimpleGraph(ctx) graph.RegisterSimpleStateGraph(ctx) // Blocking process exits sigs := make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) <-sigs // Exit logs.Infof("[eino dev] shutting down\n") } ``` -------------------------------- ### Start Chapter 9 Application Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_09_skill_console Starts the Chapter 9 application after setting the EINO_EXT_SKILLS_DIR environment variable to the location where skills were synced. This allows the skill middleware to access the skill documents. ```bash export EINO_EXT_SKILLS_DIR=/absolute/path/to/chatwitheino/skills/eino-ext go run ./cmd/ch09 ``` -------------------------------- ### Complete Stateful Graph Example in Go Source: https://www.cloudwego.io/docs/eino/core_modules/chain_and_graph_orchestration/chain_graph_introduction A comprehensive example demonstrating the creation of a stateful graph, adding nodes with stateful handlers, and defining edges. This example showcases `WithGenLocalState`, `WithStatePreHandler`, `WithStatePostHandler`, and `ProcessState`. ```go package main import ( "context" "errors" "io" "runtime/debug" "strings" "unicode/utf8" "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" "github.com/cloudwego/eino/utils/safe" "github.com/cloudwego/eino-examples/internal/logs" ) func main() { ctx := context.Background() const ( nodeOfL1 = "invokable" nodeOfL2 = "streamable" nodeOfL3 = "transformable" ) type testState struct { ms []string } gen := func(ctx context.Context) *testState { return &testState{} } sg := compose.NewGraph[string, string](compose.WithGenLocalState(gen)) l1 := compose.InvokableLambda(func(ctx context.Context, in string) (out string, err error) { return "InvokableLambda: " + in, nil }) l1StateToInput := func(ctx context.Context, in string, state *testState) (string, error) { state.ms = append(state.ms, in) return in, nil } l1StateToOutput := func(ctx context.Context, out string, state *testState) (string, error) { state.ms = append(state.ms, out) return out, nil } _ = sg.AddLambdaNode(nodeOfL1, l1, compose.WithStatePreHandler(l1StateToInput), compose.WithStatePostHandler(l1StateToOutput)) l2 := compose.StreamableLambda(func(ctx context.Context, input string) (output *schema.StreamReader[string], err error) { outStr := "StreamableLambda: " + input sr, sw := schema.Pipe[string](utf8.RuneCountInString(outStr)) // nolint: byted_goroutine_recover go func() { for _, field := range strings.Fields(outStr) { sw.Send(field+" ", nil) } sw.Close() }() return sr, nil }) l2StateToOutput := func(ctx context.Context, out string, state *testState) (string, error) { state.ms = append(state.ms, out) return out, nil } _ = sg.AddLambdaNode(nodeOfL2, l2, compose.WithStatePostHandler(l2StateToOutput)) l3 := compose.TransformableLambda(func(ctx context.Context, input *schema.StreamReader[string]) ( output *schema.StreamReader[string], err error) { prefix := "TransformableLambda: " sr, sw := schema.Pipe[string](20) go func() { defer func() { panicErr := recover() if panicErr != nil { err := safe.NewPanicErr(panicErr, debug.Stack()) logs.Errorf("panic occurs: %v\n", err) } }() for _, field := range strings.Fields(prefix) { sw.Send(field+" ", nil) } for { chunk, err := input.Recv() if err != nil { if err == io.EOF { break } // TODO: how to trace this kind of error in the goroutine of processing sw sw.Send(chunk, err) break } sw.Send(chunk, nil) } sw.Close() }() return sr, nil }) l3StateToOutput := func(ctx context.Context, out string, state *testState) (string, error) { state.ms = append(state.ms, out) logs.Infof("state result: ") for idx, m := range state.ms { logs.Infof(" %vth: %v", idx, m) } return out, nil } _ = sg.AddLambdaNode(nodeOfL3, l3, compose.WithStatePostHandler(l3StateToOutput)) _ = sg.AddEdge(compose.START, nodeOfL1) _ = sg.AddEdge(nodeOfL1, nodeOfL2) _ = sg.AddEdge(nodeOfL2, nodeOfL3) _ = sg.AddEdge(nodeOfL3, compose.END) run, err := sg.Compile(ctx) if err != nil { logs.Errorf("sg.Compile failed, err=%v", err) return } ``` -------------------------------- ### Basic Dual-Model Failover Setup Source: https://www.cloudwego.io/docs/eino/core_modules/eino_adk/agent_implementation/chat_model/chatmodel_failover_guide Demonstrates setting up a ChatModelAgent with a primary model and a single failover attempt to a backup model. ```go agent, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ Name: "my-agent", Instruction: "You are a helpful assistant.", Model: primaryModel, // model.BaseModel[*schema.Message], required ModelFailoverConfig: &adk.ModelFailoverConfig{ MaxRetries: 1, // At most 1 failover (2 calls total) ShouldFailover: func(ctx context.Context, msg *schema.Message, err error) bool { return !errors.Is(err, context.Canceled) && !errors.Is(err, context.DeadlineExceeded) }, GetFailoverModel: func(ctx context.Context, fc *adk.FailoverContext) ( model.BaseChatModel, []*schema.Message, error, ) { return fallbackModel, nil, nil // nil messages → use original input }, }, }) ``` -------------------------------- ### Complete Transformer Implementation Example Source: https://www.cloudwego.io/docs/eino/core_modules/components/document_transformer_guide Provides a full example of a custom Transformer implementation, including its constructor, the Transform method handling options and callbacks, and a private doTransform method for the core logic. ```go type MyTransformer struct { chunkSize int overlap int minChunkLength int } func NewMyTransformer(config *MyTransformerConfig) (*MyTransformer, error) { return &MyTransformer{ chunkSize: config.DefaultChunkSize, overlap: config.DefaultOverlap, minChunkLength: config.DefaultMinChunkLength, }, nil } func (t *MyTransformer) Transform(ctx context.Context, src []*schema.Document, opts ...document.TransformerOption) ([]*schema.Document, error) { // 1. Handle Options options := &MyTransformerOptions{ ChunkSize: t.chunkSize, Overlap: t.overlap, MinChunkLength: t.minChunkLength, } options = document.GetTransformerImplSpecificOptions(options, opts...) // 2. Callback before transformation starts ctx = callbacks.OnStart(ctx, info, &document.TransformerCallbackInput{ Input: src, }) // 3. Execute transformation logic docs, err := t.doTransform(ctx, src, options) // 4. Handle errors and completion callback if err != nil { ctx = callbacks.OnError(ctx, info, err) return nil, err } ctx = callbacks.OnEnd(ctx, info, &document.TransformerCallbackOutput{ Output: docs, }) return docs, nil } func (t *MyTransformer) doTransform(ctx context.Context, src []*schema.Document, opts *MyTransformerOptions) ([]*schema.Document, error) { // Implement document transformation logic return docs, nil } ``` -------------------------------- ### Initialize ChatModelAgent with Middlewares Source: https://www.cloudwego.io/docs/eino/release_notes_and_migration/eino_v0.8._-adk_middlewares Example of creating a ChatModelAgent and providing custom middleware implementations. ```go agent, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ Model: model, Handlers: []adk.ChatModelAgentMiddleware{mw1, mw2, mw3}, }) ``` -------------------------------- ### Quick Start: Initialize and Write to Local Backend Source: https://www.cloudwego.io/docs/eino/core_modules/eino_adk/eino_adk_chatmodelagentmiddleware/filesystem_backend/backend_local_filesystem Initializes the local backend and demonstrates writing content to a file. File paths must be absolute and will overwrite existing files. ```go backend, err := local.NewBackend(ctx, &local.Config{}) // Write file (must be absolute path; overwrites if file already exists) err = backend.Write(ctx, &filesystem.WriteRequest{ FilePath: "/tmp/hello.txt", Content: "Hello, Local Backend!", }) ``` -------------------------------- ### Install AgenticModel OpenAI Component Source: https://www.cloudwego.io/docs/eino/ecosystem_integration/chat_model/agentic_model_openai Install the AgenticModel OpenAI component using go get. This command fetches the latest version of the package. ```go go get github.com/cloudwego/eino-ext/components/model/agenticopenai@latest ``` -------------------------------- ### Quick Start: Create and Inject FileSystem Middleware Source: https://www.cloudwego.io/docs/eino/core_modules/eino_adk/eino_adk_chatmodelagentmiddleware/middleware_filesystem Demonstrates the basic steps to create a FileSystem middleware instance and inject it into an Eino Agent. ```go import ( "context" "github.com/cloudwego/eino/adk" "github.com/cloudwego/eino/adk/middlewares/filesystem" ) // 1. Create middleware middleware, err := filesystem.New(ctx, &filesystem.MiddlewareConfig{ Backend: myBackend, // Implements filesystem.Backend interface }) // 2. Inject into Agent agent, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ // ... Middlewares: []adk.ChatModelAgentMiddleware{middleware}, }) ``` -------------------------------- ### Registering AgenticPromptCallbackHandler Source: https://www.cloudwego.io/docs/eino/core_modules/components/agentic_chat_template_guide Example of registering a custom `AgenticPromptCallbackHandler` using a helper function to process prompt start and error events. ```go handler := callbackHelper.NewHandlerHelper(). AgenticPrompt(&callbackHelper.AgenticPromptCallbackHandler{ OnStart: func(ctx context.Context, info *callbacks.RunInfo, input *prompt.CallbackInput) context.Context { if input != nil { fmt.Printf("variables: %v\n", input.Variables) } return ctx }, OnError: func(ctx context.Context, info *callbacks.RunInfo, err error) context.Context { fmt.Printf("prompt error: %v\n", err) return ctx }, }). Handler() result, err := runnable.Invoke(ctx, variables, compose.WithCallbacks(handler)) ``` -------------------------------- ### Quick Start: Read from Local Backend with Pagination Source: https://www.cloudwego.io/docs/eino/core_modules/eino_adk/eino_adk_chatmodelagentmiddleware/filesystem_backend/backend_local_filesystem Demonstrates reading from a file using the local backend, supporting line-level pagination with offset and limit. ```go fc, err := backend.Read(ctx, &filesystem.ReadRequest{ FilePath: "/tmp/hello.txt", Offset: 1, // Starting line number (1-based) Limit: 50, // Maximum number of lines, 0 means all }) ``` -------------------------------- ### Initialize and Run Agent with Runner Source: https://www.cloudwego.io/docs/eino/core_modules/eino_adk/agent_preview Demonstrates how to initialize a Runner with optional configurations like streaming and checkpointing, and then query the agent. ```go runner := adk.NewRunner(ctx, adk.RunnerConfig{ Agent: agent, EnableStreaming: true, CheckPointStore: store, // Optional }) iter := runner.Query(ctx, "Your question") ``` -------------------------------- ### Implement Custom Callback Handler with HandlerHelper Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_06_callback_and_trace Use NewHandlerHelper to register callbacks of interest. This example shows how to log component start, end, and error events. ```go import "github.com/cloudwego/eino/callbacks" // Use NewHandlerHelper to register callbacks of interest handler := callbacks.NewHandlerHelper(). OnStart(func(ctx context.Context, info *callbacks.RunInfo, input callbacks.CallbackInput) context.Context { log.Printf("[trace] %s/%s start", info.Component, info.Name) return ctx }). OnEnd(func(ctx context.Context, info *callbacks.RunInfo, output callbacks.CallbackOutput) context.Context { log.Printf("[trace] %s/%s end", info.Component, info.Name) return ctx }). OnError(func(ctx context.Context, info *callbacks.RunInfo, err error) context.Context { log.Printf("[trace] %s/%s error: %v", info.Component, info.Name, err) return ctx }). Handler() // Register as global Callback callbacks.AppendGlobalHandlers(handler) ``` -------------------------------- ### Standard Tool Usage Example Source: https://www.cloudwego.io/docs/eino/core_modules/components/tools_node_guide Shows how to create a ToolsNode with a list of standard tools and invoke it with mock LLM output. This demonstrates the basic workflow for tool invocation. ```go import ( "github.com/cloudwego/eino/components/tool" "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" ) // Create tools node toolsNode := compose.NewToolsNode([]tool.Tool{ searchTool, // Search tool weatherTool, // Weather query tool calculatorTool, // Calculator tool }) // Mock LLM output as input input := &schema.Message{ Role: schema.Assistant, ToolCalls: []schema.ToolCall{ { Function: schema.FunctionCall{ Name: "weather", Arguments: `{"city": "Shenzhen", "date": "tomorrow"}`, }, }, }, } toolMessages, err := toolsNode.Invoke(ctx, input) ``` -------------------------------- ### ChatModel Callback Handler Example Source: https://www.cloudwego.io/docs/eino/core_modules/components/chat_model_guide Demonstrates how to create and use a callback handler for ChatModel interactions, including handling start, end, and streaming output events. ```go import ( "context" "fmt" "github.com/cloudwego/eino/callbacks" "github.com/cloudwego/eino/components/model" "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" callbacksHelper "github.com/cloudwego/eino/utils/callbacks" ) // Create callback handler handler := &callbacksHelper.ModelCallbackHandler{ OnStart: func(ctx context.Context, info *callbacks.RunInfo, input *model.CallbackInput) context.Context { fmt.Printf("Starting generation, input message count: %d\n", len(input.Messages)) return ctx }, OnEnd: func(ctx context.Context, info *callbacks.RunInfo, output *model.CallbackOutput) context.Context { fmt.Printf("Generation complete, token usage: %+v\n", output.TokenUsage) return ctx }, OnEndWithStreamOutput: func(ctx context.Context, info *callbacks.RunInfo, output *schema.StreamReader[*model.CallbackOutput]) context.Context { fmt.Println("Starting to receive streaming output") defer output.Close() for { chunk, err := output.Recv() if errors.Is(err, io.EOF) { break } if err != nil { fmt.Printf("Stream read error: %v\n", err) return } if chunk == nil || chunk.Message == nil { continue } // Only print when model output contains ToolCall if len(chunk.Message.ToolCalls) > 0 { for _, tc := range chunk.Message.ToolCalls { fmt.Printf("ToolCall detected, arguments: %s\n", tc.Function.Arguments) } } } return ctx }, } // Use callback handler helper := callbacksHelper.NewHandlerHelper(). ChatModel(handler). Handler() /*** compose a chain * chain := NewChain * chain.appendxxx(). * appendxxx(). * ... **/ // Use at runtime runnable, err := chain.Compile() if err != nil { return err } result, err := runnable.Invoke(ctx, messages, compose.WithCallbacks(helper)) ``` -------------------------------- ### Indexer Callback Handler Setup Source: https://www.cloudwego.io/docs/eino/core_modules/components/indexer_guide Defines a callback handler for an indexer, specifying actions to perform on start and end of the indexing process. This handler can be integrated into Eino's composition. ```go import ( "context" "fmt" "log" "os" "github.com/cloudwego/eino/callbacks" "github.com/cloudwego/eino/components/indexer" "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" callbacksHelper "github.com/cloudwego/eino/utils/callbacks" "github.com/cloudwego/eino-ext/components/indexer/volc_vikingdb" ) handler := &callbacksHelper.IndexerCallbackHandler{ OnStart: func(ctx context.Context, info *callbacks.RunInfo, input *indexer.CallbackInput) context.Context { log.Printf("input access, len: %v, content: %s\n", len(input.Docs), input.Docs[0].Content) return ctx }, OnEnd: func(ctx context.Context, info *callbacks.RunInfo, output *indexer.CallbackOutput) context.Context { log.Printf("output finished, len: %v, ids=%v\n", len(output.IDs), output.IDs) return ctx }, // OnError } // Use callback handler helper := callbacksHelper.NewHandlerHelper(). Indexer(handler). Handler() chain := compose.NewChain[[]*schema.Document, []string]() chain.AppendIndexer(volcIndexer) // Use at runtime run, _ := chain.Compile(ctx) outIDs, _ := run.Invoke(ctx, docs, compose.WithCallbacks(helper)) fmt.Printf("vikingDB store success, docs=%v, resp ids=%v\n", docs, outIDs) ``` -------------------------------- ### File Loader with Callback Handler Source: https://www.cloudwego.io/docs/eino/core_modules/components/document_loader_guide Example of using a custom callback handler with the FileLoader to intercept and log loading start and end events. Requires specific callback helper imports. ```go import ( "github.com/cloudwego/eino/callbacks" "github.com/cloudwego/eino/components/document" "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" callbacksHelper "github.com/cloudwego/eino/utils/callbacks" "github.com/cloudwego/eino-ext/components/document/loader/file" ) // Create callback handler handler := &callbacksHelper.LoaderCallbackHandler{ OnStart: func(ctx context.Context, info *callbacks.RunInfo, input *document.LoaderCallbackInput) context.Context { log.Printf("start loading docs...: %s\n", input.Source.URI) return ctx }, OnEnd: func(ctx context.Context, info *callbacks.RunInfo, output *document.LoaderCallbackOutput) context.Context { log.Printf("complete loading docs, total loaded docs: %d\n", len(output.Docs)) return ctx }, // OnError } // Use callback handler helper := callbacksHelper.NewHandlerHelper(). Loader(handler). Handler() chain := compose.NewChain[document.Source, []*schema.Document]() chain.AppendLoader(loader) // Use at runtime run, _ := chain.Compile(ctx) outDocs, _ := run.Invoke(ctx, document.Source{ URI: filePath, }, compose.WithCallbacks(helper)) log.Printf("doc content: %v", outDocs[0].Content) ``` -------------------------------- ### Simplified CozeLoop Tracing Setup Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_06_callback_and_trace A simplified snippet for setting up CozeLoop tracing. It initializes the client using API token and workspace ID from environment variables and registers a LoopHandler with global callbacks. This version omits the explicit logging and defer for closing the client. ```go // Setup CozeLoop tracing cozeloopApiToken := os.Getenv("COZELOOP_API_TOKEN") cozeloopWorkspaceID := os.Getenv("COZELOOP_WORKSPACE_ID") if cozeloopApiToken != "" && cozeloopWorkspaceID != "" { client, err := cozeloop.NewClient( cozeloop.WithAPIToken(cozeloopApiToken), cozeloop.WithWorkspaceID(cozeloopWorkspaceID), ) if err != nil { log.Fatalf("cozeloop.NewClient failed: %v", err) } defer func() { time.Sleep(5 * time.Second) client.Close(ctx) }() callbacks.AppendGlobalHandlers(clc.NewLoopHandler(client)) } ``` -------------------------------- ### Build and Invoke a Simple Graph in Go Source: https://www.cloudwego.io/docs/eino/core_modules/chain_and_graph_orchestration/chain_graph_introduction Defines a graph with prompt and model nodes, sets up edges, compiles the graph, and invokes it to get a result. Includes setup for direct invocation and streaming. ```Go package main import ( "context" "fmt" "io" "github.com/cloudwego/eino/components/model" "github.com/cloudwego/eino/components/prompt" "github.com/cloudwego/eino/compose" "github.com/cloudwego/eino/schema" ) const ( nodeOfModel = "model" nodeOfPrompt = "prompt" ) func main() { ctx := context.Background() g := compose.NewGraph[map[string]any, *schema.Message]() pt := prompt.FromMessages( schema.FString, schema.UserMessage("what's the weather in {location}?"), ) _ = g.AddChatTemplateNode(nodeOfPrompt, pt) _ = g.AddChatModelNode(nodeOfModel, &mockChatModel{}, compose.WithNodeName("ChatModel")) _ = g.AddEdge(compose.START, nodeOfPrompt) _ = g.AddEdge(nodeOfPrompt, nodeOfModel) _ = g.AddEdge(nodeOfModel, compose.END) r, err := g.Compile(ctx) if err != nil { panic(err) } in := map[string]any{"location": "beijing"} ret, err := r.Invoke(ctx, in) fmt.Println("invoke result: ", ret) // stream s, err := r.Stream(ctx, in) if err != nil { panic(err) } defer s.Close() for { chunk, err := s.Recv() if err != nil { if err == io.EOF { break } panic(err) } fmt.Println("stream chunk: ", chunk) } } type mockChatModel struct{} func (m *mockChatModel) Generate(ctx context.Context, input []*schema.Message, opts ...model.Option) (*schema.Message, error) { return schema.AssistantMessage("the weather is good", nil), nil } func (m *mockChatModel) Stream(ctx context.Context, input []*schema.Message, opts ...model.Option) (*schema.StreamReader[*schema.Message], error) { sr, sw := schema.Pipe[*schema.Message](0) go func() { defer sw.Close() sw.Send(schema.AssistantMessage("the weather is", nil), nil) sw.Send(schema.AssistantMessage("good", nil), nil) }() return sr, nil } func (m *mockChatModel) BindTools(tools []*schema.ToolInfo) error { panic("implement me") } ``` -------------------------------- ### Configuring Field Mapping for Data Transfer Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_08_graph_tool Demonstrates how to use FieldMapping to pass data between non-adjacent nodes or merge data sources. This example maps 'TopK' from the 'filter' node and 'Question' from the START node to the 'answer' node. ```go wf.AddLambdaNode("answer", answerFunc). AddInputWithOptions("filter", // Get data from filter node []*compose.FieldMapping{compose.ToField("TopK")}, compose.WithNoDirectDependency()). AddInputWithOptions(compose.START, // Get data from START node []*compose.FieldMapping{compose.MapFields("Question", "Question")}, compose.WithNoDirectDependency()) ``` -------------------------------- ### Run Quickstart Chat Application Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_03_memory_and_session Use these commands to run the chat application. Create a new session or resume an existing one using a session ID. ```bash # Create a new session go run ./cmd/ch03 # Resume an existing session go run ./cmd/ch03 --session ``` -------------------------------- ### Install AgenticArk Component Source: https://www.cloudwego.io/docs/eino/ecosystem_integration/chat_model/agentic_model_ark Use this command to install the latest version of the agenticark component. ```bash go get github.com/cloudwego/eino-ext/components/model/agenticark@latest ``` -------------------------------- ### Example Parameter Definition using map[string]*ParameterInfo Source: https://www.cloudwego.io/docs/eino/core_modules/components/tools_node_guide/how_to_create_a_tool Illustrates how to define a 'User' parameter using a map where keys are parameter names and values are ParameterInfo structs. ```go map[string]*schema.ParameterInfo{ "name": &schema.ParameterInfo{ Type: schema.String, Required: true, }, "age": &schema.ParameterInfo{ Type: schema.Integer, }, "gender": &schema.ParameterInfo{ Type: schema.String, Enum: []string{"male", "female"}, }, } ``` -------------------------------- ### Run ChatModelAgent Example Source: https://www.cloudwego.io/docs/eino/quick_start/chapter_02_chatmodelagent_runner_agentevent Execute the ChatModelAgent example from the command line. This demonstrates a multi-turn conversation in a console application. ```bash go run ./cmd/ch02 ``` -------------------------------- ### Usage Example: Creating and Using Middleware Skill Source: https://www.cloudwego.io/docs/eino/core_modules/eino_adk/eino_adk_chatmodelagentmiddleware/middleware_skill Demonstrates the steps to create a Backend, initialize the Middleware Skill, and pass it to a ChatModelAgent's handlers. ```go // 1. Create Backend backend, err := skill.NewBackendFromFilesystem(ctx, &skill.BackendFromFilesystemConfig{ Backend: fsBackend, BaseDir: "/path/to/skills", }) if err != nil { return err } // 2. Create Middleware handler, err := skill.NewMiddleware(ctx, &skill.Config{ Backend: backend, AgentHub: myAgentHub, // Optional, only needed for fork mode ModelHub: myModelHub, // Optional, only needed when using model field }) if err != nil { return err } // 3. Pass to Agent's Handlers agent, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{ // ... other config Handlers: []adk.ChatModelAgentMiddleware{handler}, }) ```