본문으로 건너뛰기

커스텀 Function 배포와 사용

현재 Component 경계

현재 @px.component의 책임은 process-local companion metadata와 Python annotation 기반 port shape 등록까지입니다. 별도 V1 container의 기존 presentation·settings wire는 호환을 위해 보존하지만, 저장된 exact Component target은 production Flow reader에서 unsupported로 표시됩니다. exact ProjectScope data-path isolation은 구현됐지만 current installer에는 안전한 inactive quarantine이 없으므로 authenticated-principal authorization과 execution-trust closure가 모두 닫힐 때까지 production third-party Component install admission과 activation을 열지 않습니다. 후속 V2 Canvas는 package UI를 마운트하지 않고 host-owned component.declarative@2만 사용합니다. settings를 component-declared-settings@1로 선언당 최대 8개까지 받고 host control registry가 그립니다. rich surface는 RFC-016의 component-rich-surface-declaration@1이 소유하며 bridge는 Node context 읽기와 settings 제안까지만 허용합니다.

커스텀 Function을 package로 배포하면 설치 사용자는 Definitions → Functions에서 definition을 찾습니다. definition을 설치하거나 import하는 것만으로는 Canvas에 아무것도 생기지 않습니다. Studio의 Place Node 또는 SDK의 node = flow.node("node_key", function_target)가 실제 Function Reference Node를 배치합니다.

  • @px.function은 reusable Function definition과 metadata를 등록합니다.
  • decorator는 함수를 실행하거나 nodeKey, layout, connection과 Run을 소유하지 않습니다.
  • flow.input(...), flow.connect(...), flow.result(...)가 Flow interface와 wiring을 명시합니다.
  • AI는 MCP로 같은 FunctionDescriptor와 generated usage를 읽습니다.

Component companion target은 @px.component로 등록합니다. 기존 V1 artifact/internal fixture의 flow.node(...) placement shape는 exact Component target을 저장하고 production reader는 이를 unsupported로 표시합니다. 후속 V2의 Node body와 Port는 package renderer가 아니라 host-owned component.declarative@2이 그립니다.

Function source를 한 번 작성하고 Studio, SDK, 저장된 Flow와 MCP에서 같은 계약을 사용합니다.

먼저 구분할 세 가지

개념의미생성되는 시점
FunctionCanvas Node가 실행할 계산 definitionPython 함수에 explicit key를 가진 @px.function을 붙이면 등록
Nodetarget을 stable nodeKey로 특정 Flow에 배치한 실제 사용처Studio의 Place Node 또는 flow.node(...)
FlowNode, connection, public input/result를 담는 실행 단위flow = px.Flow("flow_key", ...)

V1 flow.node(...) target union은 explicit key를 가진 @px.function과 imported @px.component shape를 모두 기록하지만, 현재 production 실행 경로는 supported Function입니다. Component target은 existing V1 bytes에서 read-only unsupported로 보존합니다. decorator 없는 일반 Python def는 Function·Component 내부 helper로 사용하며 Canvas Node target으로 배치하지 않습니다.

python
from pipelinexlab import px
from project_checks import check_area
from section_tools import rectangular_section


flow = px.Flow(
    "section_review",
    label="Section review",
    description="Checks one section.",
)
width = flow.input("width", float, unit="mm", description="Section width.")
depth = flow.input("depth", float, unit="mm", description="Section depth.")
minimum_area = flow.input(
    "minimum_area",
    float,
    unit="mm2",
    description="Minimum required area.",
)

section = flow.node("gross_section", rectangular_section)
area_check = flow.node("area_check", check_area)
flow.connect(width, section.inputs.width)
flow.connect(depth, section.inputs.depth)
flow.connect(section.results.area, area_check.inputs.area)
flow.connect(minimum_area, area_check.inputs.minimum_area)
flow.result("area", section.results.area)
flow.result("passed", area_check.results.passed)

check_arearectangular_section은 각 package의 public module이 내보낸 explicit-key @px.function target입니다. 두 Function은 Node key를 다르게 정해 같은 Flow나 다른 Flow에 여러 번 배치할 수 있습니다.

