cloudwego / cloudwego/eino-ext
Claude: Vertex and Bedrock backends are compiled into every build, pulling GCP auth and the AWS SDK
- Dominant language
- Go
- Stars
- 811
- Forks
- 368
- Avg merge
- 16h 22m
- Merged PRs (30d)
- 13
Description
## What happens
`components/model/claude` imports the Vertex and Bedrock backends unconditionally:
```go
// components/model/claude@v0.1.25 claude.go
"github.com/anthropics/anthropic-sdk-go/bedrock"
"github.com/anthropics/anthropic-sdk-go/vertex"
awsConfig "github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/credentials"
"golang.org/x/oauth2/google"
```
A user who only sets `APIKey` and `Model` for the direct Anthropic API therefore compiles the Google Cloud auth stack and the AWS SDK as well.
## Cost
Package counts from `go list -deps`:
| target | packages |
| --- | --- |
| `components/model/openai` | 293 |
| `anthropics/anthropic-sdk-go` alone | 235 |
| `components/model/claude` | 642 |
What the component adds beyond the SDK it wraps: `cloud.google.com/go/auth`, `cloud.google.com/go/compute`, `aws-sdk-go-v2`, `smithy-go`, `google/s2a-go`, `googleapis/gax-go`, `googleapis/enterprise-certificate-proxy`.
Measured in a real project ([evcc](https://github.com/evcc-io/evcc), a self-hosted energy manager that ships a single binary to devices like a Raspberry Pi), building with and without the claude component:
```
with claude component 129.3 MB
without claude 113.4 MB
─────────
15.9 MB (12%)
```
We use the direct Anthropic API only. Neither Vertex nor Bedrock is reachable in our configuration, so all of that is dead weight in the shipped artifact.
## Why the obvious workarounds do not fit
- Anthropic's OpenAI compatibility layer would let us reuse `components/model/openai` and skip this entirely, but Anthropic documents it as "not considered a long-term or production-ready solution", and it does not return the thinking output, which we surface in our UI.
- Writing our own thin `ToolCallingChatModel` over `anthropic-sdk-go` works and is what we would fall back to, but then every project that wants plain Anthropic without the cloud backends reimplements the same wrapper.
## Suggestion
Any of these solves it, in rough order of preference:
1. **Separate modules**, e.g. `components/model/claude` for the direct API and `components/model/claude/vertex` plus `components/model/claude/bedrock` for the cloud backends. Go's dependency resolution then keeps the unused backends out of the build entirely. This matches how the config is already shaped, since `ByVertex` and `ByBedrock` select mutually exclusive paths.
2. **Build tags**, e.g. `claude_vertex` and `claude_bedrock`, defaulting to off, with the constructor returning a clear error when a disabled backend is configured.
3. At minimum, **document the cost** in `components/model/claude/README.md` so the dependency footprint is a deliberate choice rather than a discovery at build time.
Happy to send a PR for whichever direction you prefer, option 1 being the one I would pick.
Versions: `eino-ext/components/model/claude v0.1.25`, `eino v0.9.13`, Go 1.26.
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Contributor guide
Research direction
Start with components/model/claude/claude.go and its ByVertex and ByBedrock paths, then read components/model/claude/README.md and inspect the dependency graph with go list -deps. Choose and confirm the module or build-tag boundary before changing it. Done means direct Anthropic builds no longer include unused AWS and Google dependencies while the cloud backends remain usable.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, gcp, go
- Domain
- backend, build-system
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100