给 AI 助手装个"记忆芯片"🧠:OpenClaw + S3 Vectors 搞定个人知识库

你的 AI 助手是不是也有"金鱼脑"?

聊了半小时业务背景,一刷新全忘。公司文档?它读不懂,还会一本正经地瞎编。

我被这事折腾了好几个月。直到发现亚马逊云科技新出的 S3 Vectors ,感觉终于有解了。今天分享一下我用 OpenClaw + S3 Vectors 搭个人知识库的全过程。代码都能跑,别光收藏不看啊。

S3 Vectors:在 S3 上直接存向量

先解释一下。你可能听过"向量数据库"------把文本转成数字(向量),用数学找语义相近的内容。

传统方案要单独搞个向量数据库集群。运维成本?别提了。

S3 Vectors 思路不同:在 S3 上直接加向量能力。不用额外服务,存储成本跟 S3 走。

三个概念就够了:

  • Vector Bucket:向量桶,顶层容器
  • Vector Index:向量索引,定义维度
  • Vector:具体数据,带 key、向量值、元数据

RAG:让 AI 学会"开卷考试"

RAG(检索增强生成)的逻辑特简单:

用户提问 → 先从知识库搜相关内容 → 搜到的内容 + 问题一起喂给模型 → 模型看着"参考资料"回答

不用让 AI 背下所有知识,能"翻书"就行。

动手搭建

Step 1:建桶建索引

python 复制代码
import boto3

s3vectors = boto3.client('s3vectors')

s3vectors.create_vector_bucket(
    vectorBucketName='my-knowledge-base'
)

s3vectors.create_vector_index(
    vectorBucketName='my-knowledge-base',
    vectorIndexName='docs-index',
    dimension=1024,
    distanceMetric='cosine'
)
print('搞定!')

dimension=1024 跟 Titan Embed Text v2 的输出对齐。cosine 余弦相似度,文本场景标配。

Step 2:文档切分 + 向量化

文档不能整篇丢进去,得切成小块。我踩过这个坑------整篇转向量,搜出来的结果跟问题八竿子打不着。

python 复制代码
import boto3
import json


def get_embedding(text):
    bedrock = boto3.client('bedrock-runtime')
    response = bedrock.invoke_model(
        modelId='amazon.titan-embed-text-v2:0',
        body=json.dumps({'inputText': text})
    )
    return json.loads(response['body'].read())['embedding']


def split_text(text, chunk_size=500, overlap=50):
    chunks = []
    start = 0
    while start < len(text):
        end = start + chunk_size
        chunk = text[start:end]
        if chunk.strip():
            chunks.append(chunk.strip())
        start = end - overlap
    return chunks

500 字一块、50 字重叠,实测效果不错。

Step 3:写入向量

python 复制代码
import boto3
import json


def get_embedding(text):
    bedrock = boto3.client('bedrock-runtime')
    response = bedrock.invoke_model(
        modelId='amazon.titan-embed-text-v2:0',
        body=json.dumps({'inputText': text})
    )
    return json.loads(response['body'].read())['embedding']


def split_text(text, chunk_size=500, overlap=50):
    chunks = []
    start = 0
    while start < len(text):
        end = start + chunk_size
        chunk = text[start:end]
        if chunk.strip():
            chunks.append(chunk.strip())
        start = end - overlap
    return chunks


def ingest(documents):
    s3vectors = boto3.client('s3vectors')
    total = 0
    for doc in documents:
        chunks = split_text(doc['content'])
        vectors = []
        for i, chunk in enumerate(chunks):
            vectors.append({
                'key': f"{doc['id']}-{i:03d}",
                'data': {'float32': get_embedding(chunk)},
                'metadata': {
                    'title': doc['title'],
                    'source': doc.get('source', ''),
                    'content': chunk
                }
            })
        for j in range(0, len(vectors), 20):
            batch = vectors[j:j + 20]
            s3vectors.put_vectors(
                vectorBucketName='my-knowledge-base',
                vectorIndexName='docs-index',
                vectors=batch
            )
            total += len(batch)
    print(f'写入 {total} 条向量')


# 试试
ingest([
    {
        'id': 'deploy',
        'title': '部署指南',
        'content': '服务用 Docker 部署,拉镜像后 docker-compose up -d,'
                   '健康检查 /health 返回 200 即正常。',
        'source': 'wiki'
    }
])

每 20 条一批,稳得很。

Step 4:语义搜索

python 复制代码
import boto3
import json


def get_embedding(text):
    bedrock = boto3.client('bedrock-runtime')
    response = bedrock.invoke_model(
        modelId='amazon.titan-embed-text-v2:0',
        body=json.dumps({'inputText': text})
    )
    return json.loads(response['body'].read())['embedding']


