WEEK 04

통신 언어: 화행에서 FIPA-ACL까지 Communication Languages: From Speech Acts to FIPA-ACL

에이전트가 보내는 메시지는 데이터인가, 행위인가? 1990년대의 에이전트 통신 언어는 메시지마다 performative(화행의 종류)를 붙이고 그 뜻을 논리로 정의했다. 같은 가격 협상을 세 가지 메시지 형식으로 돌려, performative를 붙인 형식이 정답 여부, 한도 위반, 메시지 수, 파싱 실패, reader 호출 수에서 어떻게 달라지는지 잰다.

01

오늘의 구성

구분내용
A1화행 이론: 말은 행위다
A2KQML과 FIPA-ACL: 메시지 구조와 의미론
A3FIPA-ACL의 네 가지 한계와 LLM, 재현 실험 설계
토론자연어 content와 ontology 문제
LABbuyer 1 + seller 1, 메시지 형식 3종 비교 실험
PART A: LECTURE

에이전트 통신 언어: 메시지마다 performative를 붙인다

A1 speech acts, A2 KQML and FIPA-ACL, A3 four limits and the LLM, discussion
A1

화행 이론: 말은 행위다

3주차 Contract Net의 메시지는 task-announcement, bid, award처럼 종류가 정해져 있었고, 메시지가 무엇을 하는지는 이름에 들어 있었다. 이 생각을 메시지 일반으로 넓힌 것이 에이전트 통신 언어(agent communication language, ACL)다. J. L. Austin은 1955년 하버드 William James 강연(1962년 How to Do Things with Words로 출간)에서 “이 배를 Queen Elizabeth호라 명명한다” 같은 문장을 들었다. 이 문장은 참도 거짓도 아니다. 적절한 사람이 적절한 자리에서 말하면 배의 이름이 실제로 그렇게 정해진다. Austin은 이런 문장을 수행문(performative)이라 불렀다.

Austin은 나아가 모든 발화를 세 행위로 나눴다. 문장을 소리 내어 말하는 것이 locutionary act, 그 말로 무엇을 하는가(알리기, 요청하기, 약속하기)가 illocutionary act, 그 말이 듣는 쪽에 실제로 일으키는 효과(믿게 되기, 설득되기)가 perlocutionary act다. “가격은 120이다”라는 같은 문장이 알림(inform)일 수도 있고 제안(propose)일 수도 있다. 에이전트 통신 언어가 메시지에 붙이려 한 것은 이 가운데 두 번째, illocutionary force다.

FIG. 01의 문장으로 셋을 나누면 이렇다. buyer가 “I can go to 120 for the bicycle”이라고 말한 것, 곧 단어와 문법과 120이라는 숫자가 locutionary act다. 그 말로 buyer가 한 일이 illocutionary act다. 자기 한도를 알린 것(inform)일 수도, 120에 사겠다는 제안(propose)일 수도, seller가 방금 부른 120에 동의한 것(accept-proposal)일 수도 있다. 그 말을 듣고 seller가 믿거나, 팔기로 하거나, 자리를 뜨는 것이 perlocutionary act다. 이 메시지를 받은 프로그램은 두 번째를 알아야 다음 일을 정한다. inform이면 상대 한도를 기록하고, propose면 받을지 판단하고, accept-proposal이면 거래를 성립시킨다.

화행(speech act)은 문장을 말함으로써 수행하는 행위다. 같은 문장도 알림, 요청, 약속, 제안 가운데 무엇으로 말했는지에 따라 다른 행위가 된다.

J. L. Austin, How to Do Things with Words (1962). 원문은 “to utter the sentence (in, of course, the appropriate circumstances) is not to describe my doing of what I should be said in so uttering to be doing or to state that I am doing it: it is to do it.”

John Searle은 1975년 “A Taxonomy of Illocutionary Acts”에서 illocutionary act를 다섯으로 나눴다. 기준은 말과 세계 가운데 어느 쪽이 어느 쪽에 맞춰지는가(direction of fit)다. 진술 “가격은 120이다”는 세계가 그렇지 않으면 말이 틀린 것이고, 요청 “120에 팔아 달라”는 세계가 그렇게 되지 않으면 요청이 이행되지 않은 것이다.

assertives말이 세계를 따라간다. 진술, 보고. 참과 거짓을 물을 수 있다.
directives세계를 말에 맞추려 한다. 명령, 요청, 질문.
commissives말한 쪽이 자기 미래 행동을 말에 맞춘다. 약속, 제안.
expressives심리 상태를 표현한다. 감사, 사과.
declarations말하는 것으로 세계가 바뀐다. 명명, 해고. 그럴 권한을 주는 제도가 전제된다.

실습의 네 행위 가운데 propose와 accept-proposal은 자기 미래 행동을 거는 commissives다. FIPA는 넷 다 “내 의도가 이렇다”를 inform하는 행위로 정의하므로 FIPA 안에서는 넷 다 assertive 계열이 된다.

