A2A ç°¡ä»
ç°¡ä»
A2A (Agent2Agent) éè¨å宿¨å¨å° AI Agent ä¹éçéè¨æ¨æºåã
2025 å¹´ 3 æï¼IBM Research æ¨åº Agent Communication Protocol (ACP)
2025 å¹´ 4 æï¼Google å¨ Google Cloud å¹³å°ä¸æ¨åº A2A åå®ã
2025 å¹´ 9 æï¼æ£å¼å®£ä½ ACP ä½µå ¥ A2Aã䏦尿²»çæ¬å®å ¨ç§»äº¤çµ¦ Linux åºéæã

User åè² è²¬èçäºåç Client Agent æåºéæ±ï¼æ¥è該 Client Agent éé A2A ä½çºæºéæ©æ¨ï¼å°èªèº«ç¡æ³èççä»»åå§è¨çµ¦å°éè² è²¬å¯¦éå·è¡ç Remote Agent ä¾åå©å®æã
Quick Walk-through

ä¸ç¾¤ AI Agent å使ï¼é¦å éè¦ç¸äºç¼ç¾ä¸¦äºè§£å½¼æ¤çåè½ï¼å¯ä½¿ç¨ Agent Card å° Agent çæè¿°æ¨æºåã
ç¶ Client Agent æ¾å°äº Remote Agentï¼éæ¹è¦å¦ä½å°è©±ï¼

Remote Agent ç Agent card ä¸å®ç¾©äº URI å Protocol binding (ex: JSONâRPCãgRPC/protobuf)ï¼Client Agent å¯ä»¥ä¾æ¤ç¼åºè«æ±ã
Agent éè¨æ 4 種模å¼
- Synchronous
- Asynchronous
- Streaming
- Push Notification
Synchronous 模å¼

Client Agent æå å³éä¸å Message ç©ä»¶ï¼ä¸å Message 代表å°è©±ä¸çä¸å輪次ã
Message ä¸å å« Roleï¼å Partsã
Part æ¯å¯¦éçå §å®¹ï¼å¯ä»¥æ¯ç´æåãæªæ¡ãmulti-model dataï¼æ structured JSONã
ç¶ Remote Agent æ¥æ¶å°ä¾èª Client Agent çè«æ±æï¼å¦æè©²è«æ±é常簡å®ä¸è½å¿«é宿ï¼Remote Agent å¯ä»¥ç´æ¥åè¦ Client Agent ä¸åå å«è§£çåæç Messageã
Asynchronous 模å¼

ç¶ä»»åéè¦è±äºæéï¼Remote Agent å¯ä»¥ä¸åè¦è¨æ¯ï¼èæ¯åè¦ä¸å Task ç©ä»¶ãéåä»»åå ·æ IDï¼ä»¥å Statusã
Status æç¤ºäº Task çå½é±æçç¶åéæ®µï¼å å«
- submitted
- working
- input required (ç¶ Remote Agent éè¦ User æä¾æ´å¤è³è¨æ)
- completed
- failed
Client Agent å¯ä»¥éé polling æ¹æ³ä¾å¾ç¥ Task çææ°çæ ã
ç±æ¼æ¯ Remote Agent 決å®è¦åå³ message 鿝 taskï¼æä»¥ Client Agent å¿ é éå ©ç¨®æ æ³é½è½èçã

æçµï¼Task 宿å¾é²å ¥ completed ççæ ï¼èä»»åç輸åºçµæå°ææ¾å¨ artifacts æ¬ä½ä¸ã
Artifacts æ¯é¡ä¼¼æ¼ Message ççµæ§ï¼å®å忍£å ·æä¸å Artifact ID 以å Parts å §å®¹çæ®µï¼å ¶ä¸å å«äºå¯¦éçåæå §å®¹ã
Streaming 模å¼

