Open6

Agent Development Kit 試すメモ

knaka Tech-Blogknaka Tech-Blog

概要

  • Google , Agent Development Kit 試す例になります。
  • python 版

[ 公開 2025/06/14 ]


環境

  • Agent Development Kit
  • Python 3.13.4 (windows)
  • node 20 (テスト用)

関連


  • anthropic の、Agent 資料

https://www.anthropic.com/engineering/building-effective-agents


手順

  • quickstart の、インストールを進める。
  • multi_tool_agent/.env の、変数設定
  • adk web で、ADK起動
  • http://localhost:8000/dev-ui/ で、テスト画面風の画面が操作できる。

knaka Tech-Blogknaka Tech-Blog

ADK , API テスト


  • API関連

https://google.github.io/adk-docs/get-started/testing/


環境

  • Agent Development Kit
  • Python 3.13.4 (windows)
  • node 20 (テスト用)

  • 例のコード: 関連記事を参考しました。

  • Gist、アップしました。

https://gist.github.com/kuc-arc-f/6681d0aa03acc25c38471e508d311b62


  • tree
cd seq_agent2/
$ tree .
.
├── __init__.py
├── agent.py


  • .env
  • geminiの鍵
GOOGLE_GENAI_USE_VERTEXAI=FALSE
GOOGLE_API_KEY="key"

  • init.py
from . import agent

  • agent.py
import datetime
from zoneinfo import ZoneInfo
from google.adk.agents import Agent

from datetime import datetime, timedelta, timezone
from google.adk.agents import LlmAgent
from google.adk.agents import SequentialAgent

# CheckFive 5
# First agent: prompt for "5"
a1 = LlmAgent(
    name="CheckFive",
    model="gemini-2.0-flash",
    instruction="""
    Ask the user for an integer. If it's not 5, reply “Exiting” and stop. Otherwise reply “Got 5” and store it.
    """,
    output_key="value1"
)

# CheckSeven 7
# Second agent: prompt for "7"
a2 = LlmAgent(
    name="CheckSeven",
    model="gemini-2.0-flash",
    instruction="""
    I see the first number was {value1}. Now ask for another integer. If it's not 7, exit; otherwise store it.
    """,
    output_key="value2"
)

# I have two numbers: 5 and 7. Calculate and reply with their sum.
# Third agent: compute sum
a3 = LlmAgent(
    name="Summer",
    model="gemini-2.0-flash",
    instruction="""
    I have two numbers: {value1} and {value2}. Calculate and reply with their sum.
    """,
    output_key="sum"
)

root_agent = SequentialAgent(
    name="CheckAndSum",
    sub_agents=[a1, a2, a3]
)


  • api_server 起動
  • adk api_server 実行します。
D:\work\python\adk\seq_agent2>cd ..

D:\work\python\adk>

D:\work\python\adk>adk api_server
INFO:     Started server process [28612]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)


  • sessionId 等の登録
  • users の後に、userId
  • sessions の後に、sessionId
curl -X POST http://localhost:8000/apps/seq_agent2/users/u_456/sessions/s_456 -H "Content-Type: application/json"

  • 上記の agent.py の、SequentialAgent 実行しました。
  • curl POST通信
  • seq2_3.json , jsonデータ
{
  "appName": "seq_agent2",
  "userId": "u_456",
  "sessionId": "s_456",
  "newMessage": {
      "role": "user",
      "parts": [{
        "text": "I have two numbers: 5 and 7. Calculate and reply with their sum."
      }]
  }
}
  • Post - send
curl  -X POST http://localhost:8000/run  -H "Content-Type: application/json" --data @./doc/json/seq2_3.json
  • レスポンス