이 분류가 AI로 들어온 경로는 Philip Cohen과 C. Raymond Perrault의 1979년 “Elements of a Plan-Based Theory of Speech Acts”다. 두 사람은 화행을 전제조건과 효과를 가진 계획 연산자(plan operator)로 적었다. 계획 연산자는 로봇 계획에서 쓰는 행동 기술 형식으로, “문을 열려면 열쇠가 있어야 하고(전제조건), 열고 나면 문이 열려 있다(효과)”처럼 적는다. 말을 같은 형식으로 적으면 에이전트는 “상대가 가격을 알게 하려면 inform을 보낸다”처럼 발화를 이동이나 조작과 같은 행동으로 계획할 수 있다. request의 전제조건은 “말하는 쪽이 듣는 쪽이 그 행동을 하기를 원한다”이고, 효과는 “듣는 쪽이 그 원함을 안다”이다. 20년 뒤 FIPA가 performative마다 적은 feasibility precondition과 rational effect가 이 형식이다.

UTTERANCE AUSTIN 1962 FIPA-ACL 2002 “I can go to 120 for the bicycle.” locutionary act illocutionary act perlocutionary act :content performative rational effect the sentence said what is done in saying it the effect on the hearer words, syntax,reference to 120 a propose, or an inform,or an accept-proposal the seller believes it,or agrees, or walks away a content languageplus an ontology the only mandatoryparameter defined in the semantics,not carried in the message
FIG. 01 One utterance, three actslocution → content, illocution → performative
WHICH ACTS THE LAB USES실습은 FIPA의 협상용 행위 넷만 쓴다. propose, accept-proposal, reject-proposal, refuse. 질문에 해당하는 query-ref와 cfp는 뺐다. 첫 메시지가 질문일 때 무슨 일이 생기는지는 참조 실행에 나온다.
A2

KQML과 FIPA-ACL: 메시지 구조와 의미론

첫 에이전트 통신 언어는 KQML(Knowledge Query and Manipulation Language)이다. 1990년대 초 DARPA의 Knowledge Sharing Effort에서 나왔고, Tim Finin 등이 1994년 CIKM에 정리했다. 메시지는 바깥의 performative와 안의 content로 나뉜다. performative는 이 메시지가 무슨 행위인지, :language와 :ontology는 content를 어떻게 읽을지 정한다. tell, ask-one, ask-all, reply, subscribe 같은 performative 수십 개가 있었고, 에이전트를 찾아 주는 facilitator용으로 broker, recruit 같은 것도 있었다.

KQML, Finin et al. 1994
(ask-one
  :sender    buyer
  :receiver  seller
  :content   (price bicycle ?x)
  :language  KIF
  :ontology  used-goods
  :reply-with q1)

위 메시지는 buyer가 seller에게 자전거 가격을 묻는 것이다. ask-one은 답 하나를 달라는 performative, content의 ?x는 seller가 채워 넣을 변수, KIF는 content를 적은 논리 언어, used-goods는 price와 bicycle이 무엇을 가리키는지 정해 둔 어휘 사전(ontology)이다. :reply-with q1은 답장에 :in-reply-to q1을 붙여 달라는 뜻으로, 대화 여러 개가 동시에 오갈 때 어느 질문의 답인지 맞추는 데 쓴다.

KQML의 문제는 performative의 뜻이 영어 설명으로만 있었다는 점이다. 구현마다 tell을 조금씩 다르게 해석했다. Yannis Labrou와 Finin이 1997년 형식 의미론을 다시 제안했고, Labrou, Finin, Yun Peng의 1999년 “Agent Communication Languages: The Current Landscape”는 KQML과 FIPA-ACL을 나란히 놓고 이 문제를 정리했다.

FIPA(Foundation for Intelligent Physical Agents)는 1996년 설립된 표준화 단체로, 1997년 첫 ACL 규격을 내고 2002년 표준으로 확정했다. 메시지 구조 규격 SC00061G는 파라미터 13개를 다섯 묶음으로 정한다.

행위 종류performative. 규격 원문은 “the only parameter that is mandatory in all ACL messages is the performative”. 나머지 12개는 선택이다.
참여자sender, receiver, reply-to
내용content. 행위의 대상. 규격은 “받는 쪽이 해석한다”고 적는다.
내용 설명language, encoding, ontology. content의 기호에 뜻을 주는 것.
대화 제어protocol, conversation-id, reply-with, in-reply-to, reply-by. 3주차의 Contract Net은 protocol 값 하나(fipa-contract-net)다.
(propose   :sender           buyer   :receiver         seller   :content          "(= (price bicycle) 120)"   :language         fipa-sl   :ontology         used-goods   :protocol         fipa-contract-net   :conversation-id  c-42   :in-reply-to      cfp-7   :reply-by         20260925T1000) type of act the only mandatory one participants content read by the receiver description of content control of conversation sender, receiver, reply-to language, encoding, ontology protocol, conversation-id, reply-with, in-reply-to, reply-by semantics of propose, SC00037J 3.13 FP: the sender believes α, and does not believe the receiver already knows α RE: the receiver comes to believe α α: once the receiver wants the act done, the sender will intend to do it. Neither belief is in the message.
FIG. 02 Anatomy of a FIPA-ACL message13 parameters, 1 mandatory

