Skip to content

Quickstart

이 문서는 ddd-agent를 처음 쓰는 사람이 "무엇을 구현해야 하는지"를 빠르게 이해하도록 돕는 입구입니다.

목표:

  • 5분 안에 패키지 구조를 파악한다
  • packaged CLI와 example app을 직접 실행한다
  • 새 도메인 agent를 만들 때 필요한 최소 구현 지점을 이해한다

1. Install

루트 프로젝트에서 먼저 의존성을 동기화합니다.

uv sync

문서도 같이 보려면:

make docs-sync
make docs

2. Run The Built-in LangGraph Demo

가장 빠른 시작점은 packaged CLI입니다.

uv run domain-agent-demo

이 명령은 generic core만으로 동작하는 review-enabled flow를 보여줍니다.

함께 보면 좋은 명령:

uv run domain-agent-graph --format mermaid

이 그래프는 core workflow가 어떤 단계를 거치는지 보여줍니다.

GUI로 보고 싶다면:

cd examples/streamlit_review_demo
uv sync
uv run streamlit run streamlit_review_demo/app.py

이 앱은 같은 graph와 같은 AgentWorkflowService를 그대로 쓰고, 입력과 review handler만 브라우저 UI로 바꿉니다.

3. Pick A Starting Example

이 저장소의 example app은 "새 도메인을 어디서부터 시작해야 하는가"를 보여주기 위해 분리되어 있습니다.

Autonomous flow

PYTHONPATH=src:examples/autonomous_digest ./.venv/bin/python -m pytest -q examples/autonomous_digest/tests
PYTHONPATH=src:examples/langchain_digest ./.venv/bin/python -m pytest -q examples/langchain_digest/tests

이 예제들은:

  • 사람 review 없이 실행되는 agent
  • requires_human_review=False
  • 가장 단순한 AgentEngineActionExecutor
  • LangChain-backed AgentEngine example

를 보여줍니다.

Review-enabled flow

PYTHONPATH=src:examples/langchain_repo_triage ./.venv/bin/python -m pytest -q examples/langchain_repo_triage/tests
PYTHONPATH=src:examples/operational_change ./.venv/bin/python -m pytest -q examples/operational_change/tests
PYTHONPATH=src:examples/mock_api ./.venv/bin/python -m pytest -q examples/mock_api/tests
PYTHONPATH=src:examples/github_repo_review ./.venv/bin/python -m pytest -q examples/github_repo_review/tests

이 예제들은:

  • human review가 들어가는 flow
  • ReviewPacketPlanReviewResult
  • action-level partial review / partial execution
  • observation과 tool usage 흔적이 review surface에 나타나는 흐름
  • 실제 HTTP API에서 context를 읽어 오는 adapter

을 보여줍니다.

특히 GitHub API example은 실제로 이렇게 실행할 수 있습니다.

cd examples/github_repo_review
uv sync
uv run github-repo-review-demo --owner python --repository cpython --review approve

4. Build A New Domain Agent

새 도메인은 보통 src/domain_agent를 먼저 수정하지 않고, example app과 같은 방식으로 바깥에서 조합하는 것이 맞습니다.

최소 단계:

  1. 도메인별 request model을 만든다
  2. generic Request로 변환한다
  3. ContextProvider를 구현한다
  4. AgentEngine을 구현한다
  5. ActionExecutor를 구현한다
  6. human review가 필요하면 review_handler를 연결한다

가장 작은 뼈대는 아래와 같습니다.

from collections.abc import Mapping
from dataclasses import dataclass

from domain_agent.application.dto import AgentWorkResult, AnalysisResult
from domain_agent.application.ports import ActionExecutor, AgentEngine, ContextProvider
from domain_agent.domain import AgentPlan, PlannedAction, Proposal, Request, RiskLevel


@dataclass(frozen=True)
class DemoContextProvider(ContextProvider):
    def get_context(self, request: Request) -> dict[str, object]:
        return {"request_id": request.request_id, "source": "demo"}


@dataclass(frozen=True)
class DemoAgentEngine(AgentEngine):
    def prepare(self, request: Request, context: Mapping[str, object]) -> AgentWorkResult:
        analysis = AnalysisResult(
            summary=f"Analyze {request.request_id}",
            rationale=f"context={context}",
            execution_steps=("inspect inputs", "run approved action"),
            risk_level=RiskLevel.LOW,
        )
        agent_plan = AgentPlan(
            summary="Simple plan",
            rationale=analysis.rationale,
            actions=(
                PlannedAction(
                    action_id=f"{request.request_id}-action-1",
                    tool_name="demo_tool",
                    description="Run the demo action",
                ),
            ),
            expected_outcome="The demo action is completed.",
            risk_level=analysis.risk_level,
        )
        proposal = Proposal(
            summary="Simple proposal",
            rationale=analysis.rationale,
            execution_steps=analysis.execution_steps,
            risk_level=analysis.risk_level,
            prepared_by="demo-agent",
            agent_plan=agent_plan,
        )
        return AgentWorkResult(
            analysis=analysis,
            proposal=proposal,
            agent_plan=agent_plan,
        )


@dataclass
class DemoActionExecutor(ActionExecutor):
    def execute(self, request: Request, agent_plan: AgentPlan | None = None) -> str:
        return f"Executed {request.request_id}"

이 세 구현체를 WorkflowDependencies에 넣으면 새 agent app의 기본 wiring이 완성됩니다.

5. Know The Four Core Contracts

새 앱을 만들 때 가장 자주 만지는 것은 아래 4개입니다.

  • RequestRepository: request persistence
  • ContextProvider: external context collection
  • AgentEngine: analysis + plan + proposal preparation
  • ActionExecutor: reviewed action execution

즉, 이 템플릿은 "framework를 새로 만들기"보다 "이 4개 경계를 안정적으로 유지하며 도메인 앱을 만든다"에 가깝습니다.

6. LangGraph And LangChain In Practice

이 저장소에서 실제로 참고할 파일은 아래 두 곳입니다.

  • LangGraph core wiring:
  • src/domain_agent/orchestration/langgraph/graph.py
  • src/domain_agent/application/use_cases.py
  • LangChain integration:
  • src/domain_agent/adapters/outbound/langchain.py
  • examples/langchain_digest/langchain_digest_demo/bootstrap.py

즉:

  • LangGraph는 graph shape와 interrupt/resume을 담당
  • LangChain은 AgentEngine 구현체 안에서 structured output을 만드는 역할
  • 실제 external side effect는 ActionExecutor가 담당

7. Where To Go Next

Code References

  • src/domain_agent/application/ports.py
  • src/domain_agent/application/use_cases.py
  • src/domain_agent/domain/models.py
  • examples/autonomous_digest/autonomous_digest_demo/bootstrap.py
  • examples/langchain_digest/langchain_digest_demo/bootstrap.py
  • examples/github_repo_review/github_repo_review_demo/bootstrap.py
  • examples/streamlit_review_demo/streamlit_review_demo/app.py
  • examples/operational_change/operational_change_demo/bootstrap.py
  • examples/mock_api/mock_api_demo/bootstrap.py