>curl  -X POST http://localhost:8000/run  -H "Content-Type: application/json" --data @./doc/json/seq2_3.json
[{"content":{"parts":[{"text":"I'm designed to check for a specific number. Please provide an integer. If it's not 5, I'll exit. If it is 5, I'll store it and reply \"Got 5\".\n"}],"role":"model"},"usageMetadata":{"candidatesTokenCount":48,"candidatesTokensDetails":[{"modality":"TEXT","tokenCount":48}],"promptTokenCount":69,"promptTokensDetails":[{"modality":"TEXT","tokenCount":69}],"totalTokenCount":117},"invocationId":"e-9d07ce65-0072-4bdd-b852-806c0d1d200c","author":"CheckFive","actions":{"stateDelta":{"value1":"I'm designed to check for a specific number. Please provide an integer. If it's not 5, I'll exit. If it is 5, I'll store it and reply \"Got 5\".\n"},"artifactDelta":{},"requestedAuthConfigs":{}},"id":"4IBKiLKJ","timestamp":1749954632.572216},{"content":{"parts":[{"text":"Got 5\n\nNow ask for another integer. If it's not 7, exit; otherwise store it.\n"}],"role":"model"},"usageMetadata":{"candidatesTokenCount":25,"candidatesTokensDetails":[{"modality":"TEXT","tokenCount":25}],"promptTokenCount":168,"promptTokensDetails":[{"modality":"TEXT","tokenCount":168}],"totalTokenCount":193},"invocationId":"e-9d07ce65-0072-4bdd-b852-806c0d1d200c","author":"CheckSeven","actions":{"stateDelta":{"value2":"Got 5\n\nNow ask for another integer. If it's not 7, exit; otherwise store it.\n"},"artifactDelta":{},"requestedAuthConfigs":{}},"id":"LyRtDA05","timestamp":1749954633.633566},{"content":{"parts":[{"text":"12\n"}],"role":"model"},"usageMetadata":{"candidatesTokenCount":3,"candidatesTokensDetails":[{"modality":"TEXT","tokenCount":3}],"promptTokenCount":213,"promptTokensDetails":[{"modality":"TEXT","tokenCount":213}],"totalTokenCount":216},"invocationId":"e-9d07ce65-0072-4bdd-b852-806c0d1d200c","author":"Summer","actions":{"stateDelta":{"sum":"12\n"},"artifactDelta":{},"requestedAuthConfigs":{}},"id":"iVvKLVEE","timestamp":1749954634.426668}]

  • 文字数が多いので。JSコード追加, node.js 実行します
  • test3.js

const postSend = async function(){
  try{
    const item = {
      "appName": "seq_agent2",
      "userId": "u_456",
      "sessionId": "s_456",
      "newMessage": {
        "role": "user",
        "parts": [{
          "text": "I have two numbers: 5 and 7. Calculate and reply with their sum."
        }]
      }
    };
    const body = JSON.stringify(item);		
    const res = await fetch("http://localhost:8000/run", {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},      
      body: body
    });
    if(res.ok === false){
      console.error("Error, res.ok = NG");
      throw new Error("Error, res.ok = NG");
    }
    const json = await res.json();
    //console.log(json);
    //if(json[2]){
    //  console.log(json[2].actions);
    //}

  }catch(e){
    console.error("Error, postSend");
  }
}
postSend();


  • レスポンス
  • sub_agentの、a3 実行 (sub_agentの 3番目 )
  • プロンプトは 上記: I have two numbers: 5 and 7. Calculate and reply with their sum.
  • LLMの出力: 12 で正しいようです (5 + 7 の計算)

  • /run , tool指定実行の場合で、Agent返す 最後の配列に。返信が含まれるようです

https://google.github.io/adk-docs/get-started/testing/#local-testing

[{"content":{"parts":[{"functionCall":{"id":"af-e75e946d-c02a-4aad-931e-49e4ab859838","args":{"city":"new york"},"name":"get_weather"}}],"role":"model"},"invocationId":"e-71353f1e-aea1-4821-aa4b-46874a766853","author":"weather_time_agent","actions":{"stateDelta":{},"artifactDelta":{},"requestedAuthConfigs":{}},"longRunningToolIds":[],"id":"2Btee6zW","timestamp":1743712220.385936},{"content":{"parts":[{"functionResponse":{"id":"af-e75e946d-c02a-4aad-931e-49e4ab859838","name":"get_weather","response":{"status":"success","report":"The weather in New York is sunny with a temperature of 25 degrees Celsius (41 degrees Fahrenheit)."}}}],"role":"user"},"invocationId":"e-71353f1e-aea1-4821-aa4b-46874a766853","author":"weather_time_agent","actions":{"stateDelta":{},"artifactDelta":{},"requestedAuthConfigs":{}},"id":"PmWibL2m","timestamp":1743712221.895042},{"content":{"parts":[{"text":"OK. The weather in New York is sunny with a temperature of 25 degrees Celsius (41 degrees Fahrenheit).\n"}],"role":"model"},"invocationId":"e-71353f1e-aea1-4821-aa4b-46874a766853","author":"weather_time_agent","actions":{"stateDelta":{},"artifactDelta":{},"requestedAuthConfigs":{}},"id":"sYT42eVC","timestamp":1743712221.899018}]

knaka Tech-Blogknaka Tech-Blog

初級 Agent, Agent Clinet 画面

  • ADK と、React側は POST通信になります。
  • python が。良くわからない為。。
  • AIコーディング (claude code Pro版) で、ほぼ実装

環境

  • Agent Development Kit
  • Python 3.13.4 (windows)
  • node 20 (テスト用)
  • React
  • Typescript

  • 書いたコード

https://gist.github.com/kuc-arc-f/1a70d0d164aa7150e68b193856886d9d


  • tree
cd tool_sample_agent/
$ tree .
.
├── __init__.py
├── agent.py


  • .env
  • geminiの鍵
GOOGLE_GENAI_USE_VERTEXAI=FALSE
GOOGLE_API_KEY="key"

*  init.py

from . import agent

  • agent.py
import datetime
import random
from google.adk.agents import Agent

# get_random_number
# Returns a random number between 1 and 6
def get_random_number() -> str:
    """Returns a random number between 1 and 6.

    Returns:
        dict: status and result with random number.
    """
    random_num = random.randint(1, 6)
    return f"ランダムな数字: {random_num}"

# get_now_date
# Returns the current date in YYYY-MM-DD format
def get_now_date() -> str:
    """Returns the current date in YYYY-MM-DD format.

    Returns:
        dict: status and result with current date.
    """
    current_date = datetime.datetime.now().strftime("%Y-%m-%d")
    return f"今日の日付: {current_date}"

root_agent = Agent(
    name="tool_sample_agent",
    model="gemini-2.0-flash",
    description=(
        "Agent that provides random numbers and current date information."
    ),
    instruction=(
        "You are a helpful agent who can generate random numbers between 1 and 6, and provide the current date."
    ),
    tools=[get_random_number, get_now_date],
)

Agent UI 画面、React

  • React構成で、UI画面の作成
  • ADKの、API連携します。

  • 書いたコード

https://github.com/kuc-arc-f/rolldown_2ex/tree/main/mcp_react5


  • Agent
  • mcp_react5/src/agent/tool-sample-agent.ts

https://github.com/kuc-arc-f/rolldown_2ex/blob/main/mcp_react5/src/agent/tool-sample-agent.ts


  • プロンプト、参考
tool_sample_agent

knaka Tech-Blogknaka Tech-Blog

fastAPI + React , Google ADK

  • ADK と、fastAPI側は POST通信になります。

環境

  • fastAPI
  • Agent Development Kit
  • LLM= gemini
  • Python 3.13.4 (windows)
  • node 20 (テスト用)
  • React

書いたコード

https://github.com/kuc-arc-f/fastapi_1ex/tree/main/react_3


  • dev-start , port= 8080 で、起動する例です。
npm run build
uvicorn main:app --reload --port 8080

  • .env
  • ADK API接続
ADK_API_URL="http://localhost:8000"

  • ADK Agentは 前と同様です、カンタンな乱数を返却など。

https://gist.github.com/kuc-arc-f/1a70d0d164aa7150e68b193856886d9d


  • pip
pip install fastapi uvicorn sqlalchemy
pip install sqlalchemy
pip install "fastapi[all]" python-multipart
pip install requests

  • fisrtAPI バックエンド
  • react_3/main.py

https://github.com/kuc-arc-f/fastapi_1ex/blob/main/react_3/main.py


  • React 画面
  • react_3/src/client/home.tsx

https://github.com/kuc-arc-f/fastapi_1ex/blob/main/react_3/src/client/home.tsx



knaka Tech-Blogknaka Tech-Blog

GoLang + React , Google ADK

  • ADK と、GoLang側は POST通信になります。

環境

  • go version go1.24.4
  • Agent Development Kit
  • LLM= gemini
  • node 20 (テスト用)
  • React

書いたコード

https://github.com/kuc-arc-f/golang_2ex/tree/main/react10_adk


  • dev-start
npm run build
go run .

  • ADK Agentは 前と同様です、カンタンな乱数を返却など。

https://gist.github.com/kuc-arc-f/1a70d0d164aa7150e68b193856886d9d


  • API 実装
  • react10_adk/handler/handler.go

https://github.com/kuc-arc-f/golang_2ex/blob/main/react10_adk/handler/handler.go


  • agent 実行
func AdkRunHandler(w http.ResponseWriter, r *http.Request) {
		var req AdkRunReceiveItem
		err := json.NewDecoder(r.Body).Decode(&req)
		if err != nil {
			http.Error(w, "Invalid JSON", http.StatusBadRequest)
			return
		}
    //fmt.Fprintf(w, "受信したJSONデータ:\n")
    //fmt.Fprintf(w, "text: %s\n", req.RcvText)
    var url = ADK_API_URL + "/run"
    var sendText = req.RcvText
    resp, err := http.Post(
        url,
        "application/json",
        bytes.NewBuffer([]byte(sendText)),
    )
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, _ := io.ReadAll(resp.Body)

  //fmt.Println(string(body))
  w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(string(body))
}

  • 初期化、userId, sessionId送信