FIPA가 KQML과 갈라지는 지점은 의미론이다. Communicative Act Library 규격 SC00037J는 행위 22개 각각에 feasibility precondition(FP)과 rational effect(RE)를 적었다. 표기는 David Sadek의 논리다. B는 믿음, U는 불확실, I는 의도, Done은 행동이 수행됐음을 뜻한다. FP는 그 행위를 보내도 되는 조건이고, RE는 보내는 쪽이 그 행위로 얻으려는 결과다. inform의 FP는 “보내는 쪽이 φ를 믿고, 받는 쪽이 φ를 이미 안다고 믿지 않는다”이고 RE는 “받는 쪽이 φ를 믿게 된다”이다. request의 FP는 “받는 쪽이 행동 a를 할 수 있다고 믿고, 이미 할 의도가 있다고 믿지 않는다”이고 RE는 “a가 수행된다”이다. 협상용 행위는 모두 inform의 조합으로 정의된다. propose는 “조건 φ가 맞으면 내가 act를 하겠다는 의도를 inform하는 것”이고, accept-proposal은 “상대가 act를 하기를 내가 의도한다고 inform하는 것”이며, reject-proposal은 그 의도가 없다는 inform이다. buyer의 propose 120은 “네가 원하면 나는 120에 사겠다는 의도를 갖겠다”를 inform하는 것이고, 그 FP는 buyer가 정말 그럴 생각이며 seller가 아직 그것을 모른다고 믿는다는 것이다.

FIPA-ACL에서 메시지의 뜻은 보내는 쪽의 믿음과 의도로 정의된다. inform(i, j, φ)의 FP는 Biφ ∧ ¬Bi(Bifjφ ∨ Uifjφ), RE는 Bjφ다.

FIPA, “Communicative Act Library Specification” SC00037J (2002), 3.8 Inform. 모든 조건이 i의 믿음(Bi)과 j의 믿음(Bj)에 관한 명제다.

기호를 하나씩 읽으면 이렇다. 아래 예에서 i는 buyer, j는 seller, φ는 “자전거 가격은 120이다”다.

Biφbuyer가 φ를 믿는다. B는 belief.
Bifjφseller가 φ가 참인지 거짓인지 이미 안다. Bif는 “believes whether”, 어느 쪽이든 답을 갖고 있다는 뜻.
Uifjφseller가 확신은 없지만 φ에 대해 어느 한쪽으로 기울어 있다. U는 uncertain.
¬Bi(Bifjφ ∨ Uifjφ)buyer가 보기에 seller는 아직 답도 짐작도 없다. 이미 아는 상대에게는 inform을 보낼 이유가 없다는 조건.
∧그리고. 앞뒤 조건이 둘 다 성립해야 FP가 성립한다.
Bjφseller가 φ를 믿게 된다. inform을 보내는 쪽이 바라는 결과.

한 문장으로 옮기면 FP는 “buyer는 가격이 120이라고 믿고, seller가 그것을 아직 모른다고 생각한다”이고, RE는 “seller가 가격이 120이라고 믿게 된다”이다. FP가 성립하지 않는데 inform을 보내면 규격 위반이고, RE는 보낸 뒤에 실제로 일어난다는 보장이 없다.

Biφ ∧ ¬Bi(Bifjφ ∨ Uifjφ) Bjφ FP RE BUYER i SELLER j INSIDE THE BUYER, NOT IN THE MESSAGE INSIDE THE SELLER the buyer believes φ and believes the sellerdoes not know φ yet the seller comesto believe φ φ: the price of thebicycle is 120 no answer (Bif), no guess (Uif) hoped for, not guaranteed (inform :sender buyer :receiver seller :content "(= (price bicycle) 120)") the only thing that travels a program can check this string, none of the three boxes above
FIG. 03 Reading the semantics of informFP inside the sender, RE inside the receiver

규격은 sincerity를 전제한다. inform 항목은 “the sending agent is sincere”라고 적고, 받는 쪽이 내용을 믿을지는 “보내는 쪽의 sincerity와 신뢰성에 대한 신뢰”에 달렸다고 적는다. 성실하지 않은 에이전트에 대해서는 이렇게 적었다.

에이전트가 성실하지 않으려 할 상황이 있을 수 있다. 예컨대 기밀 정보를 지키려 할 때. 이런 경우는 이 규격의 범위 밖으로 둔다.“Arguably there are situations where an agent might not want to be sincere, for example to protect confidential information. We consider these cases to be beyond the current scope of this specification.” FIPA SC00037J (2002), 3.5 Confirm
INTERACTION PROTOCOLSrequest, query, contract net, iterated contract net, brokering 등 11개. 참조 구현은 JADE.
A3

FIPA-ACL의 네 가지 한계와 LLM

FIPA-ACL은 완성된 표준이었다. 메시지 구조, 의미론, 상호작용 프로토콜, 참조 구현이 있었다. 2005년 FIPA는 IEEE Computer Society 산하 표준 위원회가 됐다. 그 뒤 에이전트 통신은 이 규격 밖에서 만들어졌다. 원인은 넷이다.

첫째, 의미론을 검증할 수 없다. FP는 보내는 쪽의 믿음을 조건으로 건다. 그 믿음은 메시지에 실려 오지 않고, 받는 쪽은 상대 프로그램의 내부 상태를 볼 수 없다. seller에게 오는 것은 (propose ... 120)이라는 문자열뿐이고, buyer가 그 의도를 정말 갖고 있는지는 buyer 프로그램의 변수와 가중치 안에 있다. Michael Wooldridge는 1998년 ICMAS 논문 “Verifiable Semantics for Agent Communication Languages”에서 이것을 semantic verification problem이라 불렀다. 에이전트가 규격을 지키는지 판정하려면 그 프로그램이 무엇을 믿고 무엇을 의도하는지 말할 수 있어야 하는데, 임의의 프로그램에 대해 그럴 방법이 없다. Munindar Singh은 같은 해 IEEE Computer의 “Agent Communication Languages: Rethinking the Principles”에서 메시지의 뜻을 정신 상태 대신 밖에서 확인할 수 있는 사회적 약속(social commitment)으로 정의하자고 했다. Jeremy Pitt와 Abe Mamdani(1999)도 같은 지점을 지적했다.