.py Flow module은 top-level public flow object를 정확히 하나 export합니다. 별도 module의 exported Flow를 재사용할 때는 flow.subflow("subflow_key", imported_flow)를 사용합니다. same-Flow flow.group(...)은 presentation membership만 바꿉니다.

처음부터 끝까지 보는 전체 과정

다음 과정에서 같은 rectangular_section Function이 어떻게 설치되고 Node가 되는지 확인할 수 있습니다.

Function 제공자는 계약을 배포하고, 사용자는 Node로 배치하며, AI는 같은 계약을 읽어 승인 가능한 변경을 제안합니다.

Studio에서 만드는 경우

Package를 설치한 사용자는 다음 순서로 작업합니다.

  1. Project의 Dependencies에서 section_tools를 설치합니다.
  2. PXFLOW Studio에서 새 Flow를 만듭니다.
  3. Main toolbar의 Definitions → Functions에서 Rectangular section을 검색합니다.
  4. Function의 목적, version, width, deptharea를 확인합니다.
  5. Place Node를 누르고 배치할 Flow와 nodeKey를 확인합니다.
  6. 이 Flow 안에서 사용할 Node key를 gross_section으로 정합니다.
  7. widthdepth를 Flow input 또는 이전 Node result에 연결합니다.
  8. area를 다음 Node input에 연결하거나 Flow result로 공개합니다.
  9. Validate로 누락된 입력과 단위 호환성을 확인한 뒤 저장합니다.

Function과 배치할 Flow 및 stable nodeKey를 확인하는 Place Node 화면

Place Node 화면 — target Flow와 stable nodeKey를 확인한 뒤 Function Reference Node를 캔버스에 배치합니다.

완성된 화면의 의미는 다음과 같습니다.

Studio의 두 연결선과 공개 result가 SDK의 flow.connect 및 flow.result 선언에 대응합니다.

FunctionDescriptor에서 Node 사각형, input/result 연결점, 기본 입력 form과 일반 Node를 더블클릭했을 때 열리는 중앙 상세 modal을 생성합니다. Component companion target은 @px.component로 등록하지만, 후속 V2 Canvas는 같은 host-owned component.declarative@2 projection만 사용합니다.

SDK에서 같은 Flow를 만드는 경우

Studio에서 한 작업은 다음 module-level SDK code와 같은 의미입니다.

python
from pipelinexlab import px
from section_tools import rectangular_section


flow = px.Flow(
    "section_properties",
    label="Section properties",
    description="Calculates properties for one rectangular section.",
)
width = flow.input("width", float, unit="mm", description="Section width.")
depth = flow.input("depth", float, unit="mm", description="Section depth.")

section = flow.node("gross_section", rectangular_section)
flow.connect(width, section.inputs.width)
flow.connect(depth, section.inputs.depth)
flow.result("area", section.results.area)
Studio에서 한 작업SDK code
새 Flow 만들기flow = px.Flow("section_properties", ...)
Definitions → Functions에서 Function 선택rectangular_section import
Canvas에 Function 배치flow.node("gross_section", rectangular_section)
Flow width를 Node width에 연결flow.connect(width, section.inputs.width)
Flow depth를 Node depth에 연결flow.connect(depth, section.inputs.depth)
Node area를 Flow result로 공개flow.result("area", section.results.area)

자동으로 만들어지는 것과 직접 정하는 것

자동으로 제공되는 항목사용자가 직접 정하는 항목
Project Definitions의 이름, 설명과 version현재 Flow에서 사용할 Function
Node의 input/result 연결점과 단위Node key와 화면 label
기본 입력 form과 validation message각 input에 연결할 값
Python import와 generated type stub어떤 result를 다음 Node 또는 Flow result에 연결할지
MCP가 읽는 Function 설명과 SDK 예제Flow의 실행 구조, 반복과 공개 범위
package update와 호환성 비교 정보update 승인과 끊어진 연결의 수정

Chart, 3D preview, 전용 file picker와 같은 rich surface는 현재 Component 또는 V2 Canvas 계약에 포함하지 않습니다. reusable Component companion은 @px.component로 등록할 수 있지만 V2 Canvas에는 host-owned component.declarative@2만 투영합니다. rich surface의 package field와 사용자 흐름은 RFC-016의 component-rich-surface-declaration@1이 정의합니다.

