Tool - httprequest
HTTP 请求工具
一组为 Eino 实现的 HTTP 请求工具,遵循 InvokableTool
接口。这些工具允许你轻松执行 GET、POST、PUT 和 DELETE 请求,并可与 Eino 的聊天模型交互系统及 ToolsNode
集成,实现更强大的功能。
功能
- 实现了
github.com/cloudwego/eino/components/tool.InvokableTool
接口 - 支持 GET、POST、PUT 和 DELETE 请求
- 可配置请求头和 HttpClient
- 可与 Eino 工具系统简单集成
安装
使用 go get
安装该包(请根据你的项目结构调整模块路径):
go get github.com/cloudwego/eino-ext/components/tool/httprequest
快速开始
下面分别展示了如何单独使用 GET 和 POST 工具的示例。
GET 请求示例
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/bytedance/sonic"
req "github.com/cloudwego/eino-ext/components/tool/httprequest/get"
)
func main() {
// Configure the GET tool
config := &req.Config{
// Headers is optional
Headers: map[string]string{
"User-Agent": "MyCustomAgent",
},
// HttpClient is optional
HttpClient: &http.Client{
Timeout: 30 * time.Second,
Transport: &http.Transport{},
},
}
ctx := context.Background()
// Create the GET tool
tool, err := req.NewTool(ctx, config)
if err != nil {
log.Fatalf("Failed to create tool: %v", err)
}
// Prepare the GET request payload
request := &req.GetRequest{
URL: "https://jsonplaceholder.typicode.com/posts",
}
jsonReq, err := sonic.Marshal(request)
if err != nil {
log.Fatalf("Error marshaling JSON: %v", err)
}
// Execute the GET request using the InvokableTool interface
resp, err := tool.InvokableRun(ctx, string(jsonReq))
if err != nil {
log.Fatalf("GET request failed: %v", err)
}
fmt.Println(resp)
}
POST 请求示例
package main
import (
"context"
"fmt"
"log"
"time"
"github.com/bytedance/sonic"
post "github.com/cloudwego/eino-ext/components/tool/httprequest/post"
)
func main() {
config := &post.Config{}
ctx := context.Background()
tool, err := post.NewTool(ctx, config)
if err != nil {
log.Fatalf("Failed to create tool: %v", err)
}
request := &post.PostRequest{
URL: "https://jsonplaceholder.typicode.com/posts",
Body: `{"title": "my title","body": "my body","userId": 1}`,
}
jsonReq, err := sonic.Marshal(request)
if err != nil {
log.Fatalf("Error marshaling JSON: %v", err)
}
resp, err := tool.InvokableRun(ctx, string(jsonReq))
if err != nil {
log.Fatalf("Post failed: %v", err)
}
fmt.Println(resp)
}
配置
GET、POST、PUT 和 DELETE 工具共享类似的配置参数,这些参数在各自的 Config
结构体中定义。例如:
// Config 表示 HTTP 请求工具的通用配置。
type Config struct {
// 灵感来源于 LangChain 项目的 "Requests" 工具,特别是 RequestsGetTool。
// 详情请见:https://python.langchain.com/docs/integrations/tools/requests/
// 可选。默认值: "request_get"。
ToolName string `json:"tool_name"`
// 可选。默认值: "A portal to the internet. Use this tool when you need to fetch specific content from a website.
// Input should be a URL (e.g., https://www.google.com). The output will be the text response from the GET request."
ToolDesc string `json:"tool_desc"`
// Headers 是 HTTP 头部名称与对应值的映射。
// 这些头部会包含在工具发起的每个请求中。
Headers map[string]string `json:"headers"`
// HttpClient 用于执行请求的 HTTP 客户端。
// 如果未提供,将初始化并使用一个默认的 30 秒超时和标准传输的客户端。
HttpClient *http.Client
}
对于 GET 工具,请求结构如下:
type GetRequest struct {
URL string `json:"url" jsonschema_description:"要执行 GET 请求的 URL"`
}
对于 POST 工具,请求结构如下:
type PostRequest struct {
URL string `json:"url" jsonschema_description:"要执行 POST 请求的 URL"`
Body string `json:"body" jsonschema_description:"POST 请求要发送的请求体"`
}
与 agent 集成示例
package main
import (
"context"
"fmt"
"log"
"os"
"time"
"github.com/bytedance/sonic"
"github.com/cloudwego/eino-ext/components/model/openai"
req "github.com/cloudwego/eino-ext/components/tool/httprequest/get"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/compose"
"github.com/cloudwego/eino/schema"
)
// float32Ptr is a helper to return a pointer for a float32 value.
func float32Ptr(f float32) *float32 {
return &f
}
func main() {
// Load OpenAI API key from environment variables.
openAIAPIKey := os.Getenv("OPENAI_API_KEY")
if openAIAPIKey == "" {
log.Fatal("OPENAI_API_KEY not set")
}
ctx := context.Background()
// Setup GET tool configuration.
config := &req.Config{
Headers: map[string]string{
"User-Agent": "MyCustomAgent",
},
}
// Instantiate the GET tool.
getTool, err := req.NewTool(ctx, config)
if err != nil {
log.Fatalf("Failed to create GET tool: %v", err)
}
// Retrieve the tool info to bind it to the ChatModel.
toolInfo, err := getTool.Info(ctx)
if err != nil {
log.Fatalf("Failed to get tool info: %v", err)
}
// Create the ChatModel using OpenAI.
chatModel, err := openai.NewChatModel(ctx, &openai.ChatModelConfig{
Model: "gpt-4o", // or another supported model
APIKey: openAIAPIKey,
Temperature: float32Ptr(0.7),
})
if err != nil {
log.Fatalf("Failed to create ChatModel: %v", err)
}
// Bind the tool to the ChatModel.
err = chatModel.BindTools([]*schema.ToolInfo{toolInfo})
if err != nil {
log.Fatalf("Failed to bind tool to ChatModel: %v", err)
}
// Create the Tools node with the GET tool.
toolsNode, err := compose.NewToolNode(ctx, &compose.ToolsNodeConfig{
Tools: []tool.BaseTool{getTool},
})
if err != nil {
log.Fatalf("Failed to create ToolNode: %v", err)
}
// Build the chain with the ChatModel and the Tools node.
chain := compose.NewChain[[]*schema.Message, []*schema.Message]()
chain.
AppendChatModel(chatModel, compose.WithNodeName("chat_model")).
AppendToolsNode(toolsNode, compose.WithNodeName("tools"))
// Compile the chain to obtain the agent.
agent, err := chain.Compile(ctx)
if err != nil {
log.Fatalf("Failed to compile chain: %v", err)
}
// Define the API specification (api_spec) in OpenAPI (YAML) format.
apiSpec := `
openapi: "3.0.0"
info:
title: JSONPlaceholder API
version: "1.0.0"
servers:
- url: https://jsonplaceholder.typicode.com
paths:
/posts:
get:
summary: Get posts
parameters:
- name: _limit
in: query
required: false
schema:
type: integer
example: 2
description: Limit the number of results
responses:
"200":
description: Successful response
content:
application/json:
schema:
type: array
items:
type: object
properties:
userId:
type: integer
id:
type: integer
title:
type: string
body:
type: string
/comments:
get:
summary: Get comments
parameters:
- name: _limit
in: query
required: false
schema:
type: integer
example: 2
description: Limit the number of results
responses:
"200":
description: Successful response
content:
application/json:
schema:
type: array
items:
type: object
properties:
postId:
type: integer
id:
type: integer
name:
type: string
email:
type: string
body:
type: string
`
// Create a system message that includes the API documentation.
systemMessage := fmt.Sprintf(`You have access to an API to help answer user queries.
Here is documentation on the API:
%s`, apiSpec)
// Define initial messages (system and user).
messages := []*schema.Message{
{
Role: schema.System,
Content: systemMessage,
},
{
Role: schema.User,
Content: "Fetch the top two posts. What are their titles?",
},
}
// Invoke the agent with the messages.
resp, err := agent.Invoke(ctx, messages)
if err != nil {
log.Fatalf("Failed to invoke agent: %v", err)
}
// Output the response messages.
for idx, msg := range resp {
fmt.Printf("Message %d: %s: %s\n", idx, msg.Role, msg.Content)
}
}
更多详情
最后修改
July 24, 2025
: Update parser_html.md (#1379) (7d0738a)