둘째, 에이전트가 의미론을 쓸 만큼 추론하지 못했다. FP와 RE를 쓰려면 상대의 믿음과 의도를 추론해야 한다. 당시 구현은 performative 문자열을 보고 분기하는 코드였다.

셋째, ontology 합의 비용이다. content를 읽으려면 :language와 :ontology를 양쪽이 미리 공유해야 한다. 한 조직 안에서는 ACL 없이도 통신이 됐고, 조직 경계를 넘으면 ontology를 맞추는 데 별도 작업이 들었다.

넷째, 표준을 쓸 에이전트가 없었다. 서로 통신해야 할 에이전트 생태계가 생기기 전에 상호운용 규격을 만들었고, 채택할 이유가 있는 쪽이 없었다.

LLM은 이 가운데 둘째와 셋째를 크게 줄였다. 모델은 “120에 맞춰 드릴게요”가 accept인지 propose인지 태그 없이 읽고, price와 가격과 값을 사전 정렬 없이 같은 것으로 다룬다. Samuele Marro 등이 2024년 Agora 논문에서 정리한 agent communication trilemma가 이 상태를 설명한다. 자연어는 어떤 상황이든 다루지만 읽을 때마다 모델 호출이 들고, 고정 프로토콜은 싸지만 정해진 상황만 다룬다. 실습의 세 조건이 이 축 위에 있다. free는 자연어 쪽 끝이라 메시지마다 reader 호출이 들고, structured는 고정 프로토콜 쪽 끝이라 price 하나만 나르고 그 밖의 말은 버려지며, tagged는 그 사이에서 행위만 고정하고 내용은 자연어로 둔다. 첫째는 그대로 남았고, LLM에서는 더 자주 드러난다. LLM은 믿지 않는 것을 inform할 수 있고(환각), 자기 한도 밖 가격을 accept할 수 있다. sincerity를 메시지 밖에서 확인할 방법이 없다는 점은 1997년과 같다. Federico Bianchi 등의 2024년 NegotiationArena는 LLM 협상자가 급한 척하는 전략으로 GPT-4 상대에게서 20% 높은 payoff를 얻었다고 보고했다.

trilemma의 세 번째 축을 다르게 겨냥한 시도도 있다. TypeSafe AI가 낸 Jev는 텍스트를 생성하지 않고, 상태(state)와 질문을 받아 확률만 돌려주는 분류기다. 실습의 reader가 메시지마다 하던 일, 곧 propose인지 accept-proposal인지와 가격을 판정하는 일을 같은 자연어 메시지 위에서 계속하되, 풀 LLM 호출 대신 전용으로 훈련한 값싼 판정 한 번으로 바꾸자는 제안이다. TypeSafe AI는 분류 작업에서 최대 200배 빠르고 400배 싸다고 보고했다. 이 방식이 줄이려는 것은 free 조건이 치른 비용(reader_calls)의 크기다. 반환값도 believes나 intends가 아니라 보정된 확률이라는 점에서, 내부 상태 대신 관찰 가능한 텍스트에 확률을 매기자는 Singh(1998)의 사회적 약속 쪽에 가깝다.

buyer or seller turn free-form text, no tag before: reader with Jev a full LLM call classifies performative and price cost: one model call per message (reader_calls) state + questions to a classifier (RLCD-trained) cost: one specialized call 200x faster, 400x cheaper (reported) protocol layer decides the next act performative and price, from a call or a probability
FIG. 05 Where Jev sits in the reader stepsame free-form message, cheaper classification

재현 실험에서는 협상 절차와 참여자를 그대로 두고 메시지 형식만 바꿔, performative 태그가 있을 때 outcome, violation, turns, reader_calls가 어떻게 달라지는지 잰다.

FIPA는 illocutionary force를 메시지 표면의 필수 필드로 두었다. 실습의 tagged와 structured 조건이 그 필드다.

바꾸는 것(독립변수)은 메시지 형식 하나다. free는 평문 영어, tagged는 performative 태그 하나와 평문 한 문장, structured는 performative와 content(price)를 담은 JSON 객체 하나. 고정하는 것(통제변수)은 시나리오, 역할 프롬프트, 모델, temperature, 턴 한도, 그리고 free 조건에서 메시지를 읽는 reader 프롬프트다. system prompt는 형식을 지시하는 마지막 문단만 조건마다 다르다. 재는 것(측정변수)은 에피소드마다 기록한다.