1. 기능 제공자가 작성하는 것

Function은 일반 SDK 문법으로 작성합니다.

python
from pipelinexlab import px


class SectionResults(px.Results):
    area: float


@px.function(
    key="rectangular_section",
    version="1.0.0",
    description="Calculates the gross area of a rectangular section.",
)
def rectangular_section(width: float, depth: float) -> SectionResults:
    return SectionResults(area=width * depth)

Package는 계산 선언 외에 안정적인 public Python module을 명시합니다.

toml
[project]
name = "pipelinexlab-section-tools"
version = "1.2.0"

[tool.pipelinexlab]
contract-version = 1
package-key = "section_tools"
entry-module = "section_tools.catalog"
public-module = "section_tools"
manual-root = "docs"
  • entry-module은 descriptor와 Flow declaration을 검사하는 승인된 module입니다.
  • public-module은 package를 설치한 사용자가 import하는 안정적인 Python module입니다.
  • package-key는 catalog와 저장 참조에서 사용하는 semantic key입니다.
  • @px.function(key=...)는 package 안에서 유지되는 explicit stable functionKey입니다. Python symbol은 import와 IDE 사용성을 위한 이름이며 Function identity를 대신하지 않습니다.

Public module은 지원하는 Function과 public type을 명시적으로 다시 내보냅니다.

python
# src/section_tools/__init__.py
from .catalog import SectionResults, rectangular_section

__all__ = ["SectionResults", "rectangular_section"]

pxlab package check는 public module을 import해 다음 조건을 검사합니다.

  • 공개한 Function 객체가 entry module의 exact declaration과 같습니다.
  • public symbol이 descriptor의 exact functionKey에 명시적으로 mapping되어 있고 중복되지 않습니다. Python symbol을 rename해도 decorator의 key를 유지하면 FunctionRef identity는 바뀌지 않습니다.
  • Record와 Results type이 SDK signature를 완성하는 데 필요한 만큼 공개되어 있습니다.
  • public module import가 declaration-only이며 side effect 없이 완료되는지 검사합니다.
  • package build가 descriptor와 일치하는 .pyi type stub을 포함합니다.

Build가 FunctionDescriptor와 public symbols에서 .pyi를 생성합니다.

python
# generated section_tools/__init__.pyi
from pipelinexlab import px


class SectionResults(px.Results):
    area: float


def rectangular_section(
    width: float,
    depth: float,
) -> SectionResults: ...

Function 내부 구현이 Python, Rust native module 또는 승인된 remote adapter여도 소비자 문법은 같습니다. package는 public Python facade, .pyi, FunctionDescriptor와 매뉴얼을 제공하고 LLM discovery에는 이 공개 계약을 전달합니다.

2. 설치 package가 제공하는 SDK 문법

다른 사용자는 public module에서 Function definition을 import하고, Flow module에서 explicit placement와 connection을 작성합니다.

python
from pipelinexlab import px
from section_tools import rectangular_section


flow = px.Flow(
    "section_properties",
    label="Section properties",
    description="Calculates properties for one rectangular section.",
)
width = flow.input("width", float, unit="mm", description="Section width.")
depth = flow.input("depth", float, unit="mm", description="Section depth.")

section = flow.node("gross_section", rectangular_section)
flow.connect(width, section.inputs.width)
flow.connect(depth, section.inputs.depth)
flow.result("area", section.results.area)
code의미
rectangular_section설치한 package의 reusable Function definition
gross_section현재 Flow가 소유하는 stable Node key
section.inputs.width배치된 Node의 exact input destination
section.results.area배치된 Node의 named result source

public import와 handle-based explicit wiring은 IDE, type checker와 refactor가 exact target과 port를 추적하게 합니다.

3. 다른 사용자가 설치하는 방법

사용자는 자신이 작성 중인 SDK package 또는 Project에서 dependency를 추가합니다.

bash
pxlab dependency add section_tools@^1.2.0

