--- id: wiki-2026-0508-aci title: ACI (Agent-Computer Interface) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [Agent-Computer Interface, ACI, agent harness interface, tool interface, LLM tool design] duplicate_of: none source_trust_level: B confidence_score: 0.85 verification_status: conceptual tags: [aci, agent, llm, tool-design, harness, infrastructure, prompt-engineering, mcp] raw_sources: [] last_reinforced: 2026-05-09 github_commit: wikification-aci inferred_by: Claude Opus 4.7 (manual cleanup 2026-05-09) tech_stack: language: TS / Python framework: MCP / Anthropic SDK / OpenAI SDK / LangChain --- # ACI (Agent-Computer Interface) ## πŸ“Œ ν•œ 쀄 톡찰 (The Karpathy Summary) > **Human UI β‰  Agent UI**. LLM agent 의 λ§€ file / tool / output 의 representation κ°€ model 의 perception. **Tool name + description + schema + error message κ°€ agent 의 IQ λ₯Ό κ²°μ •**. SWE-bench score 의 λ§€ jump κ°€ ACI 의 redesign. ## πŸ“– κ΅¬μ‘°ν™”λœ 지식 (Synthesized Content) ### μ •μ˜ ACI = LLM agent κ°€ 컴퓨터 (OS, file, tool, API) 와 μƒν˜Έμž‘μš© ν•˜λŠ” interface design. - Human 에 GUI / CLI κ°€ 있으면, agent 에 ACI. - λ§€ ACI 의 quality κ°€ agent 의 task 성곡λ₯  κ²°μ •. - "Same model + better ACI = +20% score" (Princeton SWE-agent 의 발견). ### Why ACI matters - **Token 효율**: λ§€ tool 의 verbose output = context 폭발 / cost. - **Error recovery**: λ§€ error message 의 actionable feedback. - **Cognitive load**: λ„ˆλ¬΄ λ§Žμ€ tool / option = LLM 의 confusion. - **Robustness**: λ§€ schema 의 strict validation = parsing fail ↓. ### 핡심 design principle #### 1. Tool naming - ❌ `do_thing()`, `helper_5()`, `process()` β€” λͺ¨ν˜Έ. - βœ… `read_file(path)`, `search_codebase(query)`, `run_python(code)` β€” λ™μž‘ λͺ…ν™•. #### 2. Schema (input) ```json { "name": "edit_file", "description": "Edit a file by replacing exact text. Fails if oldText not found exactly.", "input_schema": { "type": "object", "properties": { "path": { "type": "string", "description": "Absolute file path" }, "oldText": { "type": "string", "description": "Exact text to replace (whitespace sensitive)" }, "newText": { "type": "string", "description": "Replacement text" } }, "required": ["path", "oldText", "newText"] } } ``` β†’ λ§€ field 의 description κ°€ 맀우 important. #### 3. Output ν˜•μ‹ ``` βœ… Structured: { "success": true, "result": { "rows": 5, "data": [...] }, "warnings": [] } βœ… Truncated when too long: { "result": "...", "truncated": true, "fullLength": 50000, "next": "Use offset=1000 to read next chunk" } ❌ Raw 맀번 큰 dump: "... 50KB of stdout ...": ``` #### 4. Error message (κ°€μž₯ μ€‘μš”) ``` ❌ Bad: "Error 500" ❌ Bad: "Operation failed" βœ… Good: { "error": "FileNotFound", "path": "/abs/path", "hint": "Did you mean: /abs/path-similar? Or run list_directory('/abs/').", "recovery": ["check path", "list_directory parent"] } ``` β†’ Error κ°€ agent 의 λ‹€μŒ action 의 hint. #### 5. State visibility ``` λ§€ tool call ν›„: - Current working directory. - Recently modified files. - Open file count. - Resource usage. β†’ Agent 의 implicit context. ``` ### Design patterns #### Pattern 1: Agent 의 file 의 line number prefix ``` 1: import { foo } from './bar'; 2: 3: function hello() { 4: return foo(); 5: } ``` β†’ Edit μ‹œ line number 의 reference κ°€λŠ₯. #### Pattern 2: Diff format (edit) ``` edit_file(path="...", oldText="function foo()", newText="async function foo()") ``` β†’ Search-and-replace κ°€ line number 보닀 robust. #### Pattern 3: Pagination ``` read_file(path, offset=0, limit=2000) β†’ "lines 0-2000 of 5000. Use offset=2000 for next." ``` β†’ λ§€ large file 의 chunked. #### Pattern 4: Sub-agent (delegation) ``` spawn_subagent(task="Search for X across codebase") β†’ Sub-agent κ°€ 자체 context. Result 의 summary. ``` β†’ Main context 의 token μ ˆμ•½. #### Pattern 5: Confirmation (destructive) ``` delete_file(path) β†’ "Confirm? This will delete...": agent 의 explicit OK ν›„ μ‹€ν–‰. ``` β†’ Mistake 의 prevent. ### Modern protocol: MCP **Model Context Protocol** (Anthropic 2024): - Standardized server κ°€ λ§€ tool / resource expose. - LLM-agnostic. - Server / client architecture. - λ§€ IDE (Cursor, Claude Desktop) κ°€ native. ```typescript // MCP server server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: [ { name: 'read_file', description: '...', inputSchema: {...} }, ], })); server.setRequestHandler(CallToolRequestSchema, async (req) => { if (req.params.name === 'read_file') { return { content: [{ type: 'text', text: await fs.readFile(req.params.arguments.path) }] }; } }); ``` β†’ Tool 의 reusable + discoverable. ### Examples (good ACI) #### Cursor / Claude Code - File 의 line number prefix. - Edit 의 string-based (not line-based). - Bash result 의 exit code + stdout/stderr. - Search 의 ripgrep + path filter. #### SWE-agent (Princeton) - Custom CLI (cat, edit, ls, search). - λ§€ command 의 LLM μΉœν™” syntax. - "Window" 의 file view. - Search + line jump. #### Devin (Cognition) - Browser tool (visual + DOM tree). - Plan + execute. - Replay + debug UI. ### Bad ACI examples (avoid) - ❌ Tool list κ°€ 100+: agent κ°€ ν—·κ°ˆλ¦Ό. - ❌ Tool name 의 inconsistent: `getFile`, `readDoc`, `loadContent`. - ❌ Error κ°€ stack trace 만: actionable X. - ❌ Output κ°€ unbounded: token 폭발. - ❌ Schema κ°€ loose: any input β†’ unpredictable. ### Token efficiency λ§€ tool call 의 token cost: - Tool definition (system prompt): 100-500 tokens / tool. - Tool result: 100-10000 tokens. - 100 tool list = 10k+ tokens / call. β†’ Lazy load: λ§€ task 의 relevant tool 만. ```python # Static (μ˜›) all_tools = [tool1, tool2, ..., tool100] # Dynamic (modern) relevant_tools = router(query) # λ§€ query 의 relevant 5 tool 만. ``` ## πŸ’» μ½”λ“œ νŒ¨ν„΄ (Code Patterns) ### Anthropic tool use ```python import anthropic client = anthropic.Anthropic() tools = [{ "name": "read_file", "description": "Read contents of a file. Returns text or error.", "input_schema": { "type": "object", "properties": { "path": { "type": "string", "description": "Absolute file path" }, "offset": { "type": "integer", "description": "Start line (0-indexed)", "default": 0 }, "limit": { "type": "integer", "description": "Max lines (default 2000)", "default": 2000 } }, "required": ["path"] } }] response = client.messages.create( model="claude-opus-4-7", max_tokens=4096, tools=tools, messages=[{"role": "user", "content": "Read /etc/hostname"}] ) ``` ### Tool execution wrapper ```python def execute_tool(name, arguments): try: if name == "read_file": content = read_file(**arguments) # Truncate if too long if len(content) > 10000: content = content[:10000] + f"\n[Truncated. Total {len(content)} chars]" return {"type": "tool_result", "content": content} # ... except FileNotFoundError as e: # Actionable error parent = os.path.dirname(arguments['path']) siblings = os.listdir(parent) if os.path.exists(parent) else [] return { "type": "tool_result", "is_error": True, "content": f"FileNotFound: {arguments['path']}\nNearby files in {parent}: {siblings[:10]}" } ``` ### MCP server (TypeScript) ```typescript import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; const server = new Server( { name: 'my-tools', version: '1.0.0' }, { capabilities: { tools: {} } } ); server.setRequestHandler(ListToolsRequestSchema, () => ({ tools: [ { name: 'list_users', description: 'List users matching filter. Use for finding existing; for creating, use create_user.', inputSchema: { type: 'object', properties: { filter: { type: 'string', description: 'Optional name/email substring' }, limit: { type: 'integer', default: 50 } } } } ] })); server.setRequestHandler(CallToolRequestSchema, async (req) => { if (req.params.name === 'list_users') { const users = await db.users.findMany({...}); return { content: [{ type: 'text', text: JSON.stringify(users, null, 2) }] }; } }); await server.connect(new StdioServerTransport()); ``` ### Tool registry (dynamic) ```ts class ToolRegistry { private tools = new Map(); register(tool: Tool) { this.tools.set(tool.name, tool); } forContext(query: string): Tool[] { // λ§€ query 의 relevant 5 만. return [...this.tools.values()] .map(t => ({ ...t, score: this.relevance(query, t) })) .sort((a, b) => b.score - a.score) .slice(0, 5); } } // Agent loop const tools = registry.forContext(userQuery); const response = await llm.complete({ messages, tools }); ``` β†’ Token cost ↓. ### Permission whitelist ```ts const ALLOWED = { read_file: { paths: ['/safe/*', '!/etc/*'] }, write_file: { paths: ['/output/*'] }, shell: { commands: ['ls', 'cat', 'grep'] }, }; function isAllowed(tool: string, args: any): boolean { const rule = ALLOWED[tool]; if (!rule) return false; // λ§€ path / command 의 검증 } ``` ## πŸ€” μ˜μ‚¬κ²°μ • κΈ°μ€€ (Decision Criteria) | μž‘μ—… | μΆ”μ²œ | |---|---| | Simple internal tool | Inline schema | | Multi-tool agent | MCP server | | 큰 codebase navigation | File tools (line number, search, read chunked) | | Browser automation | Computer Use (Anthropic) / WebArena | | Code edit | Search-and-replace > line-based | | Permission | Whitelist > blacklist | | Long-running | Sub-agent (delegation) | | Confirmation | Destructive 만 | | Tool discovery | Dynamic (per-query) | **κΈ°λ³Έκ°’**: MCP-compliant + clear schema + actionable error + structured output. λ§€ tool 의 description 의 quality κ°€ agent 의 IQ. ## ⚠️ λͺ¨μˆœ 및 μ—…λ°μ΄νŠΈ (Contradictions & Updates) - **좔상화 μˆ˜μ€€ 의 trade-off**: λ„ˆλ¬΄ high-level (`do_task()`) = agent 의 control λΆ€μ‘±. λ„ˆλ¬΄ low-level (`syscall_5()`) = cognitive load. - **ν‘œμ€€ 의 λΆ€μž¬**: λ§€ harness (Cursor, Devin, AutoGPT) 의 different ACI. λ§€ agent 의 specific lock-in. - **MCP 의 emerging standard**: 2024-2025 의 push. λ§€ IDE 의 native support μ‹œμž‘. - **Tool κ°€ λ„ˆλ¬΄ 많음**: λ§€ LLM 의 context limit. Dynamic / hierarchical tool routing. - **Vision (browser screenshot) vs DOM**: Vision κ°€ robust κ°€, expensive. DOM tree κ°€ cheap κ°€, brittle. ## πŸ”— 지식 μ—°κ²° (Graph) - λΆ€λͺ¨: [[Agent-Architecture]] Β· [[Tool-Use-Function-Calling]] Β· [[Prompt_Engineering|Prompt-Engineering]] - μ‘μš©: [[Claude-Code]] - Related: [[AI-Tool-Composition-Deep]] Β· [[AI-Anthropic-Skills-Patterns]] Β· [[AI-Multi-Agent-Coordination]] ## πŸ€– LLM ν™œμš© 힌트 (How to Use This Knowledge) **μ–Έμ œ 이 지식을 μ“°λŠ”κ°€:** - μƒˆ LLM agent 의 tool design. - MCP server 의 μž‘μ„±. - Agent harness 의 evaluation / improvement. - Production agent 의 quality κ°œμ„ . - Browser / desktop automation. - Code agent (Cursor / Devin alternative) λ””μžμΈ. **μ–Έμ œ μ“°λ©΄ μ•ˆ λ˜λŠ”κ°€:** - Single-shot LLM call (no tool). - Simple chatbot (no agentic). - Pre-built framework (LangChain) κ°€ μΆ©λΆ„ β€” custom κ°€ cost. - ML model serving (λ‹€λ₯Έ domain). ## ❌ μ•ˆν‹°νŒ¨ν„΄ (Anti-Patterns) - **Tool description λͺ¨ν˜Έ**: agent 의 wrong tool 선택. - **Error κ°€ stack trace 만**: agent κ°€ recovery λͺ» 함. - **Output unbounded**: token 폭발. - **Tool list 100+**: λ§€ call 의 cognitive overload. - **Schema loose / no validation**: parsing fail 자주. - **No permission**: λ§€ sensitive operation 의 μœ„ν—˜. - **State visibility μ—†μŒ**: agent 의 wrong assumption. - **Sync tool only (long-running)**: timeout. Sub-agent / async. ## πŸ§ͺ 검증 μƒνƒœ (Validation) - **정보 μƒνƒœ:** verified (concept-level). - **좜처 신뒰도:** B (Anthropic MCP spec, SWE-agent Princeton paper, OpenAI function calling docs). - **κ²€ν†  이유:** Manual cleanup. ACI design κ°€ evolving. MCP 의 standardization κ°€ μ§„ν–‰ 쀑. ## 🧬 쀑볡 검사 (Duplicate Check) - **κΈ°μ‘΄ μœ μ‚¬ λ¬Έμ„œ:** [[AI-Tool-Composition-Deep]] (overlap), [[MCP-Server-Building]] (subset), [[AI-Anthropic-Skills-Patterns]] (related). - **처리 방식:** KEEP (focused on interface design). - **처리 이유:** ACI κ°€ design discipline. Tool composition κ°€ algorithm. MCP κ°€ specific protocol. ## πŸ•“ λ³€κ²½ 이λ ₯ (Changelog) | λ‚ μ§œ | λ³€κ²½ λ‚΄μš© | 처리 방식 | 신뒰도 | |------|-----------|-----------|--------| | 2026-05-08 | P-Reinforce Phase 1 μ •κ·œν™” | UPDATE | A | | 2026-05-09 | Manual cleanup β€” code pattern + design principle + MCP integration + μ•ˆν‹°νŒ¨ν„΄ μΆ”κ°€ | UPDATE | B |