Tools as Services:Go Micro 为何天生就为 AI 就绪
2026/9/20 6:34:53 网站建设 项目流程

Tools as Services:Go Micro 为何天生就为 AI 就绪

【免费下载链接】go-microA Go agent harness and service framework项目地址: https://gitcode.com/gh_mirrors/go/go-micro

导读:本文以 Go Micro(go-micro.dev/v6)为背景,剖析其核心设计理念——"服务即工具(Tools as Services)"。从 2015 年的 HTTP API 网关,到 MCP 网关与micro chat,访问层不断演进,但服务本身从未改变:注册表(Registry)中的服务始终自描述、可寻址、统一可调用。读完本文,你将理解 Go Micro 为何无需重写即可接入 LLM,掌握 MCP 工具目录的生成原理、micro chat的调用链路,以及如何用文档注释让 AI 更精准地调用你的服务。

从 API 网关到 MCP:我们并没有发明新东西

当人们看到micro chat或 MCP 网关时,很容易以为这是全新的构建。事实并非如此——我们只是把早已存在的东西暴露了出来

Go Micro 一直把服务当作**自描述(self-describing)、可寻址(addressable)**的单元:

  • 每个服务都会把自己的名称、端点(endpoints)和请求类型注册到注册表(registry/registry.go);
  • 每个端点都可以通过标准化路径被调用;
  • 唯一变化的是**"谁在调用"**——从 HTTP 客户端、浏览器、开发者,变成了 AI Agent。

核心模式:无论怎么访问,服务都以同样方式可达

Go Micro 建立在一个核心理念之上:一个服务应该以相同的方式被访问,无论你通过什么渠道访问它。2015 年项目启动时,这一理念体现为三个平行的访问层:

HTTP API 网关:/{service}/{endpoint}路由

每个服务都通过/{service}/{endpoint}可达:

POST /users/Users.Create {"name": "Alice"}

没有路由配置,没有 URL 映射。你添加一个 handler,它立即可达。网关读取注册表并自动路由。其实现位于 gateway/api/gateway.go——网关持有注册表引用,将 HTTP 请求翻译为 RPC 调用,无需任何静态路由表。

Web Dashboard:每个服务都是一张页面

每个服务都呈现为一个页面,端点可浏览、可从 UI 直接调用。同一个注册表,不同的呈现方式。

CLI:每个服务都是一条命令

micro call users Users.Create '{"name": "Alice"}'

同一个注册表、同一个端点、不同的界面。服务没有变,变的是访问层(access layer)

访问层模式的心智模型

Service (Go handler + registry metadata) ↓ accessed via API Gateway → HTTP clients Web Dashboard → browsers CLI → developers MCP Gateway → AI agents micro chat → natural language

每一层做的是同一件事:读取注册表 → 以消费者能理解的形式呈现服务 → 把调用路由回服务。服务本身浑然不觉,它只是处理请求。

演进到 AI:MCP 只是下一个访问层

当 AI 时代来临,Go Micro 没有发明新的服务调用方式,而是新增了一种LLM 能理解的发现方式

MCP 网关:每个服务都是 AI 可调用的工具

MCP 网关(gateway/mcp/mcp.go)读取注册表,把每个端点翻译成一个工具定义,并通过 Model Context Protocol 暴露出去:

{ "name": "users_Users_Create", "description": "Create a new user account", "parameters": { "name": {"type": "string"}, "email": {"type": "string"} } }

同一个注册表、同一个端点、同一份服务代码。Claude、ChatGPT 或任何兼容 MCP 的 Agent 都可以发现并调用你的服务——而你一行 AI 专属代码都不用写

从源码看,工具目录的构建发生在discoverServices()(gateway/mcp/mcp.go):

  1. 通过共享的schema resolver(gateway/schema/schema.go)读取注册表;
  2. 每个端点被转换为一个Tool,包含NameDescriptionInputSchema
  3. 请求字段类型通过schema.JSONType()映射为 JSON Schema 类型(stringstring,整数→integer,浮点→number,布尔→boolean);
  4. 若端点元数据带有example,则写入inputSchema["examples"]
  5. 网关还会持续watchServices()监听注册表变化,服务上线/下线时自动重建工具目录

调用时(invokeTool,gateway/mcp/mcp.go),网关走的是完整的生产级管道:x402 支付门(可选)→ OpenTelemetry 追踪 → 认证与 scope 鉴权 → 限流 → 熔断 → RPC 调用 → 审计日志。工具调用本质上就是client.NewRequest(tool.Service, tool.Endpoint, ...)+client.Call(...)——和 CLI、HTTP 网关完全同一条 RPC 通道。

除服务端点外,网关还会注册框架级工具(registerFrameworkTools):micro_registry_listmicro_registry_getmicro_store_list/read/writemicro_broker_publish——注册表、存储、Broker 这些框架原语也一并成为了 AI 可调用的工具。

micro chat:每个服务都是你可以对话的对象

> create a user named Alice with email alice@example.com → users_Users_Create({"name":"Alice","email":"alice@example.com"}) Done. User Alice created.

同一个注册表、同一个端点。LLM 读取工具描述后自行决定调用哪个工具。服务根本不知道自己在被 AI 调用

