01
エージェントが提案します。人間が承認します。
Ductは、ライブシステムへの変更(キャンペーンの一時停止、除外キーワードの追加、GA4の主要イベントのマークなど)を準備できます。プレビューとガードレールチェックを表示し、そこで停止します。
エージェント向けの承認または適用ツールはありません。無効化されたものでも、フラグの背後にあるものでもありません。モデルが見るツールレジストリには存在しないため、モデルはそれを呼び出すことも、呼び出すように説得されることも、プロンプトインジェクションで呼び出されることもありません。破壊的なゲートは絶対的です。いかなる設定も破壊的な操作の自動適用を許可しません。ロールバックはすべての実行者の契約の一部であり、後付けではありません。
より高い自律性は姿勢であり、より広い許可リストではありません。エージェントがあなたを中断する頻度を変えます。クリックなしで適用される可能性のあるものを変更することはありません。
backend/service/execution/policy.py
02
Ductはエージェントハーネスを借ります。専有しません。
エージェントフレームワークは、このスタックの中で最も変化が激しく、差別化が最も少ないレイヤーです。それらは0.xであり、毎週リリースされ、そのすべてが誰かに破壊的な移行を強いてきました。その上に製品を構築することは、基盤を借りるようなものです。
そのため、ここでのドメインコードはエージェントフレームワークをインポートしません。プロンプト、ツール、スキーマ、目標、スコアリング、およびアーティファクト契約はプレーンなPythonです。フレームワークのインポートはランナーとバインダーのみに存在し、テストは明示的な許可リストで境界を強制します。その許可リストにファイルを追加することは意図的な行為であり、失敗したテストを修正する方法ではありません。
意図的にAgentHarnessインターフェースはなく、今後も存在すべきではありません。交差部分を取ると、サブエージェント、ファイルシステム、スキル、HITLの粒度と圧縮が失われます。これらはハーネスをレンタルするすべての理由です。和集合を取ると、フレームワークを書いていることになります。
backend/agents/core/ports/__init__.py
03
アダプターは最初の実装ではなく、2番目の実装で書きます。
1つの実装を持つポートは推測です。2つの実装を持つポートは事実です。2番目のケースが存在する前に構築された抽象化は、最初のケースが必要としたものを何でもエンコードし、その後はすべてがその形状と戦うことになります。
エージェント層のすべてのポートには2つのアダプターがありますが、1つだけ例外があります。その例外は、自身のドキュメント文字列でその旨を明記し、それに値する実装を指名しています。ギャップを明示することで、推測でひっそりと埋められるのを防ぎます。
STYLE.md
04
認可はメンバーシップであり、APIキーは境界ではありません。
アプリのAPIキーはブラウザに送られます。それは「このリクエストはDuctアプリから来た」ことを証明します。それは「この呼び出し元がその行を所有している」ことを証明したことはなく、そうであるかのように扱うと、マルチテナントのデータ漏洩が発生します。
そのため、プロジェクトスコープの行に触れるすべてのルートは、サインインしたユーザーを解決し、メンバーシップをチェックします。非メンバーは403ではなく404を受け取ります。なぜなら、403は行が存在することを伝えるからです。テストはツリー内のすべてのルートをたどり、書面による理由なしにゲートされていないルートがあればビルドを失敗させます。
backend/tests/test_route_auth_boundaries.py
05
あなたのマシン、あなたのキー、あなたのデータ。
Ductはデスクトップアプリとして動作し、バックエンドをローカルサイドカーとしてバンドルします。ディスク上のSQLite、ループバックのみ、OSキーチェーン内のプロバイダーキーを使用します。アカウントもサーバーもなく、マシンから何も外部に出ることはありません。または、バックエンドをセルフホストすることも可能です。getduct.aiでホストされているバージョンを使用することもできます。これは、公開されているコードと同じコードを実行します。
モデルもご自身で持ち込んでください。Anthropic、OpenAI、Gemini、またはOpenRouter上のあらゆるモデルを、推論に重い作業と安価な要約が同じ価格にならないように、3つの階層にわたってジョブごとに割り当てます。ビジネス全体を読み取るツールが、ベンダーを決定すべきではありません。
desktop/README.md
06
コメントは「なぜ」を伝えます。差分はすでに「何を」示しています。
その下の行を繰り返すコメントは、コメントがないよりも悪いものです。なぜなら、読者にコメントをスキップするように教えてしまうからです。書く価値のあるコメントは、コードでは表現できないもの、つまり制約、契約、その行を動機付けた失敗、却下された代替案とその理由を伝えます。
これは、エージェントによって部分的に書かれたコードベースでは、より重要であり、軽視すべきではありません。個々に正当化できる変更のセットが、全体としてアーキテクチャを溶解させるのが、エージェント加速型コードベースが失敗する具体的な方法です。すべての変更はそれ自体を主張し、全体を主張するものはありません。ファイルに残された推論が、次の人、または次のモデルが違いを判断できるようにします。
STYLE.md
07
エージェントが作成した貢献も歓迎します。ただし、レビューはより厳しく行われます。
多くのプロジェクトがAI支援のプルリクエストを静かに禁止しています。Ductは逆を求めます。PRテンプレートはエージェントがどこで支援したかを尋ね、レビュー担当者が最も注意深く見るべき場所を知るようにします。それはペナルティボックスではありません。それは、変更のどの部分について最も確信がなかったかを伝えるのと同じ理由です。
Ductは、エージェントで構築されたエージェント製品です。貢献プロセスにおいてそうでないふりをするのは不誠実であり、レビュアーが得られる最も有用なシグナルを捨てることになります。
CONTRIBUTING.md