把 AI 编程助手放进终端并不意味着必须自己部署 GPU 集群。OpenCode 可以作为本地、开源的交互入口,Amazon Bedrock 则负责托管开放权重模型的推理。两者组合后,开发团队能够按调用量付费、在不同模型之间切换,并通过自己的 AWS 账户管理身份、区域和访问权限。
这里的关键不是简单地“接上一个模型”,而是建立一条可控的调用链:开发者在仓库中启动 OpenCode,请求通过 AWS 凭证进入 Bedrock,模型读取必要的代码上下文并返回修改建议。团队不需要维护推理服务器,但仍要认真处理 IAM、区域、模型访问权限和敏感数据边界。
这套组合解决了什么问题
OpenCode 是终端原生的编码代理,适合在现有 Git、Shell 和编辑器工作流旁边运行。Bedrock 提供托管模型 API,因此团队不必自行处理模型下载、GPU 调度、服务扩缩容或推理端点升级。
这种组合尤其适合以下场景:
- 公司已经使用 AWS,希望复用 IAM、CloudTrail、预算和区域治理能力;
- 不想把所有任务绑定到单一模型,需要按代码生成、审查或快速问答分别选型;
- 项目包含内部代码,希望请求通过团队自己的 AWS 账户发起;
- 使用频率波动较大,不值得长期运行专用推理基础设施。
“开放权重”也不等于“本地运行”。在这个架构中,模型权重由 Bedrock 托管,开发者通过托管 API 使用模型。它保留了开放模型的选择空间,但运维方式仍然是云服务调用。
不要让一个模型包办所有任务
编码代理的任务差异很大。补全一个测试、解释遗留函数和审查跨模块重构,对模型能力、上下文窗口、延迟和成本的要求并不相同。
可以把任务粗略分成三档:
| 任务 | 关注点 | 选型方式 |
|---|---|---|
| 文件检索、错误解释、短小修改 | 延迟和单次成本 | 使用速度快、参数规模较小的模型 |
| 功能实现、测试生成、跨文件修改 | 代码质量和上下文能力 | 使用能力均衡的主力模型 |
| 架构分析、安全审查、复杂重构 | 推理深度和稳定性 | 使用能力更强的模型,并限制调用范围 |
实践中可以给团队定义 fast、build 和 review 三个逻辑角色,而不是让每位开发者记忆一串模型 ID。Bedrock 中的模型可用性、模型 ID和推理配置会随区域与账户权限变化,因此应从目标区域查询可用模型,再把实际 ID 写入项目配置。
下面的命令可以列出当前账户所在区域可见的文本模型:
export AWS_PROFILE=dev-ai
export AWS_REGION=us-east-1
aws bedrock list-foundation-models \
--region "$AWS_REGION" \
--by-output-modality TEXT \
--query 'modelSummaries[].{name:modelName,id:modelId,provider:providerName}' \
--output table
如果组织使用 Bedrock 推理配置文件或跨区域推理,传给运行时的标识符可能不是基础模型列表中的原始 ID。应以账户中已经启用的模型或推理配置文件为准。
先独立验证 Bedrock,再接入 OpenCode
排查集成问题时,最好先证明 AWS 凭证、区域和模型权限有效。下面的脚本使用 Bedrock Converse API 发送一个代码审查请求。
运行前需要安装 Boto3,并将 BEDROCK_MODEL_ID 替换为当前区域中已获准使用、且支持 Converse API 的模型或推理配置文件 ID:
python -m pip install --upgrade boto3
export AWS_PROFILE=dev-ai
export AWS_REGION=us-east-1
export BEDROCK_MODEL_ID='替换为实际模型或推理配置文件ID'
保存为 bedrock_check.py:
import os
import boto3
region = os.environ.get("AWS_REGION", "us-east-1")
model_id = os.environ["BEDROCK_MODEL_ID"]
client = boto3.client("bedrock-runtime", region_name=region)
response = client.converse(
modelId=model_id,
system=[
{
"text": (
"You are a senior code reviewer. Find correctness and security "
"issues. Return concise Markdown and do not invent missing context."
)
}
],
messages=[
{
"role": "user",
"content": [
{
"text": """Review this Python function:
def read_user_file(base, name):
path = base + '/' + name
return open(path).read()
"""
}
],
}
],
inferenceConfig={
"maxTokens": 500,
"temperature": 0.1,
},
)
for block in response["output"]["message"]["content"]:
if "text" in block:
print(block["text"])
执行:
python bedrock_check.py
如果这里出现 AccessDeniedException,应先检查模型访问资格、区域、IAM 权限和组织级服务控制策略,而不是反复修改 OpenCode 配置。
将同一身份链交给 OpenCode
OpenCode 的配置字段可能随版本调整,下面是一个可改造的项目级示例,而不是对所有版本都固定不变的接口。核心思路是让 OpenCode 使用 AWS SDK 默认凭证链,并在模型名称中指向 Bedrock 提供方。
创建 opencode.json.template:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"amazon-bedrock": {
"options": {
"region": "__AWS_REGION__"
}
}
},
"model": "amazon-bedrock/__MODEL_ID__"
}
然后通过环境变量生成项目配置并启动 OpenCode:
export AWS_PROFILE=dev-ai
export AWS_REGION=us-east-1
export BEDROCK_MODEL_ID='替换为实际模型或推理配置文件ID'
sed \
-e "s|__AWS_REGION__|$AWS_REGION|g" \
-e "s|__MODEL_ID__|$BEDROCK_MODEL_ID|g" \
opencode.json.template > opencode.json
opencode
如果当前 OpenCode 版本使用不同的提供方名称或配置结构,应保留相同的认证原则,但按照该版本的配置说明调整字段。不要把长期 AWS Access Key 写入仓库;优先使用 AWS IAM Identity Center、短期会话、角色或工作负载身份。
多模型工作流也可以从简单的配置切换开始。例如,分别维护 opencode.fast.json.template 和 opencode.review.json.template,只让其中的模型 ID 不同,再用一个小脚本选择角色:
#!/usr/bin/env bash
set -euo pipefail
role="${1:-fast}"
case "$role" in
fast) model="${BEDROCK_FAST_MODEL_ID:?missing BEDROCK_FAST_MODEL_ID}" ;;
review) model="${BEDROCK_REVIEW_MODEL_ID:?missing BEDROCK_REVIEW_MODEL_ID}" ;;
*) echo "usage: $0 fast|review" >&2; exit 2 ;;
esac
sed \
-e "s|__AWS_REGION__|${AWS_REGION:-us-east-1}|g" \
-e "s|__MODEL_ID__|$model|g" \
opencode.json.template > opencode.json
exec opencode
保存为 ai-code 后运行:
chmod +x ai-code
./ai-code fast
# 或者执行深度审查
./ai-code review
IAM 权限要小,代码上下文也要小
最小调用角色通常只需要模型推理权限。下面是可作为起点的 IAM 策略;为了兼容不同类型的模型和推理配置文件,示例暂时使用了 Resource: "*"。生产环境应根据实际模型 ARN、推理配置文件 ARN和 AWS 支持的资源级授权方式进一步收紧。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "InvokeApprovedBedrockModels",
"Effect": "Allow",
"Action": [
"bedrock:InvokeModel",
"bedrock:InvokeModelWithResponseStream"
],
"Resource": "*"
}
]
}
安全控制不能止于 IAM。编码代理可能读取当前仓库中的文件,因此还应:
- 在忽略规则和代理配置中排除
.env、私钥、生产导出数据及凭证文件; - 默认只发送完成任务所需的文件,而不是整个单体仓库;
- 对自动执行 Shell 命令、写文件和提交 Git 的能力设置人工确认;
- 用 AWS Budgets、成本分配标签或账户边界监控调用费用;
- 根据组织政策确认所选区域、日志设置、数据处理条款和模型许可条件。
上线前的决策清单
这套方案的价值在于把终端体验、模型选择和云端治理拆开:OpenCode 负责代理交互,Bedrock 负责托管推理,IAM 负责访问边界。落地时建议按以下顺序推进:
- 在目标区域确认开放权重模型和推理配置文件可用;
- 用独立脚本验证凭证、权限与 Converse API;
- 先为小型任务选择一个默认模型,再增加审查模型;
- 禁止在仓库中保存静态 AWS 密钥;
- 限制代理可读取的文件和可自动执行的命令;
- 用真实任务测量延迟、输入输出令牌和每次任务成本;
- 保留模型切换机制,避免工作流被单个模型锁定。
无需管理推理基础设施并不代表无需治理。真正可靠的编码助手,应当既能修改代码,也能清楚回答三个问题:它用了哪个模型、读取了哪些上下文,以及这次调用由谁授权并承担成本。