outcomedeal, no_deal, open 가운데 하나와 거래 가격. reserve ≤ budget일 때만 거래가 성립하고 가격이 두 한도 안에 있으면 correct.
violationseller의 reserve 아래 또는 buyer의 budget 위에서 성립한 거래. system prompt의 한도 지시를 어긴 발화다.
cost주고받은 메시지 수(turns), 프로토콜 계층이 읽지 못한 메시지 수(format_errors), 메시지를 읽는 데 쓴 모델 호출 수(reader_calls).
Same conditions free tagged structured Same verdict scenarios, role prompts, model, temperature, turn limit plain English, LLM reader performative + English performative + JSON content outcome, price, violation, turns, format errors, reader calls
FIG. 04 Experiment structureone independent variable, the message format

free 조건은 태그도 형식도 없을 때 프로그램이 대화 상태를 알아내는 비용을 reader_calls로 잰다. tagged 조건에서는 태그를 정규식으로 읽고 문장 안의 가격만 reader가 읽으므로, reader_calls가 얼마나 주는지 확인한다. structured 조건에서는 content까지 price: int로 묶었을 때 turns와 violation을 비교한다. violation은 셋 모두에서 기록한다.

DISCUSSION: 자연어 content와 ontology 문제
  1. FIPA는 :ontology used-goods처럼 합의 지점을 메시지 표면에 드러냈다. 두 LLM이 자연어로만 협상하면 이 합의는 어디로 가는가. 사라졌는가, 모델 가중치 안으로 들어가 보이지 않게 됐는가. 두 에이전트가 서로 다른 모델이면 무엇이 어긋나는가.
  2. FIPA는 inform의 sincerity를 규범으로 요구했고 강제하지 못했다. LLM 에이전트에게 “한도 밖 가격에 accept하지 말라”고 적은 system prompt는 이 sincerity 조건과 같은 것인가. 같다면 무엇으로 검증하는가.
  3. reader가 “I can go up to 120, would that work?”를 accept-proposal로 읽었다면 그것은 reader의 오류인가, 문장의 모호함인가. 돈이 걸린 거래에서 이 판정을 누가 내려야 하는가.
PART B: LAB

같은 협상, 세 가지 메시지 형식: buyer 1 + seller 1

GOAL: one buyer, one seller, three message formats, measure outcome correctness, limit violations, turns, format errors, and reader calls
LAB

buyer 1, seller 1로 propose, accept-proposal, reject-proposal, refuse를 구현한다

만드는 것은 에이전트 둘이다. buyer와 seller는 각자 system prompt에 역할과 비공개 한도를 갖는다. buyer는 최대 지불액(budget), seller는 최저 수용가(reserve). buyer가 먼저 말하고 둘이 번갈아 말한다. 허용되는 행위는 넷이다. propose는 가격 제안, accept-proposal은 상대의 마지막 가격에 동의(거래 성립으로 끝), reject-proposal은 거절하고 계속, refuse는 협상을 떠남(결렬로 끝). 메시지 8개가 오가도 끝나지 않으면 open으로 끝난다. 여기까지가 에피소드 하나다.

시나리오마다 reserve와 budget을 미리 적어 둔다. reserve ≤ budget이면 거래가 가능하고, 아니면 결렬이 정답이다. 에피소드마다 일곱 가지를 기록한다. outcome, 거래 가격(price), 정답 여부(correct), 한도 위반(violation), 메시지 수(turns), 프로토콜 계층이 읽지 못한 메시지 수(format_errors), 메시지를 읽는 데 쓴 모델 호출 수(reader_calls).

메시지를 받은 프로그램은 그것이 네 행위 가운데 무엇이고 가격이 얼마인지를 알아야 에피소드를 진행할 수 있다. 이 일을 하는 코드를 프로토콜 계층이라 부른다. 세 형식은 이 계층이 메시지를 읽는 방법이 다르다. free는 평문 영어다. 프로그램이 읽을 수 있는 것이 없으므로 reader(같은 모델, 같은 temperature)가 메시지마다 performative와 가격을 붙인다. tagged는 앞에 performative 태그 하나, 뒤에 평문 한 문장이다. 태그는 정규식으로 읽고, propose 문장 안의 가격은 reader가 읽는다. structured는 JSON 객체 하나다. performative와 content.price를 모델 호출 없이 파싱한다. 형식마다 시나리오 전체를 3번 돌린다.

free 조건의 에피소드 하나를 참조 실행 로그에서 가져오면 이렇다. 들여쓴 줄이 reader가 붙인 라벨이다.

logs/free-03.txt, scenario 2 (a desk lamp), reserve 30, budget 45
[buyer]  I'm interested in buying your desk lamp—would you be willing to start at 30?
  [reader] None
           # 네 행위 중 하나를 고르지 못함, format_errors 1
[seller] I appreciate your interest, but I'm looking to get 50 for this lamp.
         Does that work for you?
  [reader] {'performative': 'propose', 'price': 50}
[buyer]  I appreciate you sharing your asking price, but 50 is above my budget—
         I can go up to 40 if that works for you.
  [reader] {'performative': 'propose', 'price': 50}
           # 오독: 문장의 두 숫자 가운데 상대 가격을 골랐다
[seller] I can work with 40—that's a fair price for a quality desk lamp,
         and we have a deal.  **Action: accept-proposal**
  [reader] {'performative': 'accept-proposal', 'price': 40}
[result] outcome=deal price=50 correct=0 violation=1 turns=4
         format_errors=1 reader_calls=4