polling task å¨ç°¡å®çæ æ³ä¸éä½è¯å¥½ï¼ä½å¦ææ³è¦å¿«éç²å¾æ´æ°ï¼é䏦䏿¯é常ææçã
A2A æ¯æ´ä½¿ç¨ SSE (Server-Sent Events) é²è¡ streamingã 妿 Remote Agent ç Agent card è¼ææ¯æ´ streamingï¼Cient Agent å°±å¯ä»¥ä½¿ç¨ SSE æ¹æ³éè¨ï¼Server Agent å¯ä»¥å¨æ´æ°ç¼çæå³æå³çµ¦ Client Agentã
éäºæ´æ°å¯ä»¥æ¯
- task object
- status update events 忝 èçä¸ æä»»å已宿ç
- artifact update events ç¢åºç©æ´æ°äºä»¶
妿 Artifact çµæè³æè¼å¤§ï¼ä¾å¦ä¸ä»½é·ç¯æè¦ï¼Server Agent å¯ä»¥å°å ¶é²è¡ä¸²æµå³éã
使ç¨è å¯ä»¥çå°å³æçé²åº¦æ´æ°ï¼æè å¨çæ¡çæçåæçå°å®éæ¥åç¾ã
Push Notification 模å¼

è¥ Remote Agent ç Agent card è¼ææ¯æ´ pushNotificationsï¼
Client Agent å¯ä»¥æä¾ callback URLï¼
Remote Agent å¯ä»¥ä¸»åå°éç¥ task çæ è®åï¼æ artifact å·²æºå宿.
Agent Card
å¨ A2A agent å·è¡ä»»ä½æä½ä¹åï¼å®éè¦å®ç¾©èªå·±è½åä»éº¼ï¼Agent Skillï¼ï¼ä»¥åå ¶ä» agents æ clients å¦ä½å¾ç¥éäº capabilitiesï¼Agent Cardï¼ã
Agent Skill: æè¿°äº Agent è½å¤ å·è¡çç¹å® capability æ functionã宿¯æ§æ Agent çåºæ¬ building blockï¼ç¨æ¼åç¥ clients 該 Agent æ é·èçåªäºé¡åç tasksã
Agent Card: ä¸ä»½ç± A2A Server æä¾ç JSON documentï¼éå¸¸åæ¾æ¼ .well-known/agent-card.json endpointãå®å°±åæ¯è©² Agent çæ¸ä½åçã
{
"capabilities": {
"streaming": true
},
"defaultInputModes": [
"text"
],
"defaultOutputModes": [
"text"
],
"description": "Just a hello world agent",
"name": "Hello World Agent",
"preferredTransport": "JSONRPC",
"protocolVersion": "0.3.0",
"skills": [
{
"description": "just returns hello world",
"examples": [
"hi",
"hello world"
],
"id": "hello_world",
"name": "Returns hello world",
"tags": [
"hello world"
]
}
],
"supportsAuthenticatedExtendedCard": true,
"url": "http://localhost:9999/",
"version": "1.0.0"
}
Opaque return types
ç´é Opaque types çä¸äºè³è¨ã
struct ContentView: View {
var body: some View {
Text("hello world")
}
}
public protocol View {
/// The type of view representing the body of this view.
associatedtype Body : View
/// The content and behavior of the view.
@ViewBuilder var body: Self.Body { get }
}
æ¤ ContentView å®ç¾© body ç Read-Only computed propertiesï¼getter åå³ some Viewï¼æå符å View protocol çåå¥ï¼ç¨±çº Opaque typeã
å®ç¶²å®ç¾©ï¼
A function or method with an opaque return type hides its return valueâs type information. Instead of providing a concrete type as the functionâs return type, the return value is described in terms of the protocols it supports. Hiding type information is useful at boundaries between a module and code that calls into the module, because the underlying type of the return value can remain private. Unlike returning a value whose type is a protocol type, opaque types preserve type identityâthe compiler has access to the type information, but clients of the module donât.
ç±ä»¥ä¸èªªæå¯ç¥ï¼Opaque return type å¯ä»¥é±èåå¥è³è¨ã
æåå¯ä»¥èè以䏿¹æ³ä¾å¾ç¥ç實ç body åå¥è³è¨ãå¨éåä¾åä¸ï¼ç實åå³çå奿¯ VStack<Button<Text>>ã
struct ContentView: View {
var body: some View {
VStack {
Button("print my type") {
print(type(of: self.body))
// VStack<Button<Text>>
}
}
}
}
SwiftUI NavigationLink lazy loading
ç´éä¸å SwiftUI çååè§£æ³ã
NavigationLink ç destination æç«å³è¢«åµå»ºï¼å¨éæ²æå¯¦éæä¸æéä¹åã
æ¤æè¥æåäºè¤éçè¨ç®åæè¢«ç«å³å·è¡â¦ (ä¾ç
§ SwiftUI çæç¶é輯æè©²å»¶å¾æ¤è¤éæä½)ã
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink {
// Create immediately.
// What if need some expensive computation here...
Text("detail view")
} label: {
Text("show detail view")
}
}
}
}
è§£æ³ 1 : onAppear
å¨ destination åºç¾ææå·è¡è¤éçæä½ã
å¦å¤è¦æ³¨æ View åè¦å¤æ¬¡åºç¾çæ
æ³ã
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(
// Destination created immediately.
destination: {
Text("Detail View")
.onAppear {
// do expensive computation at onAppear
}
},
label: { Text("show detail view") }
)
}
}
}
è§£æ³ 2 : Lazy loading
View ç body å¨è¢«é¡¯ç¤ºçæåææå·è¡ï¼
æä»¥å¯ééå¦ä¸å Wrapper View æ destination çåµå»ºï¼ç¨ closure å³å
¥ï¼å»¶å¾å° Wrapper View ç body 被å·è¡æã
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(
destination: { LazyView(<...
WWDC 2021 Get ready to optimize your App Store product page
å¨ WWDC 2021 ä¸ï¼æç¼ä½æªä¾ AppStore å°æçæ°åè½ãä¹è¨±è· Developer ç¡ç´æ¥ç¸éï¼ä½å¾ç¢åæ¨å»£çè§åº¦ä¸å¾æå¹«å©ãåå¥çº
- Custom product pages
- Product page optimization

Custom product pages

é¤äºé è¨çç¢åé ä¹å¤ï¼å¯ä»¥è¨è¨é¡å¤ç custom product pageï¼å»å®¢è£½åé 覽影çï¼è¢å¹æªåï¼é½å¯ä»¥åèªè¨å°æã
徿尿ç覽ä¾ç使ç¨è
ï¼æé²å°é è¨ç¢åé ï¼èå¾å°å±¬çé£çµé²ä¾ç使ç¨è
ï¼åæé£å°å®¢è£½åçç¢åé ã
ç¶å¾å¯ä»¥åæå¨é樣çæ
æ³ä¸åèªç
- Impression
- Downloads
- Conversion rate
- Retention
- Average proceeds per paying user
æå¤å¯ä»¥å»ºç« 35 å客製åç¢åé ï¼è䏿¤æµç¨ä¸éè¦éæ°ä¸å³ Appï¼åªéè¦å¯©æ ¸ç¢åé ã
Product page optimization
èå¨é è¨çç¢åé ä¸ï¼å¯ä»¥è¨å®ä¸åçµåï¼æç¨± bucket or A/B testingï¼ä¾åªåä¸è¼è½æçã
å¦åä¸ï¼å³éçç´
è² App Icon æè¼é«çè½æçï¼åå¯ä»¥èæ
®ä¿®æ¹ç¢åé ã

è½å¤ è®åçé¨åï¼æ App Iconï¼è¢å¹æªååé 覽影çã
æå¤å¯ä»¥ååºä¸å treatments çµåï¼ç¶å¾è¨å®åèªåºç¾å¨ä½¿ç¨è
ç®åçæ©çï¼åä¸è¨å®æ©ççºå 10%

App Icon æ¯éè¦ç使ç¨è
é«é©ï¼ä¹ææ¯è¦ä¸è¦æé App çéè¦ééµãå¾ A/B testing çåç¾ä¸è¼å¾ç App Iconï¼æç¶æèè·ç¶å AppStore ç¢åé çµåä¸è´ç樣å¼ã

å¯ä»¥æå®éå°ç¹å®èªç³»ç AppStore ç¢åé ååªåã
è¦éä¸çµæ°ç A/B testing ä»ç¶è¦éå¯©æ ¸ï¼ä½ä¸ç¨ä¸å³æ°ç binaryã
å¦æè¦æ¸¬è©¦ App Icon çä¸åçµåï¼åè¦äºå
æææç Icon æ¾å¨ binary ä¸ãæçµé è¨ç App Icon å¦æè¦æ´æç話ï¼ä»ç¶è¦å¨ä¸ä¸åæ°çæ¬ç binary 䏿´æã
æå¾ï¼ä¸è¿°ç Custom product pages 以å Product page optimization é½ææ¯æ´ App Store Connect API.
è½å¤ é 35 å custom product pageï¼æåèçææ¯å ´ç½é£ï¼åç¨ API èèªååæè½å°æçæå°æé«ã
Reference
Bazel cache behind the scenes
Bazel did a great help on speedup build by remote cache, letâs see how it works behind the scenes.
Show Bazel logs
Turn on bazel logs, we could take a closer look at how Bazel works, and do some analysis.
Here are some options to turn on the logs.
-
âdisk_cache=<a path>:
A path to a directory where Bazel can read and write actions and action outputs. If the directory does not exist, it will be created.
-
âexecution_log_binary_file=<a path>:
Log the executed spawns into this file as delimited Spawn protos.
-
âexecution_log_json_file=<a path>:
Log the executed spawns into this file as json representation of the delimited Spawn protos.
Letâs try the following command.
bazel build //BazelDemo --disk_cache=./local_cache --execution_log_json_file=./json.log
Based on Bazel document,
there are 2 types of cache data.
- The action cache, which is a map of action hashes to action result metadata.
- A content-addressable store (CAS) of output files.
So the folder will also have 2 sub-folders, ac and cas.

Take a look at the cas files by command: file local_cache/cas/*/*, it will shows result as

Before dive right in to see what are these, letâs read more about the build process.
Xcode Build Process
From 2018 WWDC - Behind The Scenes of The Xcode Build Process, the xcode build process could roughly split into compiling, processing, linking.

The compiler compiles source code into Mach object file (Mach-O)

The linker links .o files together as final executable output.

Flutter Plugins Ordering Issue and Solution
About
Flutter plugins 被註åçé åºï¼æå½±é¿å° plugin code å·è¡çé åºï¼é²èå¯è½æé æç¬¬ä¸æ¹ç»å
¥å¤±æï¼æç¡æ³æ£ç¢ºå°æ¶å° deep link çå¼å«ã
Android å iOS ç Flutter ä¾èªåä¸å Engineï¼æä»¥åæ¨£é½æè¼å
¥é åºçåé¡ã
æ¬ç¯æ³ç´éå顿¢è©¢çéç¨ï¼ä»¥åè§£æ±ºçæ¹æ³ã
Issue Intro
iOS ä¸ï¼å
¶ä¸ä¸åèçå¾å¤é¨å¼å« App ç callback function æ¯ application(_:open:options:)ã
常è¦ç實ä½å¦ä¸ï¼
// sample code
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey: Any] = [:]) -> Bool {
if FacebookLogin.handle(url) {
return true // èç Facebook ç»å
¥
} else if LineLogin.handle(url) {
return true // èç LINE ç»å
¥
} else if FirebaseDynamicLinks.handle(url) {
return true // èç Firebase Dynamic Links
} else {
return AppRouter.handle(url) // å°éå deeplink urlï¼å¨ App å
§é¨ä½¿ç¨ webview æä½¿ç¨æ°ç native ç«é¢åç¾
}
}
ä¸åå¼å« App èµ·ä¾ç urlï¼åªæå±¬æ¼ä¸ç¨®æ
æ³ãé常æå¨èçå®ç»å
¥åç¹æ®ç deeplink (ex: FirebaseDynamicLinks) ä¹å¾ï¼æä½¿ç¨ App å
§ç Router ä¾åç¾éå urlã
æ¤æ code çé åºæå
¶å¿
è¦ï¼æåç¾ url æ¾å¨æå¾ã
èå¨ Flutter ä¸ï¼plugin æå¯¦ä½ FlutterPlugin ç protocol registerWithRegistrar:registrarã
å¨å
¶ä¸ï¼plugin è· Flutter ä½¿ç¨ addApplicationDelegate: 註åï¼è²æèªå·±è¦èç UIApplicationDelegate çå¼å«ãæ¤æè¥å¤å plugin é½æè²æï¼åéåé åºæ¯å¦ä½è¢«æ±ºå®çå¢ï¼
Solve the issue about cannot open iOS simulator in Android Studio
Start using Flutter in our new project. Record some of the issues and solutions.
One of the weird things that happened recently, is that although iOS simulator is opened, it still cannot be selected as deploy target in Android Studio. The opened iOS simulator not shown in the list.

At this time, try to check the simulator version, with the current selected Xcode version.
xcode-select -p
/Applications/Xcode-11.3.app/Contents/Developer
// Should be same as opened simulator version as below image.

WWDC 2019 æèèå
é»ä¹æ
åé£åç¸ç¶å¿ç¢ï¼ä¹ééäºå
§é¨çå¯©æ ¸ç¨åºï¼WWDC 2019 çåèå¿å¾çµæ¼ç¼ä½å¨å
¬å¸ç LINE Engineering Blog ä¹ä¸äºã
æè¬å
¬å¸è´å©ï¼åä¾å¾å種 Sharing ä¹ç¸ç¶ç´®å¯¦ã
- å
§é¨ 4 å ´ Sharing
- å¤é¨ Meetupï¼iOS @ LINE @ Taipei
- 䏿 Blogï¼WWDC 2019 æèèå
é»ä¹æ
- è±æ Blogï¼ä¹å¾æ¾æéè½è²¼ä¸ä¾
ç¸ç¶ç²¾å¯¦çææï¼æ¯å¤©é½å¨è· Labï¼æå¾è·ç¸½é¨åäºåä¸èµ·å®æäºä¸å¤§å¼µ Sheet ç Lab Q&A ä»»åãèåååå è
交æµï¼ä¹å¤èªèäºæ¥æ¬èéåçåäºãç¾å¨é¸çºè£ Session çéå½±ä¸ã
WWDCï¼æå¾
åè¦é¢ï¼
SwiftUI dyld Library not loaded
ç´éä¸å踩å°ç Apple Known Issueã
å çº SwiftUI æ¯ iOS 13 ä»¥ä¸ææ¯æ´ï¼æä»¥ä½¿ç¨å¨æ¢æçå°æ¡è¦å ä¸çæ¬ç夿·: @availableã
@available(iOS 13.0, *)
struct ContentView: View {
var body: some View {
Text("Hello")
}
}
å³ä½¿å ä¸äºéåä¿è·ï¼ä½å»å¨ iOS 12 ç實æ©éå°äº Crashã
dyld: Library not loaded: /System/Library/Frameworks/SwiftUI.framework/SwiftUI
Reason: image not found
æ¥äºä»¥å¾æç¥é鿝åå·²åå¨ Release Notes çåé¡ã
è§£æ³çºå ä¸ -weak_framework SwiftUI flag to the Other Linker Flags setting in the Build Settings tabã

https://developer.apple.com/documentation/ios_ipados_release_notes/ios_13_release_notes
Apps containing SwiftUI inside a Swift package might not run on versions of iOS earlier than iOS 13. (53706729)
Workaround: When back-deploying to an OS which doesnât contain the SwiftUI framework, add the -weak_framework SwiftUI flag to the Other Linker Flags setting in the Build Settings tab. See Frameworks and Weak Linking for more information on weak linking a framework. This workaround doesnât apply when using dynamically linked Swift packages which import SwiftUI.
Hello World
2019-09-03
Blog é£è¼åé :p
ä¸ç´æ³å¾ http://cj-lin.logdown.com æ¬å®¶åºä¾ï¼ä½çºä¸åæ¯æ´ Markdown 䏿æ¼ä½¿ç¨ç Blog ä¾èªªï¼logdown å¨ç¶æçç¢ºç®æ¯æ»¿é æçï¼å¥ä½å¾ä¾å·²ç¶åæ¢æ´æ°äºã
æ¥ä¸ä¾å°±ä¸ç¯ä¸ç¯å°å份åºä¾å§ã
ææéå Blog æçºç´éæè¡è·¯ä¸éå°ç黿»´ï¼åæä¸äºå¤§è
¦çè¨æ¶é«ã
Put the ++ and -- operators back at Swift
Swift had remove the ++ and -- operators for the reason that it might be confusing to users.
Reference: Proposal from Chris Lattner
extension Int {
static prefix func --(i: inout Int) -> Int {
i -= 1
return i
}
static prefix func ++(i: inout Int) -> Int {
i += 1
return i
}
static postfix func --(i: inout Int) -> Int {
let n = i
i -= 1
return n
}
static postfix func ++(i: inout Int) -> Int {
let n = i
i += 1
return n
}
}
Just saw this extension, now we get to use these handy operators yet again. :p
About typeof in Objective-C
2018-01-18
I want to share something about my misunderstanding about typeof.
The story goes from my pull request to mopub repo.
I found following code occurs in a block.
It seems not using weakSelf for weak-strong dance, but capturing self by the __typeof__(self).
__strong __typeof__(self) strongSelf = weakSelf;
So I create a pull request and change it to
__strong __typeof__(weakSelf) strongSelf = weakSelf;
In fact, my PR had a mistake. The typeof, __typeof and __typeof__ are compile-time flag. Thus self in this block is not retained.
Another thing is that, __typeof__(weakSelf) is not a good pattern.
This will carry __weak attribute, thus we need an explicit __strong attribute to overwrite it.
Thus using __typeof__(self) is better, to prevent accidentally creating a strongSelf which is actually not.
Symbolic breakpoint at UIViewController dealloc
2017-09-04
å¯¦ç¨ Symbolic breakpoint, å°æ¼æåº memory leak 徿幫å©ã
--- dealloc @(id)[$arg1 description]@ @(id)[$arg1 title]@

Reference: https://twitter.com/0xced/status/900692839557992449
Use Branch.io to implement App Banner and Deep Link
2016-01-27
éç¯ç¶²èªä¸»è¦æ¯èªªæçºä½æè©²ä½¿ç¨ Branch ä¾å¯¦ä½ Smart App Banner å Deep Linkï¼ä»¥å Web 端çè¨å®æ¹æ³ã
Smart App Banner Intro
Smart App Banner è½æé«ç¶²é å° App çè½æçï¼å¦ä¸æ¹éåã
æä¸ banner åä½å¾
- å¦ææ²æå®è£ Appï¼è·³è½å° AppStore 以便使ç¨è
é²è¡ä¸è¼ã
- 妿已å®è£ Appï¼åè·³è½æé App

Simulate default GPS location
2014-10-14
Product -> Scheme -> Edit Scheme â¦-> Run -> Options -> Default Location

å¨ NSLog ä¸å°åºæå¨ç class å method
2014-10-07
NSLog(@"<%@:%@:%d>", NSStringFromClass([self class]), NSStringFromSelector(_cmd), __LINE__);
NSLog(@"%s", __PRETTY_FUNCTION__);
UIDynamic Animator
2014-08-15
Set up physics relating animatable objects and let them run until they resolve to stasis
Easily possible to set it up so that stasis never occurs, but that could be performance problem