def search(query, top_k=5):
    s3vectors = boto3.client('s3vectors')
    results = s3vectors.query_vectors(
        vectorBucketName='my-knowledge-base',
        vectorIndexName='docs-index',
        queryVector={'float32': get_embedding(query)},
        topK=top_k
    )
    for vec in results.get('vectors', []):
        meta = vec.get('metadata', {})
        print(f"[{vec.get('score', 0):.4f}] {meta.get('title', '')}")
        print(f"  {meta.get('content', '')[:100]}")


search('怎么部署')

搜"怎么部署"能匹配到"部署指南",语义搜索就是这么神奇。

Step 5:接入 OpenClaw

OpenClaw 用 Skill 扩展能力。建个 knowledge-base/scripts/search.py

python 复制代码
#!/usr/bin/env python3
import sys
import json
import boto3


def get_embedding(text):
    bedrock = boto3.client('bedrock-runtime')
    response = bedrock.invoke_model(
        modelId='amazon.titan-embed-text-v2:0',
        body=json.dumps({'inputText': text})
    )
    return json.loads(response['body'].read())['embedding']


def search(query, top_k=5):
    s3vectors = boto3.client('s3vectors')
    results = s3vectors.query_vectors(
        vectorBucketName='my-knowledge-base',
        vectorIndexName='docs-index',
        queryVector={'float32': get_embedding(query)},
        topK=top_k
    )
    return [
        {
            'title': v.get('metadata', {}).get('title', ''),
            'content': v.get('metadata', {}).get('content', ''),
            'score': v.get('score', 0)
        }
        for v in results.get('vectors', [])
    ]


if __name__ == '__main__':
    q = sys.argv[1] if len(sys.argv) > 1 else ''
    if not q:
        print('用法: python search.py "关键词"')
        sys.exit(1)
    print(json.dumps(search(q), ensure_ascii=False, indent=2))

再配个 SKILL.md 告诉 OpenClaw 什么时候该搜知识库,整个 RAG 就通了。

S3 Vectors 和 Bedrock Knowledge Base 咋选?

亚马逊云科技的 Bedrock Knowledge Base 也能做 RAG。

  • Bedrock Knowledge Base:全家桶,自动切分、自动向量化、自动检索。省事,适合快速验证
  • S3 Vectors:乐高积木,每一步自己控制。灵活,适合需要定制的场景

我选 S3 Vectors,因为切分策略、搜索逻辑全在我手里。出了 bug 好查,想调优有空间。

成本呢?

存储跟 S3 标准走,查询按次计费,Embedding 按 token 计费。几百篇文档的知识库,月成本个位数美金。比单独跑数据库服务便宜太多。

实战体验

我把公司 30 多篇技术文档和会议纪要都灌进去了,大概花了 5 分钟。搜索延迟在 200ms 以内,体感非常丝滑。

实际使用中,我发现几个优化点:

  • 元数据要丰富metadata 里多存点信息(来源、日期、作者),方便后续过滤
  • chunk_size 要调:技术文档 500 字合适,会议纪要可以放到 800 字
  • 定期更新:文档变了记得重新导入对应的向量

最后

整套方案:S3 Vectors 存向量,Bedrock 出 Embedding,OpenClaw 做调度。代码不到 200 行,一个下午搞定。

AI 助手的"失忆症",这次算是彻底治好了。

觉得有用的话,点个赞呗 👍

相关推荐
A小辣椒12 天前
AWS Clould Support Engineer就职面试题
aws
亚林瓜子15 天前
AWS WAF中如何放行某个触发了托管规则的接口
aws·waf
悠悠1213817 天前
AWS DevOps Agent 体验一周后,我决定把 oncall 手机调成静音了
云计算·aws·devops
yyuuuzz17 天前
独立站运营的几个技术层面常见问题
大数据·运维·服务器·网络·数据库·aws
yyuuuzz17 天前
游戏云服务器推荐的技术选择思路
大数据·运维·服务器·游戏·云计算·aws
kernelcraft18 天前
Boto3:Python 操作 AWS 的官方 SDK
开发语言·python·其他·aws
普通网友25 天前
Serverless 框架:多云函数部署(AWS + 阿里云 + 腾讯云)
阿里云·serverless·aws
TG_yunshuguoji1 个月前
亚马逊云代理商:如何用 CloudWatch+Lambda 打造自动化告警系统
大数据·运维·自动化·云计算·aws
yyuuuzz1 个月前
独立站搭建的几个核心技术问题
运维·服务器·网络·数据库·aws
yyuuuzz1 个月前
aws亚马逊云服务的基础认知与常见场景
大数据·运维·服务器·网络·云计算·aws