### Run tRPC-Agent-Go Tool Examples Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Provides commands to navigate to example directories and run the tool and MCP tool examples. It also shows how to start an external server for the streamable server example. ```bash # 进入工具示例目录 cd examples/tool go run . # 进入 MCP 工具示例目录 cd examples/mcp_tool # 启动外部服务器 cd streamalbe_server && go run main.go & # 运行主程序 go run main.go -model="deepseek-chat" ``` -------------------------------- ### Create and Start A2A Server with Agent Source: https://trpc-group.github.io/trpc-agent-go/zh/a2a?q= This example demonstrates how to create a local agent and expose it as an A2A service using the A2A Server. It configures the server to listen on a specific host and port, and enables streaming capabilities. ```go package main import ( "trpc.group/trpc-go/trpc-agent-go/agent/llmagent" "trpc.group/trpc-go/trpc-agent-go/model/openai" a2aserver "trpc.group/trpc-go/trpc-agent-go/server/a2a" ) func main() { // 1. 创建一个普通的 Agent model := openai.New("gpt-4o-mini") agent := llmagent.New("MyAgent", llmagent.WithModel(model), llmagent.WithDescription("一个智能助手"), ) // 2. 一键转换为 A2A 服务 server, _ := a2aserver.New( a2aserver.WithHost("localhost:8080"), a2aserver.WithAgent(agent, true), // 开启 streaming ) // 3. 启动服务,即可接受 A2A 请求 server.Start(":8080") } ``` -------------------------------- ### Run Example with `runner-card` mode Source: https://trpc-group.github.io/trpc-agent-go/zh/a2a?q= Switch to the `WithRunner(...) + WithAgentCard(...)` server construction method by running the example with the `-server-mode runner-card` flag. ```bash cd examples/a2aagent go run . -server-mode runner-card ``` -------------------------------- ### Run A2A Server and A2AAgent in One Program Source: https://trpc-group.github.io/trpc-agent-go/zh/a2a?q= This example shows how to simultaneously run an A2A Server to expose a local agent and an A2AAgent to call a remote service within the same Go program. It includes creating and starting the server, initializing the agent, and comparing responses from local and remote agents. ```go package main import ( "context" "fmt" "time" "trpc.group/trpc-go/trpc-agent-go/agent/a2aagent" "trpc.group/trpc-go/trpc-agent-go/agent/llmagent" "trpc.group/trpc-go/trpc-agent-go/model/openai" "trpc.group/trpc-go/trpc-agent-go/runner" "trpc.group/trpc-go/trpc-agent-go/server/a2a" "trpc.group/trpc-go/trpc-agent-go/session/inmemory" ) func main() { // 1. 创建并启动远程 Agent 服务 remoteAgent := createRemoteAgent() startA2AServer(remoteAgent, "localhost:8888") time.Sleep(1 * time.Second) // 等待服务启动 // 2. 创建 A2AAgent 连接到远程服务 a2aAgent, err := a2aagent.New( a2aagent.WithAgentCardURL("http://localhost:8888"), a2aagent.WithTransferStateKey("user_context"), ) if err != nil { panic(err) } // 3. 创建本地 Agent localAgent := createLocalAgent() // 4. 对比本地和远程 Agent 的响应 compareAgents(localAgent, a2aAgent) } func createRemoteAgent() agent.Agent { model := openai.New("gpt-4o-mini") return llmagent.New("JokeAgent", llmagent.WithModel(model), llmagent.WithDescription("I am a joke-telling agent"), llmagent.WithInstruction("Always respond with a funny joke"), ) } func createLocalAgent() agent.Agent { model := openai.New("gpt-4o-mini") return llmagent.New("LocalAgent", llmagent.WithModel(model), llmagent.WithDescription("I am a local assistant"), ) } func startA2AServer(agent agent.Agent, host string) { server, err := a2a.New( a2a.WithHost(host), a2a.WithAgent(agent, true), // 启用流式 ) if err != nil { panic(err) } go func() { server.Start(host) }() } func compareAgents(localAgent, remoteAgent agent.Agent) { sessionService := inmemory.NewSessionService() localRunner := runner.NewRunner("local", localAgent, runner.WithSessionService(sessionService)) remoteRunner := runner.NewRunner("remote", remoteAgent, runner.WithSessionService(sessionService)) userMessage := "请帮我讲个笑话" // 调用本地 Agent fmt.Println("=== Local Agent Response ===") processAgent(localRunner, userMessage) // 调用远程 Agent (通过 A2AAgent) fmt.Println("\n=== Remote Agent Response (via A2AAgent) ===") processAgent(remoteRunner, userMessage) } func processAgent(runner runner.Runner, message string) { events, err := runner.Run( context.Background(), "user1", "session1", model.NewUserMessage(message), agent.WithRuntimeState(map[string]any{ "user_context": "test_context", }), ) if err != nil { fmt.Printf("Error: %v\n", err) return } for event := range events { if event.Response != nil && len(event.Response.Choices) > 0 { content := event.Response.Choices[0].Message.Content if content == "" { content = event.Response.Choices[0].Delta.Content } if content != "" { fmt.Print(content) } } } fmt.Println() } ``` -------------------------------- ### Multi-Agent Collaboration Example Source: https://trpc-group.github.io/trpc-agent-go/zh?q= Illustrates setting up a chain of agents to work collaboratively on a task. This example shows how to create a chain agent composed of sub-agents (e.g., analysis and execution agents) and then use a runner to execute tasks across these agents. ```Go // 创建链式 Agent chainAgent := chainagent.New("problem-solver", chainagent.WithSubAgents([]agent.Agent{ analysisAgent, // 分析 Agent executionAgent, // 执行 Agent })) // 使用 Runner 执行 runner := runner.NewRunner("multi-agent-app", chainAgent) events, _ := runner.Run(ctx, userID, sessionID, message) ``` -------------------------------- ### Configure Member Tool Settings for a Coordinator Team Source: https://trpc-group.github.io/trpc-agent-go/zh/team This example shows how to customize the behavior of members when they are presented as tools to a coordinator team. It starts with default settings and then modifies stream inner, inner text mode, history scope, and summarization skipping. ```go memberCfg := team.DefaultMemberToolConfig() memberCfg.StreamInner = true memberCfg.InnerTextMode = team.InnerTextModeExclude memberCfg.HistoryScope = team.HistoryScopeParentBranch memberCfg.SkipSummarization = false tm, err := team.New( coordinator, members, team.WithMemberToolConfig(memberCfg), ) ``` -------------------------------- ### Implement and Use a Streamable Weather Tool in Go Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Define input/output structures, implement a function that returns a stream of weather data, and create a streamable function tool. This example shows how to call the tool and process the streamed chunks. ```go type weatherInput struct { Location string `json:"location" jsonschema:"description=查询地点,例如城市名或经纬度" } type weatherOutput struct { Weather string `json:"weather" } // 2. 实现流式工具函数 func getStreamableWeather(input weatherInput) *tool.StreamReader { stream := tool.NewStream(10) go func() { defer stream.Writer.Close() // 模拟逐步返回天气数据 result := "Sunny, 25°C in " + input.Location for i := 0; i < len(result); i++ { chunk := tool.StreamChunk{ Content: weatherOutput{ Weather: result[i : i+1], }, Metadata: tool.Metadata{CreatedAt: time.Now()}, } if closed := stream.Writer.Send(chunk, nil); closed { break } time.Sleep(10 * time.Millisecond) // 模拟延迟 } }() return stream.Reader } // 3. 创建流式工具 weatherStreamTool := function.NewStreamableFunctionTool[weatherInput, weatherOutput]( getStreamableWeather, function.WithName("get_weather_stream"), function.WithDescription("流式获取天气信息"), ) // 4. 使用流式工具 reader, err := weatherStreamTool.StreamableCall(ctx, jsonArgs) if err != nil { return err } // 接收流式数据 for { chunk, err := reader.Recv() if err == io.EOF { break // 流结束 } if err != nil { return err } // 处理每个数据块 fmt.Printf("收到数据: %v\n", chunk.Content) } reader.Close() ``` -------------------------------- ### MCP Server Description Example Source: https://trpc-group.github.io/trpc-agent-go/zh/tool This JSON shows the structure of the response from `mcp_list_servers`, including the optional `description` field for each server. This description helps the model decide which server to explore first, similar to OpenAI's tool namespace descriptions. ```json { "servers": [ { "name": "local_stdio_code", "transport": "stdio", "description": "Project management, documentation, and calendar tools." } ] } ``` -------------------------------- ### Call Remote A2A Service Using A2A Client Source: https://trpc-group.github.io/trpc-agent-go/zh/a2a?q= This example demonstrates how to use the A2A client to connect to a remote A2A service and send a message to an agent. The agent automatically processes the message and returns a response. ```go import ( "trpc.group/trpc-go/trpc-a2a-go/client" "trpc.group/trpc-go/trpc-a2a-go/protocol" ) func main() { // 连接到 A2A 服务 client, _ := client.NewA2AClient("http://localhost:8080/") // 发送消息给 Agent message := protocol.NewMessage( protocol.MessageRoleUser, []protocol.Part{protocol.NewTextPart("你好,请帮我分析这段代码")}, ) // Agent 会自动处理并返回结果 response, _ := client.SendMessage(context.Background(), protocol.SendMessageParams{Message: message}) } ``` -------------------------------- ### Create Nested Teams with trpc-agent-go Source: https://trpc-group.github.io/trpc-agent-go/zh/team This example demonstrates creating a nested team structure where a 'dev_team' is a member of a 'project_manager' team. It initializes individual agents, groups them into a 'dev_team', and then includes this 'dev_team' as a member of the outer 'pmTeam'. ```go import ( "trpc.group/trpc-go/trpc-agent-go/agent" "trpc.group/trpc-go/trpc-agent-go/agent/llmagent" "trpc.group/trpc-go/trpc-agent-go/model/openai" "trpc.group/trpc-go/trpc-agent-go/runner" "trpc.group/trpc-go/trpc-agent-go/team" ) modelInstance := openai.New("deepseek-chat") backendDev := llmagent.New( "backend_dev", llmagent.WithModel(modelInstance), llmagent.WithInstruction("Design service interfaces and server-side logic."), ) frontendDev := llmagent.New( "frontend_dev", llmagent.WithModel(modelInstance), llmagent.WithInstruction("Design user interfaces and client-side logic."), ) devCoordinator := llmagent.New( "dev_team", llmagent.WithModel(modelInstance), llmagent.WithInstruction( "You lead dev_team. Collect input from your members when needed, "+ "then return an integrated technical plan.", ), ) devTeam, err := team.New( devCoordinator, []agent.Agent{backendDev, frontendDev}, ) if err != nil { panic(err) } docWriter := llmagent.New( "doc_writer", llmagent.WithModel(modelInstance), llmagent.WithInstruction("Write clear documentation."), ) pmCoordinator := llmagent.New( "project_manager", llmagent.WithModel(modelInstance), llmagent.WithInstruction( "You are the project manager. Delegate technical work to dev_team "+ "and docs to doc_writer, then produce the final answer.", ), ) pmTeam, err := team.New( pmCoordinator, []agent.Agent{devTeam, docWriter}, // devTeam is a Team. ) if err != nil { panic(err) } r := runner.NewRunner("app", pmTeam) _ = r ``` -------------------------------- ### Basic LLM Agent Usage with Tool Source: https://trpc-group.github.io/trpc-agent-go/zh?q= Demonstrates how to create an LLM agent, define a custom tool (calculator), and run a conversation with the agent. It shows setting up the model, tool, generation configuration, agent, and runner, then processing the event stream for responses. Ensure the custom tool function and its request/response types are defined. ```Go package main import ( "context" "fmt" "log" "trpc.group/trpc-go/trpc-agent-go/agent/llmagent" "trpc.group/trpc-go/trpc-agent-go/model" "trpc.group/trpc-go/trpc-agent-go/model/openai" "trpc.group/trpc-go/trpc-agent-go/runner" "trpc.group/trpc-go/trpc-agent-go/tool" "trpc.group/trpc-go/trpc-agent-go/tool/function" ) func main() { // 创建模型 modelInstance := openai.New("deepseek-chat") // 创建工具 calculatorTool := function.NewFunctionTool( calculator, function.WithName("calculator"), function.WithDescription("执行加减乘除。参数:a、b 为数值,op 取值 add/sub/mul/div;返回 result 为计算结果。"), ) // 启用流式输出 genConfig := model.GenerationConfig{ Stream: true, } // 创建 Agent agent := llmagent.New("assistant", llmagent.WithModel(modelInstance), llmagent.WithTools([]tool.Tool{calculatorTool}), llmagent.WithGenerationConfig(genConfig), ) // 创建 Runner runner := runner.NewRunner("calculator-app", agent) // 执行对话 ctx := context.Background() events, err := runner.Run(ctx, "user-001", "session-001", model.NewUserMessage("计算 2+3 等于多少"), ) if err != nil { log.Fatal(err) } // 处理事件流 for event := range events { if event.Object == "chat.completion.chunk" { fmt.Print(event.Response.Choices[0].Delta.Content) } } fmt.Println() } func calculator(ctx context.Context, req calculatorReq) (calculatorRsp, error) { var result float64 switch req.Op { case "add", "+": result = req.A + req.B case "sub", "-": result = req.A - req.B case "mul", "*": result = req.A * req.B case "div", "/": result = req.A / req.B } return calculatorRsp{Result: result}, nil } type calculatorReq struct { A float64 `json:"a"` B float64 `json:"b"` Op string `json:"op"` } type calculatorRsp struct { Result float64 `json:"result"` } ``` -------------------------------- ### Initialize Knowledge Search with ToolKnowledge Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Set up Knowledge Search by creating a `ToolKnowledge` instance with an embedder and vector store, then passing it to `toolsearch.New`. ```go import ( "trpc.group/trpc-go/trpc-agent-go/plugin/toolsearch" openaiembedder "trpc.group/trpc-go/trpc-agent-go/knowledge/embedder/openai" vectorinmemory "trpc.group/trpc-go/trpc-agent-go/knowledge/vectorstore/inmemory" ) toolKnowledge, err := toolsearch.NewToolKnowledge( openaiembedder.New(openaiembedder.WithModel(openaiembedder.ModelTextEmbedding3Small)), toolsearch.WithVectorStore(vectorinmemory.New()), ) if err != nil { /* handle */ } tc, err := toolsearch.New(modelInstance, toolsearch.WithMaxTools(3), toolsearch.WithToolKnowledge(toolKnowledge), toolsearch.WithFailOpen(), ) if err != nil { /* handle */ } modelCallbacks.RegisterBeforeModel(tc.Callback()) ``` -------------------------------- ### Create a Coordinator Team with Agents Source: https://trpc-group.github.io/trpc-agent-go/zh/team This snippet demonstrates setting up a Coordinator Team. It initializes a model instance, creates specialized agents (coder, reviewer), and a coordinator agent. The team is then formed with the coordinator and its members, and a runner is created for the team. ```go import ( "trpc.group/trpc-go/trpc-agent-go/agent" "trpc.group/trpc-go/trpc-agent-go/agent/llmagent" "trpc.group/trpc-go/trpc-agent-go/model/openai" "trpc.group/trpc-go/trpc-agent-go/runner" "trpc.group/trpc-go/trpc-agent-go/team" ) modelInstance := openai.New("deepseek-chat") coder := llmagent.New( "coder", llmagent.WithModel(modelInstance), llmagent.WithInstruction("Write Go code."), ) reviewer := llmagent.New( "reviewer", llmagent.WithModel(modelInstance), llmagent.WithInstruction("Review for correctness."), ) coordinator := llmagent.New( "team", llmagent.WithModel(modelInstance), llmagent.WithInstruction( "You are the coordinator. Consult the right specialists, "+ "then produce the final answer.", ), ) tm, err := team.New( coordinator, []agent.Agent{coder, reviewer}, team.WithDescription("A tiny coordinator team"), ) if err != nil { panic(err) } r := runner.NewRunner("app", tm) _ = r ``` -------------------------------- ### Pass Authentication Token in A2A Request Header Source: https://trpc-group.github.io/trpc-agent-go/zh/a2a?q= Example of passing an authentication token using the Authorization header within A2A requests. ```go agent.WithA2ARequestOptions( client.WithRequestHeader("Authorization", "Bearer "+token), ) ``` -------------------------------- ### Create and Use a Simple Calculator Function Tool in Go Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Demonstrates how to define a custom function tool for simple calculations (add, multiply) and integrate it with an LLM agent. Ensure the necessary packages are imported. ```go package main import ( "context" "fmt" "trpc.group/trpc-go/trpc-agent-go/runner" "trpc.group/trpc-go/trpc-agent-go/agent/llmagent" "trpc.group/trpc-go/trpc-agent-go/model/openai" "trpc.group/trpc-go/trpc-agent-go/model" "trpc.group/trpc-go/trpc-agent-go/tool/function" ) func main() { // 1. 创建简单工具 calculatorTool := function.NewFunctionTool( func(ctx context.Context, req struct { Operation string `json:"operation" jsonschema:"description=运算类型,例如 add/multiply"` A float64 `json:"a" jsonschema:"description=第一个操作数"` B float64 `json:"b" jsonschema:"description=第二个操作数"` }) (map[string]interface{}, error) { var result float64 switch req.Operation { case "add": result = req.A + req.B case "multiply": result = req.A * req.B default: return nil, fmt.Errorf("unsupported operation") } return map[string]interface{}{"result": result}, nil }, function.WithName("calculator"), function.WithDescription("简单计算器"), ) // 2. 创建模型和 Agent llmModel := openai.New("DeepSeek-V3-Online-64K") agent := llmagent.New("calculator-assistant", llmagent.WithModel(llmModel), llmagent.WithInstruction("你是一个数学助手"), llmagent.WithTools([]tool.Tool{calculatorTool}), llmagent.WithGenerationConfig(model.GenerationConfig{Stream: true}), // 启用流式输出 ) // 3. 创建 Runner 并执行 r := runner.NewRunner("math-app", agent) ctx := context.Background() userMessage := model.NewUserMessage("请计算 25 乘以 4") eventChan, err := r.Run(ctx, "user1", "session1", userMessage) if err != nil { panic(err) } // 4. 处理响应 for event := range eventChan { if event.Error != nil { fmt.Printf("错误: %s\n", event.Error.Message) continue } // 显示工具调用 if len(event.Response.Choices) > 0 && len(event.Response.Choices[0].Message.ToolCalls) > 0 { for _, toolCall := range event.Response.Choices[0].Message.ToolCalls { fmt.Printf("🔧 调用工具: %s\n", toolCall.Function.Name) fmt.Printf(" 参数: %s\n", string(toolCall.Function.Arguments)) } } // 显示流式内容 if len(event.Response.Choices) > 0 { fmt.Print(event.Response.Choices[0].Delta.Content) } if event.Done { break } } } ``` -------------------------------- ### Create and Integrate Function Tool Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Demonstrates how to define a calculator function, create a Function Tool using 'function.NewFunctionTool', and integrate it into an Agent. ```go import "trpc.group/trpc-go/trpc-agent-go/tool/function" // 1. 定义工具函数 func calculator(ctx context.Context, req struct { Operation string `json:"operation" jsonschema:"description=运算类型,例如 add/multiply"` A float64 `json:"a" jsonschema:"description=第一个操作数"` B float64 `json:"b" jsonschema:"description=第二个操作数"` }) (map[string]interface{}, error) { switch req.Operation { case "add": return map[string]interface{}{"result": req.A + req.B}, nil case "multiply": return map[string]interface{}{"result": req.A * req.B}, nil default: return nil, fmt.Errorf("unsupported operation: %s", req.Operation) } } // 2. 创建工具 calculatorTool := function.NewFunctionTool( calculator, function.WithName("calculator"), function.WithDescription("执行数学运算"), ) // 3. 集成到 Agent agent := llmagent.New("math-assistant", llmagent.WithModel(model), llmagent.WithTools([]tool.Tool{calculatorTool})) ``` -------------------------------- ### Exclude Specific Tools with Blacklist Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Use NewExcludeToolNamesFilter to prevent specific tools from being used by the agent. This is useful for security or to guide the agent's behavior. ```go import "trpc.group/trpc-go/trpc-agent-go/tool" // 排除 text_tool,其他工具都可用 filter := tool.NewExcludeToolNamesFilter("text_tool", "dangerous_tool") eventChan, err := runner.Run(ctx, userID, sessionID, message, agent.WithToolFilter(filter), ) ``` -------------------------------- ### Create and Initialize MCP ToolSet with STDIO Transport Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Demonstrates creating an MCP ToolSet for STDIO transport, specifying the command and arguments to execute. It includes optional tool filtering and explicit initialization. ```go import "trpc.group/trpc-go/trpc-agent-go/tool/mcp" // 创建 MCP 工具集(以 STDIO 为例) mcpToolSet := mcp.NewMCPToolSet( mcp.ConnectionConfig{ Transport: "stdio", // 传输方式 Command: "go", // 执行命令 Args: []string{"run", "./stdio_server/main.go"}, Timeout: 10 * time.Second, }, mcp.WithToolFilterFunc(tool.NewIncludeToolNamesFilter("echo", "add")), ) // (可选但推荐)显式初始化 MCP:建立连接 + 初始化会话 + 列工具 if err := mcpToolSet.Init(ctx); err != nil { log.Fatalf("初始化 MCP 工具集失败: %v", err) } // 集成到 Agent agent := llmagent.New("mcp-assistant", llmagent.WithModel(model), llmagent.WithToolSets([]tool.ToolSet{mcpToolSet})) ``` -------------------------------- ### Initialize Swarm with Entrypoint and Members Source: https://trpc-group.github.io/trpc-agent-go/zh/team Initialize a new Swarm team with a specified entrypoint member and a list of agents. The entrypoint must be present in the members list and support SetSubAgents. ```go tm, err := team.NewSwarm( "team", "researcher", // entrypoint(入口)成员名称 []agent.Agent{coder, researcher, reviewer}, ) if err != nil { panic(err) } ``` -------------------------------- ### Non-Streaming Request with Tool Call Source: https://trpc-group.github.io/trpc-agent-go/zh/a2a-interaction?q= This is an example of a non-streaming HTTP POST request to the tRPC agent. It includes user ID and trace context in headers, and a message with a text part in the JSON body. The metadata specifies client capabilities and user information. ```http POST / HTTP/1.1 Host: agent.example.com Content-Type: application/json X-User-ID: user_12345 traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01 { "jsonrpc": "2.0", "id": "req-001", "method": "message/send", "params": { "message": { "kind": "message", "messageId": "msg-001", "role": "user", "contextId": "ctx-001", "parts": [ { "kind": "text", "text": "北京天气如何?" } ], "metadata": { "interaction_spec_version": "0.1", "invocation_id": "inv-001", "user_id": "user_12345" } } } } ``` -------------------------------- ### Non-Streaming Response with Tool Call and Result Source: https://trpc-group.github.io/trpc-agent-go/zh/a2a-interaction?q= This is an example of a non-streaming HTTP 200 OK response from the tRPC agent. It includes a task ID, context ID, and status. The response details a tool call to 'get_weather' and its subsequent result, followed by a final text artifact with the answer. ```http HTTP/1.1 200 OK Content-Type: application/json { "jsonrpc": "2.0", "id": "req-001", "result": { "id": "task-001", "contextId": "ctx-001", "status": { "state": "completed", "timestamp": "2025-01-23T10:30:00Z" }, "history": [ { "kind": "message", "messageId": "msg-tool-call", "role": "agent", "parts": [ { "kind": "data", "data": { "id": "call_001", "type": "function", "name": "get_weather", "args": "{\"city\":\"Beijing\"}" }, "metadata": { "type": "function_call" } } ], "metadata": { "object_type": "chat.completion", "tag": "", "llm_response_id": "chatcmpl-abc123" } }, { "kind": "message", "messageId": "msg-tool-resp", "role": "agent", "parts": [ { "kind": "data", "data": { "id": "call_001", "name": "get_weather", "response": "{\"temp\":\"20°C\",\"condition\":\"sunny\"}" }, "metadata": { "type": "function_response" } } ], "metadata": { "object_type": "tool.response", "tag": "", "llm_response_id": "chatcmpl-abc123" } } ], "artifacts": [ { "artifactId": "msg-final", "parts": [ { "kind": "text", "text": "北京当前气温20°C,天气晴朗。" } ] } ] } } ``` -------------------------------- ### Initialize Tool Search as Runner Plugin Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Use this to initialize Tool Search as a plugin for the runner. It allows specifying the maximum number of tools to select and an option to fail open if search fails. ```go import ( "trpc.group/trpc-go/trpc-agent-go/agent/llmagent" "trpc.group/trpc-go/trpc-agent-go/plugin/toolsearch" "trpc.group/trpc-go/trpc-agent-go/runner" ) ts, err := toolsearch.New(modelInstance, toolsearch.WithMaxTools(3), toolsearch.WithFailOpen(), // 可选:search 失败时退回到“全部工具可用” ) if err != nil { /* handle */ } ag := llmagent.New("assistant", llmagent.WithModel(modelInstance), llmagent.WithTools(allTools), // 仍然注册“全量工具”,Tool Search 会挑 TopK ) r := runner.NewRunner("app", ag, runner.WithPlugins(ts), ) ``` -------------------------------- ### Initialize MCP Broker for On-Demand Discovery Source: https://trpc-group.github.io/trpc-agent-go/zh/tool This code initializes an MCP Broker, which exposes a limited set of broker tools initially. The LLMAgent can then discover and call remote MCP capabilities on demand. This is suitable for scenarios with many long-tail tools or when reducing initial context pressure is desired. It supports both stdio and ad-hoc HTTP connections. ```go import ( "time" "trpc.group/trpc-go/trpc-agent-go/agent/llmagent" "trpc.group/trpc-go/trpc-agent-go/tool/mcp" "trpc.group/trpc-go/trpc-agent-go/tool/mcpbroker" ) broker := mcpbroker.New( mcpbroker.WithServers(map[string]mcp.ConnectionConfig{ "local_stdio_code": { Transport: "stdio", Command: "go", Args: []string{"run", "./stdio_server/main.go"}, Timeout: 10 * time.Second, Description: "Project management, documentation, and calendar tools.", }, }), mcpbroker.WithAllowAdHocHTTP(true), ) agent := llmagent.New( "assistant", llmagent.WithModel(model), llmagent.WithTools(broker.Tools()), ) ``` -------------------------------- ### Create Agent with Integrated Tools Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Create an AI agent and integrate various tools including function tools, built-in tools, and MCP tool sets with different transport configurations. ```go import ( "trpc.group/trpc-go/trpc-agent-go/agent/llmagent" "trpc.group/trpc-go/trpc-agent-go/tool" "trpc.group/trpc-go/trpc-agent-go/tool/function" "trpc.group/trpc-go/trpc-agent-go/tool/duckduckgo" "trpc.group/trpc-go/trpc-agent-go/tool/mcp" ) // 创建函数工具 calculatorTool := function.NewFunctionTool(calculator, function.WithName("calculator"), function.WithDescription("执行基础数学运算")) timeTool := function.NewFunctionTool(getCurrentTime, function.WithName("current_time"), function.WithDescription("获取当前时间")) // 创建内置工具 searchTool := duckduckgo.NewTool() // 创建 MCP 工具集(不同传输方式的示例) stdioToolSet := mcp.NewMCPToolSet( mcp.ConnectionConfig{ Transport: "stdio", Command: "python", Args: []string{"-m", "my_mcp_server"}, Timeout: 10 * time.Second, }, ) sseToolSet := mcp.NewMCPToolSet( mcp.ConnectionConfig{ Transport: "sse", ServerURL: "http://localhost:8080/sse", Timeout: 10 * time.Second, }, ) streamableToolSet := mcp.NewMCPToolSet( mcp.ConnectionConfig{ Transport: "streamable_http", ServerURL: "http://localhost:3000/mcp", Timeout: 10 * time.Second, }, ) // 创建 Agent 并集成所有工具 agent := llmagent.New("ai-assistant", llmagent.WithModel(model), llmagent.WithInstruction("你是一个有帮助的AI助手,可以使用多种工具协助用户"), // 添加单个工具(Tool 接口) llmagent.WithTools([]tool.Tool{ calculatorTool, timeTool, searchTool, }), // 添加工具集(ToolSet 接口) llmagent.WithToolSets([]tool.ToolSet{ stdioToolSet, sseToolSet, streamableToolSet, }), ) ``` -------------------------------- ### Initialize mcpbroker with AdHoc HTTP enabled Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Enable ad-hoc HTTP MCP connections by setting WithAllowAdHocHTTP to true. In production, validate URLs in the business logic before using ad-hoc HTTP. ```go broker := mcpbroker.New( mcpbroker.WithAllowAdHocHTTP(true), ) ``` -------------------------------- ### Initialize MCP ToolSet with SSE Transport Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Sets up an MCP ToolSet using Server-Sent Events (SSE) transport, including the server URL and authorization headers. Initialization is required to establish the connection. ```go mcpToolSet := mcp.NewMCPToolSet( mcp.ConnectionConfig{ Transport: "sse", ServerURL: "http://localhost:8080/sse", Timeout: 10 * time.Second, Headers: map[string]string{ "Authorization": "Bearer your-token", }, }, ) if err := mcpToolSet.Init(ctx); err != nil { return fmt.Errorf("初始化 SSE MCP 工具集失败: %w", err) } ``` -------------------------------- ### Create LLMAgent with Auto-Refreshing MCP ToolSet Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Use this to create an LLMAgent that automatically refreshes its tool list before each run. This is useful when the remote MCP server might add or remove tools dynamically. The agent uses context from the current execution for refreshing. ```go import ( "trpc.group/trpc-go/trpc-agent-go/agent/llmagent" "trpc.group/trpc-go/trpc-agent-go/model/openai" "trpc.group/trpc-go/trpc-agent-go/tool" "trpc.group/trpc-go/trpc-agent-go/tool/mcp" ) // 1. 创建 MCP 工具集(可以是 STDIO、SSE 或 Streamable HTTP) mcpToolSet := mcp.NewMCPToolSet(connectionConfig) // 2. 创建 LLMAgent,并开启 ToolSets 的自动刷新 agent := llmagent.New( "mcp-assistant", llmagent.WithModel(openai.New("gpt-4o-mini")), llmagent.WithToolSets([]tool.ToolSet{mcpToolSet}), llmagent.WithRefreshToolSetsOnRun(true), ) ``` -------------------------------- ### Handling Cross-Turn Follow-ups with await_user_reply Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Enable the await_user_reply tool to manage multi-turn conversations where an agent needs to ask clarifying questions. This requires pairing llmagent.WithAwaitUserReplyTool(true) with runner.WithAwaitUserReplyRouting(true). ```go profileAgent := llmagent.New("profile-agent", llmagent.WithAwaitUserReplyTool(true), llmagent.WithInstruction(` 如果你必须向用户补一个缺失字段,先调用 await_user_reply, 再提出问题。 `), ) r := runner.NewRunner( "crm-app", profileAgent, runner.WithAwaitUserReplyRouting(true), ) ``` -------------------------------- ### Basic Claude Code ToolSet Initialization Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Initialize the Claude Code ToolSet, specifying the base directory for file operations and command execution. Ensure proper error handling and defer closing the toolset. ```go import ( "log" "trpc.group/trpc-go/trpc-agent-go/agent/llmagent" "trpc.group/trpc-go/trpc-agent-go/tool" "trpc.group/trpc-go/trpc-agent-go/tool/claudecode" ) toolSet, err := claudecode.NewToolSet( claudecode.WithBaseDir("."), ) if err != nil { log.Fatal(err) } defer toolSet.Close() agent := llmagent.New( "claude-style-agent", llmagent.WithToolSets([]tool.ToolSet{toolSet}), ) ``` -------------------------------- ### Create and use an AgentTool for a sub-agent Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Wrap a sub-agent as a tool for a parent agent. Configure options like skipping summarization and streaming inner events from the sub-agent to the parent. ```go import ( "trpc.group/trpc-go/trpc-agent-go/agent/llmagent" "trpc.group/trpc-go/trpc-agent-go/model" "trpc.group/trpc-go/trpc-agent-go/tool" agenttool "trpc.group/trpc-go/trpc-agent-go/tool/agent" ) // 1) 定义一个可复用的子 Agent(可配置为流式) mathAgent := llmagent.New( "math-specialist", llmagent.WithModel(modelInstance), llmagent.WithInstruction("你是数学专家..."), llmagent.WithGenerationConfig(model.GenerationConfig{Stream: true}), ) // 2) 包装为 Agent 工具 mathTool := agenttool.NewTool( mathAgent, agenttool.WithSkipSummarization(false), // 可选,默认 false,当设置为 true 时会跳过外层模型总结,在 tool.response 后直接结束本轮 agenttool.WithStreamInner(true), // 开启:把子 Agent 的流式事件转发给父流程 agenttool.WithInnerTextMode(agenttool.InnerTextModeExclude), // 隐藏子 Agent 正文,仅保留内部进度 ) // 3) 在父 Agent 中使用该工具 parent := llmagent.New( "assistant", llmagent.WithModel(modelInstance), llmagent.WithGenerationConfig(model.GenerationConfig{Stream: true}), llmagent.WithTools([]tool.Tool{mathTool}), ) ``` -------------------------------- ### Initialize MCP ToolSet with Streamable HTTP Transport Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Configures an MCP ToolSet for streamable HTTP communication, specifying the server URL and timeout. The 'streamable_http' transport must be used. ```go mcpToolSet := mcp.NewMCPToolSet( mcp.ConnectionConfig{ Transport: "streamable_http", // 注意:使用完整名称 ServerURL: "http://localhost:3000/mcp", Timeout: 10 * time.Second, }, ) if err := mcpToolSet.Init(ctx); err != nil { return fmt.Errorf("初始化 Streamable MCP 工具集失败: %w", err) } ``` -------------------------------- ### Basic DuckDuckGo Search Tool Usage Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Create and integrate a DuckDuckGo search tool into an LLMAgent for basic search functionality. Ensure the LLMAgent is configured with a model and the search tool. ```go import "trpc.group/trpc-go/trpc-agent-go/tool/duckduckgo" // 创建 DuckDuckGo 搜索工具 searchTool := duckduckgo.NewTool() // 集成到 Agent searchAgent := llmagent.New("search-assistant", llmagent.WithModel(model), llmagent.WithTools([]tool.Tool{searchTool})) ``` -------------------------------- ### Configure Server and Client for Graph Interruptions and Recovery Source: https://trpc-group.github.io/trpc-agent-go/zh/a2a?q= Server-side configuration to allow all graph internal events, including interruptions, and client-side configuration to transfer runtime state for recovery information. ```go // Server server, _ := a2aserver.New( a2aserver.WithAgent(graphAgent, true), a2aserver.WithGraphEventObjectAllowlist("*"), a2aserver.WithStreamingEventType(a2aserver.StreamingEventTypeMessage), ) // Client subAgent, _ := a2aagent.New( a2aagent.WithAgentCardURL("http://remote:8888"), a2aagent.WithEnableStreaming(true), a2aagent.WithTransferStateKey("*"), ) ``` -------------------------------- ### Configure Child Agent Options Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Configure a child agent with options for summarization, inner stream forwarding, text mode, and history scope. ```go child := agenttool.NewTool( childAgent, agenttool.WithSkipSummarization(false), agenttool.WithStreamInner(true), agenttool.WithInnerTextMode(agenttool.InnerTextModeExclude), agenttool.WithHistoryScope(agenttool.HistoryScopeParentBranch), ) ``` -------------------------------- ### Expose Multiple A2A Agents on One Port with Base Paths Source: https://trpc-group.github.io/trpc-agent-go/zh/a2a?q= Configure multiple A2A servers, each with a unique base path, and mount them onto a shared http.Server using http.ServeMux. This allows a single service to handle requests for different agents via distinct URLs. ```Go mathServer, err := a2a.New( a2a.WithHost("http://localhost:8888/agents/math"), a2a.WithAgent(mathAgent, false), ) if err != nil { panic(err) } weatherServer, err := a2a.New( a2a.WithHost("http://localhost:8888/agents/weather"), a2a.WithAgent(weatherAgent, false), ) if err != nil { panic(err) } mux := http.NewServeMux() mux.Handle("/agents/math/", mathServer.Handler()) mux.Handle("/agents/weather/", weatherServer.Handler()) if err := http.ListenAndServe(":8888", mux); err != nil { panic(err) } ``` -------------------------------- ### Initialize MCP ToolSet with STDIO Transport Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Configures an MCP ToolSet to use STDIO transport, specifying the command and arguments for a Python server. Initialization is performed to establish the connection. ```go mcpToolSet := mcp.NewMCPToolSet( mcp.ConnectionConfig{ Transport: "stdio", Command: "python", Args: []string{"-", "m", "my_mcp_server"}, Timeout: 10 * time.Second, }, ) if err := mcpToolSet.Init(ctx); err != nil { return fmt.Errorf("初始化 STDIO MCP 工具集失败: %w", err) } ``` -------------------------------- ### Register Tool Search as Agent Callback Source: https://trpc-group.github.io/trpc-agent-go/zh/tool Register Tool Search as a callback for an agent to automatically rewrite the tool list before each model call. This approach uses `modelCallbacks.RegisterBeforeModel`. ```go import ( "trpc.group/trpc-go/trpc-agent-go/agent/llmagent" "trpc.group/trpc-go/trpc-agent-go/plugin/toolsearch" "trpc.group/trpc-go/trpc-agent-go/model" ) modelCallbacks := model.NewCallbacks() tc, err := toolsearch.New(modelInstance, toolsearch.WithMaxTools(3), toolsearch.WithFailOpen(), // 可选:search 失败时退回到“全部工具可用” ) if err != nil { /* handle */ } modelCallbacks.RegisterBeforeModel(tc.Callback()) agent := llmagent.New("assistant", llmagent.WithModel(modelInstance), llmagent.WithTools(allTools), // 仍然注册“全量工具”,Tool Search 会在每次调用前挑 TopK llmagent.WithModelCallbacks(modelCallbacks), ) ```