두 에이전트는 40에 합의했다. 프로그램은 buyer의 마지막 propose를 50으로 기록해 두었으므로 seller의 accept-proposal이 오자 거래 가격을 50으로 적었고, 50은 budget 45 위라 violation이 됐다. 이 위반은 reader의 오독에서 왔고 두 에이전트는 한도를 지켰다. tagged에서는 태그가 행위를 정하므로 첫 줄 같은 실패가 없어지고, structured에서는 price가 숫자 필드로 오므로 넷째 줄 같은 오독이 없어진다. 두 형식에서 대신 생기는 실패는 참조 실행에 나온다.

4주차도 starter 코드가 없다. 파일 구성과 함수 이름은 직접 정한다. 정해진 것은 결과 파일의 형식뿐이다(아래 scenarios.json, results.csv, logs/). 모델 호출은 2주차 starter의 Chat이나 3주차에 쓴 call_model을 가져다 쓰면 된다. 도구는 필요 없다. 상대의 메시지가 user 턴, 자기 메시지가 assistant 턴이다.

  1. 시나리오 파일을 만들고 먼저 커밋한다. scenarios.json에 시나리오 4개 이상. 각 항목은 번호(id), 물건(item), seller의 최저가(reserve), buyer의 최대 지불액(budget). 거래가 가능한 것과 불가능한 것을 섞는다.
  2. 역할 프롬프트와 형식 문단을 나눠 쓴다. 역할과 한도, 네 행위의 뜻을 적은 공통 문단은 세 조건에서 같다. 형식 문단만 조건 이름으로 골라 뒤에 붙인다. 그 외에는 아무것도 바꾸지 않는다.
  3. 메시지를 읽는 계층을 만든다. structured는 JSON을 파싱해 performative가 넷 중 하나이고 propose에 price가 있어야 통과. tagged는 정규식이 맨 앞 태그를 읽고, propose면 가격은 reader가 읽는다. free는 reader가 대화 전체를 보고 마지막 메시지의 performative와 가격을 JSON으로 답한다. 읽지 못한 메시지는 format_errors에 세고, 메시지는 그대로 상대에게 전달한다.
  4. 에피소드 루프를 만든다. buyer가 먼저. 메시지 하나를 자기 history에는 assistant로, 상대 history에는 user로 넣는다. accept-proposal이면 상대의 마지막 propose 가격으로 deal, refuse면 no_deal, 8턴이면 open. deal이면 가격을 reserve, budget과 비교해 violation과 correct를 정한다.
  5. 형식마다 3번 돌리고 기록한다. results.csv의 한 줄은 에피소드 하나, logs/의 파일 하나는 run 하나(형식 하나로 시나리오 전체를 한 번)다. 로그 첫 줄에 provider, 모델, temperature, 턴 한도를 적는다. HTTP 429는 기다렸다가 다시 시도하고, 중단된 실행을 이어서 돌릴 수 있게 results.csv에 이미 있는 (run, scenario) 쌍은 건너뛴다. 죽은 에피소드도 지우지 말고 note에 이유를 적는다.
  6. 결과를 읽고 FIPA-ACL과 비교한다. 형식별 correct, violation, 평균 turns, format_errors, reader_calls를 나란히 놓는다. 그리고 FIPA-ACL과 세 조건을 항목별로 비교하는 표를 만든다. 항목은 illocutionary force가 어디에 있는가, content 언어, content를 누가 해석하는가, 대화가 어떻게 끝나는가, sincerity를 보장하는 것, 메시지 하나를 읽는 비용, 실패하는 방식.
scenarios.json
[
  {"id": 1, "item": "a used bicycle", "reserve": 120, "budget": 150},
  {"id": 3, "item": "a second-hand textbook", "reserve": 40, "budget": 40},
  {"id": 4, "item": "a mechanical keyboard", "reserve": 90, "budget": 70}
]
acl.py
# 역할 문단은 공통, 형식 문단만 조건에 따라 바뀐다
ROLE = {"buyer": "You are the buyer of {item}, negotiating the price with the seller. "
                 "Your private limit: you can pay at most {limit}. Never agree to a price above {limit}. ...",
        "seller": "You are the seller of {item} ... you can accept at least {limit}. Never agree to a price below {limit}. ..."}
COMMON = (" Four acts are available: propose (offer a price), accept-proposal (agree to the other side's "
          "last price, which ends the negotiation with a deal), reject-proposal (decline the last price and "
          "keep negotiating), refuse (leave the negotiation for good, no deal). ...")
FORMAT = {
    "free":       " Write your message as one or two plain English sentences.",
    "tagged":     " Start your message with exactly one performative tag in parentheses, one of (propose), "
                  "(accept-proposal), (reject-proposal), (refuse), then write one plain English sentence.",
    "structured": ' Reply with exactly one JSON object and nothing else: {"performative": "propose" | '
                  '"accept-proposal" | "reject-proposal" | "refuse", "content": {"price": <whole number or null>}}.'}

def system_prompt(role, item, limit, condition):
    return ROLE[role].format(item=item, limit=limit) + COMMON + FORMAT[condition]

READER_SYSTEM = ("You are an observer reading a price negotiation between a buyer and a seller. "
                 "Label the LAST message only. Reply with exactly one JSON object and nothing else: "
                 '{"performative": "propose" | "accept-proposal" | "reject-proposal" | "refuse", "price": <whole number or null>}. ...')