명령은 다음 순서로 동작합니다.

  1. 로그인한 사용자가 해당 package와 version을 사용할 수 있는지 확인합니다.
  2. signed release, license, capability, SBOM과 지원 platform을 보여 줍니다.
  3. 사용자가 승인하면 호환되는 exact version을 dependency lock에 기록합니다.
  4. Python public module, .pyi stub과 필요한 실행 artifact를 app-private environment에 설치합니다.
  5. Project Definitions의 Function read model과 MCP Function catalog를 같은 resolved package version과 signed descriptor digest에서 갱신합니다.

작성 source에는 사람이 선택한 SemVer range를 남기고, Flow를 materialize할 때 exact signed FunctionRef를 고정합니다. Upgrade는 영향 preview와 사용자 승인 뒤 새 Flow revision으로 저장합니다.

Dependency 선언은 다음처럼 저장됩니다.

toml
[tool.pipelinexlab.dependencies]
section_tools = "^1.2.0"

Generated lock에는 exact package version, platform, package digest, dependency lock digest와 release signature reference가 들어갑니다. Python source는 public import와 dependency range만 소유합니다.

4. PXFLOW에서 커스텀 Node로 사용하는 방법

설치가 끝나면 Project Definitions → Functions에 다음 정보가 표시됩니다.

  • package label과 packageKey
  • Function 이름, version과 description
  • input/result 이름, type, unit, required와 constraints
  • file, network, secret과 GPU capability
  • manual과 예제
  • 개발, stable, deprecated 또는 blocked 상태

사용자가 Function을 Canvas에 놓는 순간 Function Reference Node가 만들어집니다. Node key는 Flow 안의 사용 목적에 맞게 정합니다.

text
Function: section_tools/rectangular_section@1.0.0
Function Reference Node: gross_section

같은 Function을 gross_section, web_section처럼 여러 Node로 배치할 수 있습니다. Function version은 같아도 각 Node의 입력 연결과 실행 위치는 서로 다릅니다.

FunctionDescriptor에서 기본 Node 화면, input/result port, form, validation message와 일반 Node를 더블클릭했을 때 열리는 중앙 상세 modal을 생성합니다. chart, 3D preview처럼 넓은 surface가 필요해도 Component V2 package에 renderer·modal을 추가하지 않습니다. V2 Canvas는 host-owned component.declarative@2만 사용하고, rich surface의 형식과 동작은 RFC-016의 component-rich-surface-declaration@1이 정의합니다. 현재 production reader의 Component target 표시는 unsupported입니다.

5. 완성된 Flow를 다른 곳에서 사용하는 방법

Node 연결이 끝났다면 외부에서 사용할 값만 Flow input과 Flow result로 공개합니다. 이것이 다른 Flow, Component와 일반 AI 작업이 우선 사용하는 안정적인 연결면입니다.

상위 Flow는 External Flow 내부 Node 대신 저장된 public input과 result에 연결합니다.

Component target 연결하기 · 계획 V2 surface

V1 wire와 내부 fixture는 container당 하나의 declaration, exact 7-field ComponentRef, raw settings와 binding을 계속 보존합니다. 이는 production third-party install/placement workflow가 아닙니다. 구현된 exact ProjectScope data-path isolation에 Project authorization과 execution-trust closure가 더해진 뒤에만 Component를 Project dependencies에 admit하고 companion target을 배치할 수 있습니다.

두 closure와 V2 host-declarative surface가 모두 구현되면 다음 최소 흐름으로 이어집니다.

  1. Components → Installed에서 호환되는 Component를 Add합니다.
  2. Canvas의 area result를 Component Node input에 연결합니다.
  3. host-owned component.declarative@2 Node에서 exact identity와 Port를 확인합니다.
  4. PXFLOW에서 Validate → Save → Run합니다.

이 흐름에는 package-provided Settings, renderer 또는 editor가 없습니다. V2 settings를 component-declared-settings@1로 선언당 최대 8개까지 받고 host control registry가 그립니다. rich surface의 동작과 entry·message 형식은 RFC-016의 component-rich-surface-declaration@1이 정의합니다.

