Skip to content

使用supervisor Agent创建的adk.Runner,内部通过tool调用sub agent后ToolCall.Function.Arguments格式错误 #786

@luweiwei

Description

@luweiwei

Describe the bug

使用supervisor Agent创建的adk.Runner,内部通过tool调用sub agent后ToolCall.Function.Arguments格式错误

Version:
v0.7.32

错误信息

panic: [NodeRunError] error generating request: error convert messages: error parsing JSON to object: invalid character 'M' looking for beginning of value
        ------------------------
        node path: [node_1, ChatModel]

goroutine 1 [running]:
main.main()
        xxx/main.go:82 +0x704
exit status 2

测试代码

package main

import (
	"ai-worker/utils"
	"bufio"
	"context"
	"fmt"
	"os"

	"github.com/cloudwego/eino-ext/components/model/ollama"
	"github.com/cloudwego/eino/adk"
	"github.com/cloudwego/eino/adk/prebuilt/supervisor"
	"github.com/cloudwego/eino/components/model"
	"github.com/cloudwego/eino/schema"
)

type transferParams struct {
	AgentName string `json:"agent_name"`
}

func main() {
	ctx := context.Background()

	model, err := newChatModel(ctx)
	if err != nil {
		panic(err)
	}

	mainAgent, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
		Name:        "MainAgent",
		Description: "An agent that can do anything",
		Model:       model,
	})
	if err != nil {
		panic(err)
	}

	subAgent, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
		Name:        "SubAgent",
		Description: "An agent that can do anything",
		Model:       model,
	})
	if err != nil {
		panic(err)
	}

	agent, err := supervisor.New(ctx, &supervisor.Config{
		Supervisor: mainAgent,
		SubAgents:  []adk.Agent{subAgent},
	})
	if err != nil {
		panic(err)
	}

	runner := adk.NewRunner(ctx, adk.RunnerConfig{
		Agent: agent,
	})

	messages := []*schema.Message{}

	for {
		input, err := getUserInput(ctx)
		if err != nil {
			panic(err)
		}
		if input == "" {
			continue
		}
		if input == "/bye" {
			break
		}
		messages = append(messages, schema.UserMessage(input))

		iter := runner.Run(ctx, messages)
		for {
			event, ok := iter.Next()
			if !ok {
				break
			}
			if event.Err != nil {
				utils.PrintAny(messages)
				panic(event.Err)
			}
			if event.Output != nil && event.Output.MessageOutput != nil {
				mo := event.Output.MessageOutput
				var msg *schema.Message
				if mo.IsStreaming {
					var printedRole bool
					for {
						chunk, err := mo.MessageStream.Recv()
						if err != nil {
							break
						}
						if !printedRole {
							fmt.Println(mo.Message.Role + ":")
							printedRole = true
						}
						fmt.Print(chunk)
					}
					msg, err = mo.GetMessage()
					if err != nil {
						panic(err)
					}
				} else {
					msg, err = mo.GetMessage()
					if err != nil {
						panic(err)
					}
					fmt.Println(mo.Message.Role + ":")
					fmt.Println(msg.Content)
				}

				// 转换ToolCall.Function.Arguments的格式,不转换就会报解析错误
				// if msg.Role == schema.Assistant {
				// 	for i, ts := range msg.ToolCalls {
				// 		if ts.Function.Name == "transfer_to_agent" {
				// 			tp := transferParams{}
				// 			err := json.Unmarshal([]byte(ts.Function.Arguments), &tp)
				// 			if err != nil {
				// 				msg.ToolCalls[i].Function.Arguments = fmt.Sprintf("{\"agent_name\":\"%s\"}", ts.Function.Arguments)
				// 			}
				// 		}
				// 	}
				// }

				messages = append(messages, msg)
			}
		}
	}

	utils.PrintAny(messages)

}

func newChatModel(ctx context.Context) (model.ToolCallingChatModel, error) {
	return ollama.NewChatModel(ctx, &ollama.ChatModelConfig{
		BaseURL: "http://localhost:11434",
		Model:   "ministral-3:3b-instruct-2512-q4_K_M",
	})
}

func getUserInput(ctx context.Context) (string, error) {
	scanner := bufio.NewScanner(os.Stdin)
	fmt.Print("user:")
	if scanner.Scan() {
		return scanner.Text(), nil
	}

	if err := scanner.Err(); err != nil {
		return "", err
	}
	return "", context.DeadlineExceeded
}

传递的essages

[{"role":"user","content":"呼叫SubAgent"},{"role":"assistant","content":"","tool_calls":[{"id":"","type":"function","function":{"name":"transfer_to_agent","arguments":"{\"agent_name\":\"SubAgent\"}"}}],"response_meta":{"finish_reason":"stop","usage":{"prompt_tokens":147,"prompt_token_details":{"cached_tokens":0},"completion_tokens":14,"total_tokens":161,"completion_token_details":{}}}},{"role":"tool","content":"successfully transferred to agent [SubAgent]","tool_name":"transfer_to_agent"},{"role":"assistant","content":"理解!现在我将以**SubAgent**的身份开始处理任务。请告诉我下一步的具体要求或问题,我将专注于提供准确、详细的回复。\n\n**当前状态**:\n- 已切换至**SubAgent**模式。\n- 可处理实时2026年2月10日(或相关时间)的信息。\n- 无法访问互联网或图片/音频等多模态功能。\n\n请确认您的需求,例如:\n- 需要查询最新数据(如股票、天气、新闻等)?\n- 需要解决具体问题(如计算、逻辑推理)?\n- 需要翻译或文本分析?","response_meta":{"finish_reason":"stop","usage":{"prompt_tokens":608,"prompt_token_details":{"cached_tokens":0},"completion_tokens":186,"total_tokens":794,"completion_token_details":{}}}},{"role":"assistant","content":"","tool_calls":[{"id":"ac565622-cfbd-4437-8486-3cec3f8be949","type":"","function":{"name":"transfer_to_agent","arguments":"MainAgent"}}]},{"role":"tool","content":"successfully transferred to agent [MainAgent]","tool_call_id":"ac565622-cfbd-4437-8486-3cec3f8be949","tool_name":"transfer_to_agent"},{"role":"assistant","content":"我已将问题转交给**MainAgent**处理。请等待其回复!","response_meta":{"finish_reason":"stop","usage":{"prompt_tokens":414,"prompt_token_details":{"cached_tokens":0},"completion_tokens":22,"total_tokens":436,"completion_token_details":{}}}},{"role":"user","content":"你好"}]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions