2024-02-26 java 基于aws bedrock接入 claude

流程

价格

image.png

授权

claude 授权

1个aws 海外版的账户
bedrock授权(claude 需要美国公司验证[我填的aws都能过],在勾选申请时仅仅勾选代码生成,有几个勾选【儿童内容生成】无法继续); claude授权感觉不到一天就有反馈
将aws账户的支付国家改为美国(可以随便生成虚拟地址,授权成功后可改回)


bedrock.png
api授权

准备调接口的iam账号授权bedrock权限


iam.png

2代码接入

此处选用aws java sdk 2
引入sdk

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>${softawssdk.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>bedrockruntime</artifactId>
        </dependency>
    </dependencies>
class ClaudeTest {
    private final static String claudeModelId = "anthropic.claude-v2";
    private final static String awsAccessKey = "";
    private final static String awsSecretKey = "";
    private static BedrockRuntimeClient client;
    private static BedrockRuntimeAsyncClient asyncClient;
    private static boolean silent = false;

    static {
        AwsBasicCredentials awsCreds = AwsBasicCredentials.create(awsAccessKey, awsSecretKey);
        client = BedrockRuntimeClient.builder()
                .region(Region.US_WEST_2)
                .credentialsProvider(StaticCredentialsProvider.create(awsCreds))
                .build();

        asyncClient = BedrockRuntimeAsyncClient.builder()
                .region(Region.US_WEST_2)
                .credentialsProvider(StaticCredentialsProvider.create(awsCreds))
                .build();
    }

    static testChat(ClaudeRequest request) {
        InvokeModelRequest request = InvokeModelRequest.builder()
                .body(SdkBytes.fromUtf8String(JSON.toJSONString(request)))
                .modelId(claudeModelId)
                .contentType(MediaType.APPLICATION_JSON_VALUE)
                .accept(MediaType.APPLICATION_JSON_VALUE)
                .build();

        InvokeModelResponse result = client.invokeModel(request);
        ClaudeResponse claudeResponse = JSONObject.parseObject(result.body().asUtf8String(), ClaudeResponse.class);
        System.out.println(claudeResponse.getCompletion());
    }

    static testStreamChat(ClaudeRequest request) {
        AtomicReference<String> finalCompletion = new AtomicReference<>("");


        InvokeModelWithResponseStreamRequest streamRequest = InvokeModelWithResponseStreamRequest.builder()
                .body(SdkBytes.fromUtf8String(JSON.toJSONString(request)))
                .modelId(claudeModelId)
                .contentType(MediaType.APPLICATION_JSON_VALUE)
                .accept(MediaType.APPLICATION_JSON_VALUE)
                .build();

        InvokeModelWithResponseStreamResponseHandler.Visitor visitor = InvokeModelWithResponseStreamResponseHandler.Visitor.builder()
                .onChunk(chunk -> {
                    String asUtf8String = chunk.bytes().asUtf8String();
                    ClaudeResponse claudeStreamResponse = JSONObject.parseObject(asUtf8String, ClaudeResponse.class);
                    String completion = claudeStreamResponse.getCompletion();
                    finalCompletion.set(finalCompletion.get() + completion);
                    if (!silent) {
                        System.out.print(completion);
                    }
                })
                .build();

        InvokeModelWithResponseStreamResponseHandler handler = InvokeModelWithResponseStreamResponseHandler.builder()
                .onEventStream(stream -> stream.subscribe(event -> event.accept(visitor)))
                .onComplete(() -> System.out.print("onComplete"))
                .onError(e -> System.out.println("\n\nError: " + e.getMessage()))
                .build();

        asyncClient.invokeModelWithResponseStream(streamRequest, handler).join();

        System.out.println(finalCompletion.get());
    }

    public static void main(String[] args) {

        String prompt = "hello";
        // Claude requires you to enclose the prompt as follows:
        String enclosedPrompt = "Human: " + prompt + "\n\nAssistant:";

        ClaudeRequest claudeRequest = new ClaudeRequest();
        claudeRequest.setPrompt(enclosedPrompt);
        claudeRequest.setMax_tokens_to_sample(200);
        claudeRequest.setTemperature(0.9);
        testChat(claudeRequest);
        testStreamChat(claudeRequest)
    }

    @Data
    private static class ClaudeRequest {
        private String prompt;
        private Integer max_tokens_to_sample;
        private Double temperature;
        private List<String> stop_sequences = new ArrayList<String>() {{
            add(promptHuman);
        }};
    }

    @Data
    private static class ClaudeResponse {

        /**
         * completion :  Hello! My name is Claude.
         * stop_reason : stop_sequence
         * stop :
         * <p>
         * Human:
         */

        public String completion;
        public String stop_reason;
        public String stop;
    }
}

备注

weblfux联用
普通聊天用mono.just()包装即可
stream聊天可以用Flux.create(FluxSink -> {
FluxSink.next(xx);
});

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容