温度は、冒険心のつまみのようなものです。下げると、はほとんどいつも、いちばんありそうな言葉を選びます。上げると、意外な言葉をもっとよく試します。top-k はつぼの中にいちばんありそうな候補を k 個だけ残し、top-p は確率の大きい順に足していき、合計が p 以上になる、いちばん小さな候補のグループだけを残します。
pwd # where am I?
ls # what is here?
mkdir ai-course # make a folder
cd ai-course # go into it (cd .. goes back up)
cat notes.txt # show a file
cp notes.txt copy.txt
mv copy.txt old.txt # move or rename
rm old.txt # delete for good (no recycle bin)
clear # clean the screen
claude # start an AI agent in this folder (or: codex, agy)
/init # inside the agent: write the project instruction file
/help # list the agent's commands
/exit # leave the agent
mkdir homepage && cd homepage
git init # save points from the first minute
claude # or: codex, agy
# then, inside the agent:
# "Make a one-page homepage in index.html for <who it is for>.
# Sections: <...>. Style: <...>. Plain HTML and CSS, works on a phone,
# no outside libraries. Show me the plan before you write."
git add index.html
git commit -m "first working homepage"
git restore index.html # throw away a change you do not like
# Direct Upload — run in the folder that has index.html
npx wrangler login
npx wrangler pages project create my-homepage
npx wrangler pages deploy ./ --project-name=my-homepage
# -> https://my-homepage.pages.dev
# Choose at the start: a Direct Upload project cannot switch to Git integration later.
# Flutter: build a signed Android App Bundle for Google Play
flutter build appbundle
# -> build/app/outputs/bundle/release/app-release.aab
# Keep the upload key and its passwords out of Git:
# android/key.properties
# *.jks
# Flutter on a Mac with Xcode: build the iOS archive for App Store Connect
flutter build ipa
# -> build/ios/archive/Runner.xcarchive (open it in Xcode)
# -> Xcode: Distribute App -> App Store Connect -> TestFlight first
# A website only wrapped in an app can be rejected (App Review Guidelines 4.2 — minimum functionality)
Claude Codeはのな(agentic coding tool)です。によって、ツール、、、のどれで呼んでも正しいです(どれがいつ合うかは「エージェントと」の章にあります)。で動き、コードエディタ、、Webでも使えます。プロジェクトフォルダで と入力すると起動します。コードを読み、コードについての質問に答え、ファイルを編集し、を実行します。
Claude Code はセッションを始めるたびに CLAUDE.md を読みます。新しいチームメンバーが、最初の朝にプロジェクトのハンドブックを読むようなものです。プロジェクトが何か、どうやってビルドしてテストするか、あなたのルールは何か。短くてわかりやすいハンドブックがあれば、同じことを何度も言わなくてすみます。
Claude Codeはファイルを編集したりコマンドを実行したりする前に確認を求め、その操作を1回だけ、このセッションの間、または常に許可するかをあなたが決めます。権限のルールは にあり、ではClaude Codeは何も変えずに読んで計画を提案するだけです。最初は厳しく始めて、信頼できるものだけをゆるめ、理解できないコマンドは決して許可しないでください。
"""
mcp-server.py: the smallest MCP server.
One tool, plain Python (standard library only), no SDK.
Who is who
MCP server This program. It offers tools (functions the AI
may use).
Host The app the user talks to (Claude Code, Codex).
It runs one MCP client for each connected server.
MCP client The part of the host that talks to this server
with JSON-RPC messages (here over stdio: one JSON
message per line).
Model The LLM (Claude Opus, GPT, ...). It never talks to
the server directly. It only talks to the host.
Flow
1. Discover tools
The client asks for the tools (tools/list). The server replies
with each tool's name, description and input schema.
2. Offer tools
The host sends the user's message to the model, together
with the tool list.
3. Model decides
The model answers directly, or asks for a tool call
(tool name + arguments). It never runs the tool itself.
4. Call the tool
The client sends the request to the server (tools/call).
5. Run the tool
The server runs the function and returns the result.
6. Model continues
The host gives the result back to the model. The model may
call more tools (3-6 again) or write the final answer.
Model Host (MCP client) MCP server
| | 1. tools/list ------> |
| | <------ tool list |
| <-- 2. message + tool list |
| 3. tool call --> | |
| | 4. tools/call ------> |
| | <------ 5. result |
| <-- 6. result | |
Rule for stdio servers: stdout carries protocol messages only.
Never print() anything else there. Write logs to stderr.
"""
import json
import random
import sys
SERVER_INFO = {"name": "strange-add-mcp", "version": "1.0.0"}
# The tool. The model reads the description to decide when to use it.
STRANGE_ADD = {
"name": "strange-add",
"description": "Add two numbers with a strange number.",
"inputSchema": {
"type": "object",
"properties": {
"a": {"type": "number"},
"b": {"type": "number"},
},
"required": ["a", "b"],
},
}
def strange_add(a, b):
"""Add a + b and a random number from 0 to 100 (always >= a + b).
The model cannot guess the answer, so a right answer proves
that the tool was really called.
"""
return a + b + random.randint(0, 100)
def handle(method, params):
"""Return the result for one request. Others (like ping) get {}."""
if method == "initialize":
# Use the client's protocol version and say "I have tools".
return {
"protocolVersion": params["protocolVersion"],
"capabilities": {"tools": {}},
"serverInfo": SERVER_INFO,
}
if method == "tools/list":
return {"tools": [STRANGE_ADD]}
if method == "tools/call":
args = params["arguments"]
total = strange_add(args["a"], args["b"])
return {"content": [{"type": "text", "text": str(total)}]}
return {}
def main():
# One JSON-RPC message per line comes in, one reply per line goes out.
for line in sys.stdin:
request = json.loads(line)
# No id means a notification: send no reply.
if "id" not in request:
continue
result = handle(request["method"], request.get("params", {}))
reply = {"jsonrpc": "2.0", "id": request["id"], "result": result}
# flush=True sends the reply at once.
print(json.dumps(reply), flush=True)
if __name__ == "__main__":
main()
mcp-client.sh
#!/bin/sh
# mcp-client.sh: the simplest MCP client, a shell script.
# It starts mcp-server.py, talks to it over stdio (one JSON-RPC
# message per line) and checks every reply.
# Exit code 0 means every check passed.
SERVER="python3 $(dirname "$0")/mcp-server.py"
# 1. Send the whole session at once and keep the replies.
# id 1 initialize agree on a version
# (no id) notifications/initialized "ready" (no reply)
# id 2 tools/list which tools are there?
# id 3 tools/call run strange-add(2, 3)
# id 4 ping is the server alive?
replies=$(
$SERVER <<'EOF'
{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2025-06-18", "capabilities": {}, "clientInfo": {"name": "shell-mcp-client", "version": "1.0.0"}}}
{"jsonrpc": "2.0", "method": "notifications/initialized"}
{"jsonrpc": "2.0", "id": 2, "method": "tools/list"}
{"jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": {"name": "strange-add", "arguments": {"a": 2, "b": 3}}}
{"jsonrpc": "2.0", "id": 4, "method": "ping"}
EOF
)
echo "--- Server replies ---"
echo "$replies"
echo "--- Checks ---"
failed=0
# 2. check <label> <reply id> <text the reply must contain>
check() {
reply=$(echo "$replies" | grep -F "\"id\": $2,")
if echo "$reply" | grep -qF "$3"; then
echo "PASS $1"
else
echo "FAIL $1 (expected: $3)"
failed=1
fi
}
check "initialize: protocol version" 1 '"protocolVersion": "2025-06-18"'
check "initialize: server info" 1 '"serverInfo": {'
check "initialize: has tools" 1 '"capabilities": {"tools": {}}'
check "tools/list: strange-add" 2 '"name": "strange-add"'
check "ping: empty result" 4 '"result": {}'
# 3. strange-add adds a random 0 to 100,
# so the answer only has to be >= 2 + 3.
total=$(echo "$replies" | grep -F '"id": 3,' |
sed 's/.*"text": "\([0-9]*\)".*/\1/')
if [ "$total" -ge 5 ] 2>/dev/null; then
echo "PASS tools/call: strange-add(2, 3) >= 5 (got $total)"
else
echo "FAIL tools/call: strange-add(2, 3) >= 5 (got $total)"
failed=1
fi
exit $failed
ターミナルで入力するコマンド
# put the two files above into one folder
mkdir -p ~/tmp/mcp && cd ~/tmp/mcp
# mcp-server.py mcp-client.sh
# 1) test the server without any AI
sh mcp-client.sh # -> 6 x PASS, exit code 0
# 2) connect it to Claude Code (no --scope: the "local" scope)
claude mcp add strange-add -- python3 ~/tmp/mcp/mcp-server.py
claude mcp list # strange-add: ... - Connected
claude mcp get strange-add # Scope: Local config
# 3) where it was saved: NOT in this folder (no new file here)
# ~/.claude.json -> projects -> "<this folder>" -> mcpServers
jq '.projects["'"$PWD"'"].mcpServers' ~/.claude.json
# 4) use it: start Claude Code in THIS folder
claude # "Use strange-add to add 2 and 3"
# -> not 5 (e.g. 61): the tool ran
claude mcp remove strange-add -s local
Claude Code にサーバーがないとき: ちがうフォルダーで Claude Code を起動しています。local スコープは、claude mcp add を実行したフォルダーのものです。~/.claude.json を確かめて、そのフォルダーで Claude Code を起動するか、--scope user でサーバーを加え直しましょう。
Claude Codeでは、が終わるたびに別の小さなが会話を読んで判定します。まだなら作業を続け、達成した、または不可能と判断したらゴールを消します。このモデルはコマンドを実行せず、ファイルも読まないので、テスト結果のように会話に出たもので証明できるゴールラインを書きましょう。状態には、これまでの時間・ターン数・が表示されます。
# Claude Code — keep working until a finish line you can check is met
/goal All tests in tests/ pass and the homepage loads without errors, or stop after 20 turns
/goal # show the condition, turns and tokens
/goal clear # remove it before it is met
claude -p "/goal CHANGELOG.md has an entry for every PR merged this week"
# Codex — the same idea, plus pause and resume
/goal All tests in tests/ pass and the homepage loads without errors
/goal # show the goal and its status
/goal pause # also: /goal resume, /goal clear
# Claude Code plugin — Ralph Loop: the same prompt again and again, with limits
/ralph-loop "Fix the failing tests in tests/. Say DONE only when all pass." --completion-promise "DONE" --max-iterations 5
ssh user@address # log in with an SSH key, not a password
tmux new -s agent # open a session called "agent"
claude # start the agent with a goal and a limit
# press Ctrl+b, then d -> detach; the agent keeps working
exit # log out — the session stays on the server
ssh user@address
tmux ls # list sessions
tmux attach -t agent # back to the same screen
tmux kill-session -t agent # stop it for good
「The cat sat because it was tired」(猫は疲れていたので座った)で、モデルが「it」まで来ると、そのクエリは「cat」のキーと強く合います。そのため「cat」のバリューの多くが「it」に流れ込みます。大きくてよく学習されたモデルなら、アテンションの重みを表示すると「cat」の横に大きな数が出るはずです。この章の小さなでは、アテンションが近くの文字に集まるのが見えます。
# a runner on your computer: download a small open model and chat
ollama run llama3.2:1b
# the same runner as a local API — no key, nothing leaves the machine
curl http://localhost:11434/api/generate -d '{
"model": "llama3.2:1b",
"prompt": "Explain a token in one sentence.",
"stream": false
}'
# your own nanoGPT: train it with the GPT-2 tokenizer (data/shakespeare, not shakespeare_char)
# and save the weights as a Hugging Face GPT-2 folder (./my-model) — then it converts like any model
# llama.cpp: model folder -> GGUF (16-bit) -> 4-bit Q4_K_M
python convert_hf_to_gguf.py ./my-model --outfile my-model-f16.gguf
./llama-quantize my-model-f16.gguf my-model-Q4_K_M.gguf Q4_K_M
ls -lh my-model-*.gguf # about four times smaller
# quick way: copy my-model-Q4_K_M.gguf into an offline chat app (e.g. PocketPal AI)
# builder's way: embed a runner in your app (llama.rn, a llama.cpp binding) and load the file