micro chat的实现位于 cmd/micro/chat/chat.go,其核心逻辑正是文档所说"连接现有工具发现 + 现有模型接口 + 一个 for 循环":

  • 启动时用ai.NewTools(reg, ai.ToolClient(cl))绑定注册表与客户端;
  • 通过tools.Discover()(ai/tools.go)把每个服务端点转换为 LLM 工具——工具名做"LLM 安全化"处理(点号替换为下划线:users.Users.Createusers_Users_Create),描述优先取端点元数据里的description
  • 在终端 REPL 中循环读取用户输入,交给模型Generate,模型返回的ToolCalls经由tools.Handler()(ai/tools.go)执行——把工具名还原为service.endpoint,通过 RPC 调用并把 JSON 结果回传给模型;
  • 工具列表按名称确定性排序,保证提示词前缀逐字节稳定,从而命中 Anthropiccache_control、Gemini 隐式缓存等 provider 侧的 prompt 缓存;
  • 若注册表中存在带type=agent元数据的 Agent,micro chat还会充当路由器routeToAgent):单个 Agent 直接 RPC 调用其Agent.Chat端点,多个 Agent 则交给 LLM 用route_to_agent工具做意图分发。

更有意思的是micro chat自带的micro_generate_service工具:当用户请求没有任何现有服务能处理时,模型可以调用该工具,通过 cmd/micro/cli/generate 现场生成、编译并启动一个新微服务,其新端点随后自动出现在工具列表中——服务的"自我增殖"由此闭环。

为什么这套模式能成立

AI 集成之所以是直截了当的工作——不是数月工程、不是重写——是因为 Go Micro 服务早已具备三个条件:

  1. 命名且可发现(Named and discoverable):注册表知道什么在运行、在哪里运行;
  2. 自描述(Self-describing):端点带类型的请求/响应 schema,handler 上的文档注释成为工具描述;
  3. 统一可调用(Uniformly callable):客户端按服务名 + 端点名发起 RPC,调用方是 HTTP 网关、CLI 还是 LLM 无关紧要。

增加 MCP 时,我们没有新增一种调用服务的方式,而是新增了一种发现它们的方式——一种 LLM 能理解的方式。调用机制早已存在。

micro chat也不是一个全新的 Agent 框架:它把已有的工具发现接到已有的模型接口上,再加一个 for 循环。整个核心大约 150 行(详见 build-your-own-ai-agent-cli-in-150-lines)。

文档注释的价值:文档从"可有可无"变成"功能性"

唯一真正改变的是:文档变得有功能性了。

在 API 网关时代,文档注释是锦上添花;在 MCP 时代,它们是 LLM 决定调用哪个工具的依据:

// CreateUser creates a new user account with the given name and email. // Returns the created user with a generated ID. // @example {"name": "Alice", "email": "alice@example.com"} func (h *Users) CreateUser(ctx context.Context, req *pb.CreateRequest, rsp *pb.CreateResponse) error {

注释成为工具描述,@example成为 LLM 推断参数形态的提示。好注释意味着 AI 选对工具,坏注释意味着它靠猜。

从实现看,这一机制是这样落地的:端点元数据(descriptionexamplescopes)随服务注册进注册表(见 gateway/schema/schema.go 中resolveEndpoint对元数据的解析),MCP 网关和ai.Tools.Discover()在生成工具定义时优先读取这些元数据。换句话说:你写的注释,最终会成为发给 LLM 的 JSON 工具描述。

这形成了一个真实的写文档激励——不是因为人类可能读它,而是因为机器一定会读它,并根据它做决策

下一步:模式可以走得更远

"服务即工具"的模式不止于服务端点。文档中列出的方向在源码中均已落地或具备条件:

  • micro registry list已经能展示正在运行的服务(对应工具micro_registry_list,见 gateway/mcp/mcp.go)——Agent 可以用同样的数据推理服务拓扑;
  • micro broker subscribe流式订阅事件——Agent 可以监控事件并做出反应,这正是micro flow(flow/flow.go)所做的事;
  • micro store持久化数据——Agent 可以在多步工作流中读写状态(对应工具micro_store_read/write)。

每个拥有 CLI 命令的框架原语,都同样可以成为一个工具。注册表、Broker、Store、Config 接口既可从终端访问,也可从代码访问。让它们对 AI Agent 可用,与我们为服务所做的是一样的步骤——事实上 MCP 网关的registerFrameworkTools已经把这些原语注册成了 MCP 工具。

结语

自 2015 年以来的论点从未改变:服务只构建一次,处处皆可访问(build the service once, access it everywhere)。"处处"只是扩展到了包含 AI 而已。

Go Micro 从未需要专门的 "agent package" 或 "AI framework"——框架本就具备正确的形态。服务从来就是工具,只是它们自己还不知道而已。

延伸阅读

  • MCP 网关完整实现与选项:gateway/mcp/mcp.go
  • 服务 schema 解析与共享目录:gateway/schema/schema.go
  • 工具发现与 RPC 执行:ai/tools.go
  • micro chat交互式 Agent 命令:cmd/micro/chat/chat.go
  • HTTP API 网关:gateway/api/gateway.go
  • 顶层统一 API(Service/Agent/Flow 三原语):micro.go

【免费下载链接】go-microA Go agent harness and service framework项目地址: https://gitcode.com/gh_mirrors/go/go-micro

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询