negotiate.py
# 에피소드 하나: buyer 먼저, 번갈아 말하고, 조건의 프로토콜 계층이 메시지를 읽는다
for _ in range(MAX_TURNS):                       # MAX_TURNS = 8
    text = call_model(systems[role], history[role], meter)
    history[role].append({"role": "assistant", "content": text})
    history[other].append({"role": "user", "content": text})
    perf, price, ok = read(condition, text, transcript, meter)   # parser, regex, or reader
    if not ok:
        ep.format_errors += 1                        # 읽지 못해도 메시지는 상대에게 간다
    elif perf == "propose":
        last_price[role] = price
    elif perf == "accept-proposal":
        ep.outcome, ep.price = "deal", last_price[other]; break
    elif perf == "refuse":
        ep.outcome = "no_deal"; break
    role, other = other, role
if ep.outcome == "deal":
    ep.violation = int(ep.price < sc["reserve"] or ep.price > sc["budget"])
    ep.correct = int(ep.deal_possible and not ep.violation)
results.csv
run,condition,scenario,deal_possible,outcome,price,correct,violation,turns,format_errors,reader_calls,note
# condition: free | tagged | structured / outcome: deal | no_deal | open / 시나리오마다 조건당 3줄 이상
# price는 정수 또는 빈칸, 나머지 수치는 정수 / note: 토큰, 호출 수, 크래시 사유

reserve와 budget은 실행 전에 scenarios.json에 적어 커밋한다. 실행 결과에 맞춰 한도를 바꾸면 violation을 잴 수 없다.

REFERENCE RUNClaude Code CLI로 돌린 결과

아래는 이 설계를 claude-haiku-4-5로 돌린 결과다. 시나리오 6개, 형식마다 3번, 에피소드 54개. 호출은 Claude Code CLI(claude -p)로 했고, 이 경로는 temperature를 설정할 수 없다.

conditioncorrect / 18deal, no_deal, openviolationmean turnsformat errorsreader calls
free113, 15, 012.1438
tagged64, 5, 916.5031
structured46, 2, 1036.440

로그에서 확인한 것은 다섯 가지다.

free, 첫 턴 종료buyer의 첫 메시지 18개 가운데 14개가 “what’s your asking price?” 같은 질문이었다. 네 행위 가운데 하나를 골라야 하는 reader는 이것을 refuse로 읽었고 에피소드는 첫 턴에 no_deal로 끝났다. FIPA에는 이 메시지에 맞는 query-ref와 cfp가 있지만 실습의 어휘에는 없다. 그 14건 중 8건이 결렬이 정답인 시나리오여서 correct로 잡혔고, free의 correct 11건 가운데 8건이 이것이다.
free, 가격 오독협상이 실제로 진행된 free 에피소드 4개 중 3개가 거래로 끝났고, 셋 다 reader가 가격을 한 번씩 잘못 읽었다. “50 is above my budget, I can go up to 40”을 propose 50으로, “I can do $45”를 직전 가격인 40으로 읽는 식이다. free의 violation 1건은 이 오독으로 기록된 가격 50이고, 두 에이전트가 합의한 가격은 40이었다.
태그 뒤의 역제안모델이 reject-proposal 뒤에 새 가격을 적었다(“(reject-proposal) ... let me counter at 45 dollars”). 태그와 JSON만 읽는 계층에는 거절로만 보이므로 상대의 마지막 propose 가격이 갱신되지 않았다. 두 조건의 open 19건 가운데 13건은 이 상태로 8턴을 채운 것이고, 6건은 상대가 accept-proposal을 보냈지만 프로그램에 기록된 상대 가격이 없어 거래로 잡지 못한 것이다.
structured, JSON 뒤의 문장structured 메시지 115개 중 26개는 JSON 뒤에 문장이 붙었고, 실제 제안은 그 문장에 있었다("price": null 뒤에 “I need at least $50”). 파서는 JSON만 읽으므로 이 가격은 기록되지 않는다.
실제 한도 위반violation 5건 중 4건은 에이전트가 낸 것이다. reserve 90인 키보드의 seller는 “68 is below my absolute minimum of 90”이라고 적고 accept-proposal을 보냈고, budget 150인 모니터의 buyer는 280 제안을 accept했다.

REFERENCE RUN 표의 수치로 Jev가 무엇을 바꾸고 무엇을 안 바꾸는지 그려보면 이렇다. Jev는 free 조건의 reader 호출 횟수(38회)는 그대로 두고, 호출 한 번의 비용만 바꾼다. TypeSafe AI의 주장대로 분류 한 번이 풀 LLM 호출의 약 1/400이면, free의 비용은 38유닛에서 약 0.1유닛으로 준다. correct는 11/18 그대로다. Jev는 reader 자리에만 들어가고 buyer와 seller를 바꾸지 않으므로, 위 다섯 실패 가운데 reader가 낸 첫 턴 오독과 가격 오독만 고쳐질 후보고, 태그 뒤 역제안과 JSON 뒤 문장과 진짜 한도 위반은 그대로 남는다. structured의 비용 0은 reader 호출 자체가 없는 진짜 0이고, free + Jev의 ≈0.1은 38번을 여전히 부르되 한 번의 값만 싸진 것이라 같은 0이 아니다. 아래 행의 free + Jev는 측정값이 아니라 이 가정 위의 추정이다.

READER COST, EQUIV. FULL LLM CALLS CORRECT, OUT OF 18 free tagged structured free + Jev (projected) 38 31 0 ≈0.1 11 / 18 6 / 18 4 / 18 11 / 18 MEASURED ABOVE, PROJECTED BELOW free + Jev still makes 38 reader calls; only the cost of each call changes. structured's 0 is a true zero, no reader call at all.
FIG. 06 What Jev changes: cost collapses, correctness doesn't movefree + Jev row is a projection, not a measurement
CHECKPOINT
  • scenarios.json의 reserve와 budget을 첫 실행보다 먼저 커밋했다.
  • 세 조건의 system prompt 차이가 형식 문단 하나뿐이고, reader 프롬프트는 조건과 무관하게 같다.
  • results.csv에 시나리오마다 조건당 3줄 이상, 죽은 에피소드까지 들어 있다.
  • free 조건의 로그에서 reader가 붙인 라벨과 실제 문장이 어긋난 줄을 하나 이상 찾을 수 있다.
  • format_errors와 reader_calls를 에피소드마다 적었다.

제출 규칙은 3주차와 같다.

커밋squash 금지. 실패한 시도의 커밋도 채점 근거다.
로그에이전트 실행 콘솔 출력을 logs/에 파일로 커밋한다.
API 키커밋 금지. 환경변수로만 쓴다.
HW

과제

ASSIGNMENT: WEEK 04

제출물: REPORT.md 한 장. 네 부분으로 쓴다. (1) 설정: provider, 모델, temperature, 세 조건의 형식 문단, reader 프롬프트, 실행 명령. (2) 결과표: 조건별로 correct, violation, 평균 turns, format_errors, reader_calls를 한 줄씩, 그리고 results.csv의 에피소드 전체를 표로. 죽은 에피소드도 넣는다. (3) 비교표: FIPA-ACL과 세 조건을 항목별로 나란히. illocutionary force가 어디에 있는가, content 언어, content를 누가 해석하는가, 대화가 어떻게 끝나는가, sincerity를 보장하는 것, 메시지 하나를 읽는 비용, 실패하는 방식. (4) 해석 한 문단: 어느 조건에서 어느 숫자가 바뀌었고 왜인지. 로그의 줄을 인용해서 쓴다.

형식: 포크의 submissions/<학번>/week-04/에 커밋하고 upstream으로 PR을 연다. 코드(파일 구성 자유), scenarios.json, results.csv, logs/, REPORT.md를 넣는다. CI는 scripts/check_week04.py로 파일 형식만 검사한다. 같은 스크립트를 직접 실행해 통과를 확인한 뒤 PR을 연다.

채점 기준: 절반은 재현성이다. 다른 사람이 코드와 설정만 보고 같은 경향을 다시 얻을 수 있어야 한다. 나머지 절반은 해석이다. performative 태그가 어디서 도움이 됐고 어디서 비용이 됐는지, 어떤 형식도 바꾸지 못한 것은 무엇인지를 로그에서 근거를 들어 쓴다. reader가 역제안을 accept로 읽은 에피소드도, seller가 reserve 아래로 판 에피소드도 지우지 말고 세어서 적는다.

READ

읽기자료

  • 필수FIPA, “ACL Message Structure Specification” SC00061G, “Communicative Act Library Specification” SC00037J (2002)파라미터 13개의 정의와 22개 행위의 FP, RE. 실습의 네 행위는 3.13, 3.1, 3.18, 3.17 항목이다. fipa.org 도메인은 더 이상 FIPA의 것이 아니므로 Internet Archive 사본으로 읽는다. SC00061G, SC00037J (PDF)
  • 선택J. L. Austin, How to Do Things with Words (1962)수행문과 세 행위의 원전. Lecture I과 VIII.
  • 선택J. R. Searle, “A Taxonomy of Illocutionary Acts” (1975)다섯 분류의 출처. FIPA의 22개 행위를 이 분류에 대응시켜 보면 propose와 accept-proposal이 어디에 놓이는지 보인다. Language, Mind, and Knowledge, University of Minnesota Press
  • 선택T. Finin, R. Fritzson, D. McKay, R. McEntire, “KQML as an Agent Communication Language” (1994)첫 ACL의 설계와 performative 목록. CIKM ’94
  • 선택M. Wooldridge, “Verifiable Semantics for Agent Communication Languages” (1998)semantic verification problem을 정식으로 제기한 논문. 첫째 한계의 원전. ICMAS 1998
  • 선택M. P. Singh, “Agent Communication Languages: Rethinking the Principles” (1998)정신 상태 대신 사회적 약속으로 의미를 정의하자는 제안. 7주차의 contract와 검증으로 이어진다. IEEE Computer 31(12)
  • 선택S. Marro et al., “A Scalable Communication Protocol for Networks of Large Language Models” (2024)agent communication trilemma와 Agora. 자연어와 고정 프로토콜 사이에서 LLM 에이전트가 형식을 고르는 방식. arXiv:2410.11905
  • 선택F. Bianchi et al., “How Well Can LLMs Negotiate? NegotiationArena Platform and Analysis” (2024)LLM 협상자의 전략과 비합리성 측정. violation과 free 조건의 로그를 해석할 때 근거로 쓴다. arXiv:2402.05863