기존 V1 document에 저장된 Component Node binding은 upstream named result를 일반 input binding으로 보존합니다. 현재 reader는 이를 read-only unsupported로 표시하고 실행하지 않습니다. 재사용 Flow의 public interface는 이름이 비슷한 Component로 자동 대체하지 않습니다.

다른 Flow에서 사용하기

완성한 Flow는 owning .py module이 export한 flow object로 재사용합니다. caller는 이 object를 flow.subflow(...)로 배치합니다.

python
from pipelinexlab import px
from section_tools.flows.section_properties import flow as section_properties_flow


flow = px.Flow(
    "member_review",
    label="Member review",
    description="Checks one member using the section properties Flow.",
)
width = flow.input("width", float, unit="mm", description="Section width.")
depth = flow.input("depth", float, unit="mm", description="Section depth.")

section_properties = flow.subflow(
    "section_properties",
    section_properties_flow,
)
flow.connect(width, section_properties.inputs.width)
flow.connect(depth, section_properties.inputs.depth)
flow.result("area", section_properties.results.area)

external Flow는 caller에서 읽기 전용인 nested Flow입니다. 내부를 수정할 때는 Edit source Flow로 owning module을 엽니다. imported Flow를 flow.node(...) target으로 전달하지 않습니다. 같은 Flow의 flow.group(...)은 presentation membership만 선언합니다.

사용자가 직접 code를 작성하는 경우

설치된 Function은 public module에서 import하고 실제 Node를 배치한 뒤 연결합니다.

python
from section_tools import rectangular_section


section = flow.node("gross_section", rectangular_section)
flow.connect(width, section.inputs.width)
flow.connect(depth, section.inputs.depth)
flow.result("area", section.results.area)

Studio, SDK와 AI가 gross_section, width, deptharea라는 같은 key를 사용합니다.

6. 설치된 기능 정보를 LLM에 전달하는 방법

LLM에는 MCP discovery 도구로 현재 단계에 필요한 공개 계약을 순서대로 제공합니다.

LLM은 source를 추측하지 않고 discovery 계약과 사용자 승인을 통해 Flow 변경을 적용합니다.

Project scope와 검색어를 보내 후보를 찾습니다.

json
{
  "scope": {
    "kind": "project",
    "workspaceKey": "structural_team",
    "projectKey": "bridge_package"
  },
  "query": "section area",
  "limit": 25
}

응답은 후보를 고르는 데 필요한 최소 정보와 page 상태를 반환합니다.

json
{
  "items": [
    {
      "packageKey": "section_tools",
      "functionKey": "rectangular_section",
      "packageVersion": "1.2.0",
      "packageDigest": "sha256:<exact package digest>",
      "functionVersion": "1.0.0",
      "description": "Calculates the gross area of a rectangular section.",
      "availability": "installed",
      "compatibility": "compatible"
    }
  ],
  "nextCursor": null,
  "appliedLimit": 25,
  "truncation": {
    "truncated": false
  }
}

검색 결과에서는 후보만 고르고, function_describe의 exact FunctionRef와 typed contract를 확인한 뒤 Node 추가를 계획합니다. nextCursor가 있으면 같은 scope와 query에 cursor를 더해 다음 page를 읽습니다.

6.2 function_describe

후보를 고른 뒤 exact Function을 설명합니다.

json
{
  "functionRef": {
    "kind": "function",
    "packageKey": "section_tools",
    "packageVersion": "1.2.0",
    "packageDigest": "sha256:<exact package digest>",
    "releaseByteDigest": "sha256:<exact release envelope digest>",
    "descriptorDigest": "sha256:<exact FunctionDescriptor digest>",
    "functionKey": "rectangular_section",
    "functionVersion": "1.0.0"
  },
  "sdk": {
    "module": "section_tools",
    "functionSymbol": "rectangular_section",
    "resultSymbol": "SectionResults"
  },
  "description": "Calculates the gross area of a rectangular section.",
  "inputs": [
    {
      "portKey": "depth",
      "type": { "kind": "float64" },
      "unit": "mm",
      "required": true,
      "constraints": { "exclusiveMinimum": 0 }
    },
    {
      "portKey": "width",
      "type": { "kind": "float64" },
      "unit": "mm",
      "required": true,
      "constraints": { "exclusiveMinimum": 0 }
    }
  ],
  "results": [
    {
      "portKey": "area",
      "type": { "kind": "float64" },
      "unit": "mm2"
    }
  ],
  "sdkExample": "from section_tools import rectangular_section\n\nsection = flow.node(\"gross_section\", rectangular_section)\nflow.connect(width, section.inputs.width)\nflow.connect(depth, section.inputs.depth)\nflow.result(\"area\", section.results.area)",
  "manuals": [
    {
      "locale": "ko",
      "title": "직사각형 단면 계산 사용하기",
      "resourceRef": "<authorized version-pinned manual resource>"
    }
  ]
}