func AdkInitialHandler(w http.ResponseWriter, r *http.Request) {

		var req AdkInitialRequest
		err := json.NewDecoder(r.Body).Decode(&req)
		if err != nil {
			http.Error(w, "Invalid JSON", http.StatusBadRequest)
			return
		}
		jsonData, _ := json.Marshal(req)

		//fmt.Printf(&req)
		var url = ADK_API_URL + "/apps/" + req.AppName + "/users/" + req.UserId + "/sessions/" + req.SessionId
		
    resp, err := http.Post(
        url,
        "application/json",
        bytes.NewBuffer(jsonData),
    )

    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, _ := io.ReadAll(resp.Body)

  fmt.Println(string(body))
  fmt.Println("OK")
}

  • React 画面
  • react10_adk/src/client/Home.tsx

https://github.com/kuc-arc-f/golang_2ex/blob/main/react10_adk/src/client/Home.tsx


knaka Tech-Blogknaka Tech-Blog

Rust Axum + React , Google ADK

  • ADK と、Axum側は POST通信になります。

環境

  • rustc 1.88.0
  • cargo 1.88.0
  • node: 20
  • Agent Development Kit
  • Python 3.13.4
  • LLM= gemini
  • React

書いたコード

https://github.com/kuc-arc-f/axum_1ex/tree/main/react11_adk


  • dev-start
npm run build
cargo run

  • ADK Agentは 前と同様です

https://gist.github.com/kuc-arc-f/1a70d0d164aa7150e68b193856886d9d


  • agent 実行
  • react11_adk/src/main.rs

https://github.com/kuc-arc-f/axum_1ex/blob/main/react11_adk/src/main.rs

pub async fn adk_run_handler(
  State(state): State<AppState>,
  Json(payload): Json<AdkRunRequest>,
) -> Result<Json<serde_json::Value>, StatusCode> {

  let client = reqwest::Client::new();
  let path_s1 = String::from("/run");
  let url = ADK_API_URL.to_string() + &path_s1;
  println!("url={}", url);
  // JSON文字列をValue型にデコード
  let value: Value = serde_json::from_str(&payload.text).expect("REASON");
  println!("{}", &value );

  let client = reqwest::Client::new();
  let response: Result<reqwest::Response, Error> = client.post(url)
      .json(&value)
      .send()
      .await;

  match response {
    Ok(resp) => {
        let status = resp.status();
        println!("HTTP Status: {}", status.to_string());

        if status.is_success() {
          println!("Request was successful!");
          let body = resp.text().await.unwrap();
          return Ok(Json(json!({
            "status": 200,
            "body": &body.to_string(),
          })))
        } 
        else if status.is_client_error() {
          println!("Client error occurred!");
          let body = resp.text().await.unwrap();
          return Ok(Json(json!({
            "status": 400,
            "body": &body.to_string(),
          })))
        }
        else if status.is_server_error() {
          println!("Server error occurred!");
          let body = resp.text().await.unwrap();
          return Ok(Json(json!({
            "status": 500,
            "body": &body.to_string(),
          })))
        }
    }
    Err(err) => {
        eprintln!("Request failed: {}", err);
    }
  }      
  Ok(Json(json!({
      "status": 500,
      "body": "",
  })))
}

  • React 画面
  • react11_adk/src-ts/client/home.tsx

https://github.com/kuc-arc-f/axum_1ex/blob/main/react11_adk/src-ts/client/home.tsx

  const chatStart = async function(){
    try{    
      setText("");
      setIsLoading(false);
      const elem = document.getElementById("input_text") as HTMLInputElement;
      let inText = "";
      if(elem){
        inText = elem.value;
      };
      console.log("inText=", inText);
      if(!inText){ return; }
      setIsLoading(true);
      const agentName = AgentUtil.validAgentName(inText.trim());
      console.log("agentName=", agentName);
      if(agentName){
        let items = [];
        if(agentName === "tool_sample_agent"){
          items = toolSampleAgent();
        }
        console.log(items);

        let htmAll = "";
        const agentSendProc = async function(){
          for(const row of items) {
            htmAll += `<div class="label character-label w-full">${row.title}</div>`;
            console.log(row);
            let res = await AgentUtil.postAgent(row.text, "tool_sample_agent");
            console.log(res);
            htmAll += `<div class="chat-bubble character-bubble w-full">`;
            htmAll += marked.parse(res);
            htmAll +=  `</div>`
            //console.log(htmAll);
            setText(htmAll);
          };
          setIsLoading(false);
        }
        agentSendProc();
        return;
      }
    } catch(e){
      console.error(e);
    }
  }