FunctionRef의 exact field는 위 여덟 개로 고정합니다. Registry의 opaque release ID, filesystem path와 Python symbol은 portable FunctionRef에 넣지 않습니다. sdk.modulesdk.functionSymbol은 같은 Function을 Python에서 import하기 위한 projection이며 symbol을 rename해도 explicit functionKey를 유지하면 저장된 Node identity는 유지됩니다.

sdkExample은 별도 손작성 문법이 아니라 descriptor의 public module, symbol과 port에서 결정적으로 생성합니다. LLM은 exact import와 parameter 이름을 그대로 사용합니다.

6.3 LLM에 전달하는 정보와 전달하지 않는 정보

전달기본적으로 전달하지 않음
package/function key와 exact versionFunction 구현 source 전체
목적을 설명하는 descriptionwheel, native library와 build output bytes
input/result type, unit, constraint와 defaultsecret 값과 사용자 credential
policy, capability와 예상 side effect다른 Project의 설치 목록과 데이터
public Python module, symbol과 generated usage내부 UUID와 registry database key
현재 질문과 관련된 manual/example 일부package 매뉴얼 전체와 무관한 예제
license·deprecated·blocked 상태raw stack trace와 host path

Manual은 Function을 이해하기 위한 비신뢰 reference data로 처리합니다. 실제 변경과 실행은 typed MCP plan, server-side authorization과 사용자 승인을 거칩니다.

7. 커스텀 Function 매뉴얼 작성

매뉴얼은 Function package의 같은 release에 포함합니다.

text
docs/
├─ ko/
│  ├─ index.md
│  └─ functions/
│     └─ rectangular_section.md
└─ en/
   ├─ index.md
   └─ functions/
      └─ rectangular_section.md

Function 문서는 semantic key로 연결합니다.

yaml
---
title: 직사각형 단면 계산 사용하기
description: 폭과 깊이로 총단면적을 계산하고 PXFLOW에 연결하는 방법입니다.
audience: user
contributions:
  - function:rectangular_section
since: 1.0.0
---

본문은 다음 순서로 작성합니다.

  1. 이 Function이 해결하는 문제
  2. 적합한 사용 상황과 사용하면 안 되는 상황
  3. 필요한 입력의 실무적 의미와 기준 위치
  4. PXFLOW에서 Node를 추가하고 연결하는 과정
  5. Python SDK import와 작은 Flow 예제
  6. 결과를 확인하는 방법
  7. 오류와 복구 방법
  8. version이 바뀔 때 주의할 호환성

정확한 signature, type, unit, default와 constraint 표는 FunctionDescriptor에서 자동 생성합니다. 매뉴얼에는 사용자가 이해해야 하는 업무 의미와 절차를 추가합니다.

8. 업데이트와 제거

  • 배포된 (packageKey, functionKey, version)의 source, descriptor와 byte digest는 immutable입니다. 같은 version의 body나 계약을 교체하지 않고 새 Function/package release를 만듭니다.
  • 기존 Flow는 저장된 exact FunctionRef를 계속 사용합니다.
  • Project가 소유한 Function은 Definitions → Functions → Open Function에서 source를 엽니다. 변경 전에 모든 사용 중인 Node와 계약 차이를 보여 주고, 승인한 사용처를 새 Function·Flow revision으로 함께 갱신합니다. 한 Node만 다르게 만들 때는 Function을 Clone / branch하고 그 Node의 참조만 새 Function으로 바꿉니다.
  • Studio와 CLI는 기존 version과 새 version의 port, type, unit, capability와 결과 의미 차이를 보여 줍니다.
  • 사용자가 Upgrade를 승인하면 영향받는 Flow와 Component binding을 먼저 검증하고 새 revision을 만듭니다.
  • public module이나 symbol 변경은 SDK import compatibility를 깨뜨릴 수 있으므로 package SemVer와 migration guide가 필요합니다. Explicit functionKey를 유지하면 FunctionRef identity는 유지되며, 계산·port 계약이 바뀔 때만 Function version 정책을 적용합니다.
  • 제거 전 해당 Function을 사용하는 Node, Flow와 saved Run 목록을 보여 줍니다.
  • package를 사용할 수 없는 환경에서도 Flow는 FunctionRef와 interface를 보존하고 unavailable Node로 표시합니다.

port 계약 변경 전후와 영향받는 Node를 확인하고 새 branch를 만드는 화면

영향 분석 화면 — 사용 중인 port 계약이 바뀌면 before/after와 영향받는 Node를 먼저 보여 주고, 기존 참조를 유지한 새 branch 생성을 요구합니다.

9. 제공자와 설치 사용자 검증

기능 제공자

bash
python -m pytest
pxlab package check .
pxlab package build . --output dist/release
pxlab package publish dist/release --channel stable

설치 사용자

bash
pxlab dependency add section_tools@^1.2.0
pxlab package check .
pxlab studio open . --flow section_properties

최종적으로 다음 네 결과가 같아야 합니다.

  1. IDE가 표시하는 Python signature와 .pyi type
  2. PXFLOW Node의 input/result port
  3. function_describe가 LLM에 반환하는 schema와 generated SDK usage
  4. materialize된 .pxflow의 exact FunctionRef와 interface

자주 혼동하는 부분

Function을 설치한 뒤 Node는 어떻게 만듭니까?

설치 후 Project Definitions → Functions에서 Function을 찾고 Place Node를 실행하세요. SDK에서는 Flow module에 flow.node(...)를 작성하고 flow.connect(...)로 연결합니다.

shared Function에는 어떤 Node UI를 사용합니까?

Function의 input, result, type, unit과 description이 기본 Function Reference Node UI의 원본입니다. reusable Component companion은 @px.component로 등록하고 flow.node(...)로 exact target을 배치합니다. 후속 V2 Canvas는 host-owned component.declarative@2만 사용하며, settings를 component-declared-settings@1로 선언당 최대 8개까지 받고 host control registry가 그립니다. rich surface는 RFC-016의 component-rich-surface-declaration@1이 소유하므로 이 가이드는 renderer·modal·entry·message 형식을 다시 정의하지 않습니다.

Flow에서 어떤 코드가 Node가 됩니까?

flow.node(...) placement 하나가 실제 Canvas Node 하나가 됩니다. Flow module에는 top-level declarative placement와 explicit connection을 작성하고, 일반 Python 계산과 helper 함수는 helpers=[...]로 선언해 Function revision에 싣습니다.

같은 Function을 여러 번 배치할 수 있습니까?

가능합니다. Function은 하나지만 Node key를 다르게 정하면 여러 사용처가 됩니다. 각 Node는 서로 다른 입력, 위치와 downstream 연결을 가질 수 있습니다.

Function과 Flow 중 무엇을 다른 사용자에게 제공합니까?

재사용할 계산 단위는 Function으로 제공합니다. 사용자가 바로 열고 실행할 완성된 계산 절차도 제공하려면 같은 package의 별도 .py module에서 exported flow object를 함께 제공합니다. 설치 사용자는 Function으로 새 Flow를 만들거나, exported Flow를 flow.subflow(...)로 read-only nested Flow에 배치하고 필요한 Component에 결과를 연결할 수 있습니다.

AI가 커스텀 Function을 어떻게 압니까?

Package 설치 시 같은 FunctionDescriptor가 PXFLOW와 MCP catalog에 등록됩니다. AI는 function_searchfunction_describe로 exact Function, port와 generated SDK 예제를 확인합니다.

다음 문서