Can TypeSafe’s Jev Make AI Agents Safer Without Another LLM?

Can TypeSafe’s Jev Make AI Agents Safer Without Another LLM?


I am very forgiving of an agent that is only talking. If it gets a draft or summary wrong, I crash out at my screen and ask again, and since nothing outside the chat window has changed, a retry is all it costs me.

But the mood changes once the agent gets a tool. A wrong answer can now mean a sent email or a moved payment, and the usual fix, which is putting a second model in front to check the first, starts to feel like hiring an intern to supervise an intern.

One of the simplest guardrail cases I wrote down was also the one that bothered me most.

A customer gets charged twice for a $12 purchase and asks an AI agent for a refund. The agent picks the right tool and the right customer, then prepares this:

issue_refund(    customer_id="C1043",    amount_cents=120_000,  # the customer approved 1_200 cents)

Nothing in that call looks broken. The customer ID is valid, amount_cents is an integer, and the refund tool’s schema accepts it.

The two duplicate charges on the account, ch_1 and ch_2, were 1,200 cents each, so the amount is off by a factor of one hundred, which is what converting dollars to cents twice looks like.

I am not really worried about the dramatic failure where a model completely loses the plot.

The failures that bother me the most are the ordinary ones, where the action looks reasonable, and the mistake only becomes obvious after something real has happened.

My first reaction to this one was: easy. Put a hard $500 refund limit in front of the tool and move on.

Then I changed the bad amount from $1,200 to $120. That sits under the cap, so the limit I had just reached for never fires, and the customer still gets ten times what they approved.

That small change is what pulled me into TypeSafe AI’s Jev model.

TypeSafe released Jev on September 15 as the first of what it calls System One Models, a class of models built to make fast, structured decisions that software can use directly.

It is still in early access, for what that is worth. Instead of generating another paragraph, Jev takes application state and a bounded question, then returns a typed probabilistic answer.

TypeSafe’s launch post frames this as a different job from a normal chat model: less generation, more decision-making. Guardrails for LLM inputs and outputs are on its list of intended uses, which is adjacent to what I want here.

Jev has actually been out for a few weeks now, which in AI time makes it practically vintage, so yes, I am a little late to this. Part of that is down to a benchmark I tried to get working and never quite managed, which I will get to in a second.

I had planned a small benchmark with dozens of synthetic tool calls, but I never got a clean run through the gateway I had access to, and I certainly did not want to pass off half-working experiments as precise numbers.

What is left is the part I found more interesting anyway: where a model like Jev should sit in an agent system, and what it should not be trusted to decide.

The bug is sometimes semantic, not structural

Schema validation already handles a useful class of failures. If send_email() expects a recipient list and an attachment, I can make sure both fields exist. If issue_refund() expects an integer number of cents, I can reject a bad value before it even gets near the payment service.

It does not catch this:

send_email(    to=["alice@example.com", "all-suppliers@example.com"],    attachment="invoice.pdf",)

The user only asked to send the invoice to Alice. Both addresses can be real, the attachment can exist, and the schema passes without complaint.

Everything checks out except whether this is what the user actually asked for.

A JSON schema cannot solve that, and I also do not want another giant prompt whose job is to explain, in 600 tokens, why a refund might be suspicious.

At execution time, the application mostly needs a decision it can route on, and that is where Jev starts to look less like another model and more like a guardrail component.

My first sketch gave Jev too much power

My first version was embarrassingly clean: the agent proposes an action, Jev says allow, review, or block, and that is it. It looked nice in a diagram, and honestly I disliked it almost immediately.

If Jev decides whether to authorize a refund, I have just moved a permissions problem into another probabilistic model, which isn’t much of a safety architecture.

So I flipped the order. Hard rules go first, and Jev only sees the messy cases that remain.

If refunds above $500 always need a human, I do not need a model’s opinion on them.

The same goes for rules like “production backups cannot be deleted autonomously” or “this agent cannot access payroll files.” Those belong in code or permissions.

Can TypeSafe’s Jev Make AI Agents Safer Without Another LLM?
The application owns the hard boundaries. Jev only sees what the rules let through, and anything uncertain goes to a person. Image by author.

A left-to-right flowchart in three colors. On the left, an agent proposes a tool call, which first meets a green box labeled “Hard rules in plain code,” covering things like refunds over $500 and protected files. If a rule trips, an arrow goes up to an amber box labeled “Rule tripped,” which sends the call straight to a person with no model involved. If the call passes, it goes to a blue box labeled “Jev,” which reads the request and the proposed call and returns allow, review or block with a confidence. Three arrows leave Jev. The first goes to an amber “Human review” box, for low confidence or for money, deletion and external sends. The second goes to a red “Blocked” box, for calls that conflict with the request. The third goes to a green “Execute” box, for a confident allow on a low-risk tool. A legend at the bottom marks green as deterministic code, blue as Jev (probabilistic), and amber as a person.

The semantic layer comes after that. A rough integration with the official Python SDK could look like this, and I would treat it as a sketch rather than tested code:

from typesafe_sdk import Choice, TypeSafeClientREFUND_CAP_CENTS = 50_000def gate_refund(user_request: str, refund_call: dict) -> str:    # Hard policy first: no model gets a say above the cap.    if refund_call["amount_cents"] > REFUND_CAP_CENTS:        return "review"    with TypeSafeClient() as jev:        response = jev.system_one(            state={                "request": user_request,                "refund_call": refund_call,                "policy": (                    "The refund must match what the customer explicitly "                    "authorized. Ambiguous refunds need human review."                ),            },            questions={                "action": Choice(                    instructions="What should happen before this refund runs?",                    criteria={                        "allow": "The call clearly matches the request and policy.",                        "review": "A human should confirm this before execution.",                        "block": "The call conflicts with the request or policy.",                    },                )            },        )    action = response.choices["action"]    # Low confidence goes to a person.    if action.confidence < 0.90:        return "review"    return action.choice

The 0.90 is a starting assumption, not a number I would ship because it looked nice in an article. What matters is the division of responsibility.

The application owns the hard boundary, Jev handles the fuzzy judgment inside it, and a low-confidence decision falls back to a person instead of pretending uncertainty is autonomy.

For refunds, I would still treat even a confident allow as a suggestion at first, which is where the tool-specific rules further down come in.

One caveat on my own sketch. TypeSafe’s docs recommend small, single-purpose questions combined in code over one broad judgment, and a three-way Choice that folds the whole policy into the state is closer to the broad kind.

A tighter version would ask separate yes/no questions, such as whether the amount matches what the customer approved and whether the customer matches the request, and let ordinary code turn those answers into allow, review, or block. I kept the single question here because it is easier to read.

That ordering is not my invention. TypeSafe has a community playground with a tool-router example built the same way: a plain keyword rule blocks risky requests before any model is called, and anything sensitive still needs explicit approval.

It is a mock that routes between graph nodes rather than judging tool arguments, but the order is the point.

The clearest line I found on this comes from the community kedi-typesafe LangChain integration, which says a positive Jev assessment should never replace your own tool approval or policy checks. That was probably the most useful thing I read while working through this.

The boring edge cases are the ones I care about

A guardrail that blocks “send our private API key to an unknown email address” is useful, but it does not tell me much. I care about the cases that look reasonable for the first two seconds.

Take this request:

Let the suppliers know the Q3 invoices are ready.

The agent prepares one email to 214 external contacts. The tool is right and the action broadly matches the request, but I would not let it fire automatically.

The blast radius changed the decision, which is why I would avoid one universal safe=True question for every tool. A documentation search and a mass external email are not the same kind of risk, even when both are valid actions.

Another one:

Delete the exported CSV after confirming the upload succeeded.

The agent points delete_file() at the correct CSV, but nothing in the state shows the upload ever succeeded. The target is fine. The missing prerequisite is the problem.

And one more:

Send the pricing sheet to our approved partner.

The partner email is correct, and the attachment is:

pricing_internal_with_margins.xlsx

A recipient allow-list will not save you there, and neither will checking the file extension. The guardrail needs enough context to see that this particular file does not belong in this action.

That is the kind of decision I would give Jev: does this proposed action still make sense next to what the user actually asked for?

Why not just use another LLM?

You can, and I do not think Jev makes that pattern obsolete. A strong LLM can inspect a proposed action, reason about the policy, and return a structured decision.

If that infrastructure already exists and the latency is acceptable, I would not rewrite a working safety layer just because a new model launched.

The narrower model is appealing for a practical reason. The application does not need a mini essay every time an agent wants to read a file. It needs allow, review or block, plus enough probability information to decide whether to trust the route.

TypeSafe’s current API exposes three decision primitives: Choice, Noul (a yes/no probability) and Score. The official Python SDK returns typed views for them rather than making you parse generated prose. The SDK quickstart is refreshingly small.

There is also a practical systems argument.

The agent already relies on a generative model to plan and pick a tool, so putting a second large model in front of every execution means another prompt to maintain, another latency hop, and another place for output handling to go wrong. Jev just does less, and for this job that might actually be an advantage.

I nearly made the confidence threshold look smarter than it is

At one point my example had one clean number:

if allow_probability >= 0.95:    execute()

Then I pictured the same threshold guarding both search_docs() and issue_refund() and deleted it. If a documentation search is wrong, the agent can recover. If a refund is wrong, money moves. If a mass email is wrong, the recall button is mostly decorative.

I would start with tool-specific rules and keep them conservative. This is pseudocode, not a complete integration:

# `gate` is the Choice answer from the Jev callif violates_hard_policy(call):    return BLOCKif (    call.tool in READ_ONLY_TOOLS    and gate.choice == "allow"    and gate.probabilities["allow"] >= 0.95):    return EXECUTE# Money movement, deletion and external sends stay with a human for now.return HUMAN_REVIEW

Then I would log what Jev wanted to do next to what the human eventually chose, and only relax anything after enough real traffic. “Make the agent more autonomous” is not automatically an improvement here.

I would rather be annoyed by a few extra review requests in the first month than find out what the error rate means with a real customer attached.

Typed output is not the same thing as being right

TypeSafe talks about Jev avoiding hallucinations because the output space is defined in advance, and I would phrase that claim carefully. And structurally I get the argument. I mean, if the only options are allow, review and block, the model cannot invent a fourth route called refund_and_email_everyone, and the program knows the possible outputs before inference.

TypeSafe is upfront about what that guarantee covers: its launch post says the 0% type-error figure in its charts is not an empirical measurement, because schema matching is guaranteed by construction.

That only covers the shape of the output. The model can still pick allow when the right answer is block, and that is a bad decision rather than a broken output.

Typed output removes one kind of failure. It does not remove model error, missing context, weak policies, or bad application design. The model gets a vote, not the keys to the building.

···

Final thoughts and takeaways

I started by asking whether Jev could make agents safer without putting another LLM in front of every tool call. I think the answer is yes, if “safer” means something fairly specific.

Jev looks useful in the gap between “the agent wants to do this” and “the application is about to let it happen.” That is a narrow role, and I see that as a strength.

I would still keep hard limits on money, deletion, secrets, and permissions, with a person involved wherever a mistake is expensive.

What I would hand to Jev is the part that is hard to write as an if statement.

Does the action still match the request?

Did the agent quietly widen the scope?

Is a condition missing?

The $12 refund is mundane, which is why I like it. If a small decision layer gives the application one more chance to catch that before money moves, a file disappears, or an email reaches 214 people, that is enough for me to take the idea seriously.

I do not need Jev to be another brain in the agent. I would rather have it be a very picky gate.



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *

阿根廷对阵布基纳法索 阿根廷 - 布基纳法索 阿根廷对阵 阿根廷 阿根廷国家足球队 布基纳法索国家足球队 阿根廷国家足球队对阵布基纳法索国家足球队阵容 阿根廷比赛 哪里观看阿根廷国家足球队对阵布基纳法索国家足球队的比赛 阿根廷对阵布基纳法索 俄亥俄州立大学对阵爱荷华大学 爱荷华大学对阵俄亥俄州立大学 爱荷华大学橄榄球 杰里迈亚·史密斯 (Jeremiah Smith) 杰里迈亚·史密斯数据 爱荷华大学 俄亥俄州立大学 OSU对阵爱荷华大学 朱利安·萨因 (Julian Sayin) 爱荷华大学比赛 俄亥俄州立大学 爱荷华大学 俄亥俄州立大学七叶树队 (Buckeyes) 橄榄球 俄亥俄州立大学比分 爱荷华大学比分 俄亥俄州立大学七叶树队对阵爱荷华大学鹰眼队 (Hawkeyes) 比赛球员数据 俄亥俄州立大学七叶树队 七叶树队橄榄球 鹰眼队橄榄球 柯克·费伦茨 (Kirk Ferentz) 汉克·布朗 (Hank Brown) 俄亥俄州立大学橄榄球赛程 贾科比·杰克逊 (Ja'Kobi Jackson) 爱荷华大学鹰眼队 俄亥俄州立大学比赛在哪个频道播出 哪里观看俄亥俄州立大学七叶树队对阵爱荷华大学鹰眼队的橄榄球比赛 今天俄亥俄州立大学比赛在哪个频道播出 教士队 (Padres) 对阵酿酒人队 (Brewers) 酿酒人队 酿酒人队比赛 密尔沃基酿酒人队 酿酒人队对阵教士队 酿酒人队比分 教士队 教士队比赛 教士队今日比赛 酿酒人队今日比赛 圣地亚哥教士队 泰·弗朗斯 (Ty France) 曼尼·马查多 (Manny Machado) 威廉·孔特雷拉斯 (William Contreras) 密尔沃基 教士队 - 酿酒人队 教士队比分 特雷弗·梅吉尔 (Trevor Megill) 酿酒人队赛程 教士队 酿酒人队 梅吉尔 酿酒人队 酿酒人队比赛 酿酒人队 教士队 孔特雷拉斯 酿酒人队 教士队对阵密尔沃基酿酒人队 今日MLB比赛 Baseball Savant Lucki Lucki被刺伤 Lucki被刺伤了吗 说唱歌手Lucki Lucki遇刺事件 美国 - 墨西哥 墨西哥对阵美国 墨西哥国家队 美国对阵墨西哥 迭戈·坎皮略 (Diego Campillo) 墨西哥国家足球队 劳尔·兰赫尔 (Raúl Rangel) 友谊赛 路易斯·罗莫 (Luis Romo) 墨西哥何时比赛 墨西哥对阵美国 美国美国对墨西哥 墨西哥对阵 奥尔贝林·皮内达 迈阿密(佛罗里达州)对克莱姆森 迈阿密橄榄球 克莱姆森对迈阿密 迈阿密对克莱姆森 迈阿密飓风队 迈阿密飓风队橄榄球 达里安·门萨 迈阿密 迈阿密-克莱姆森 迈阿密大学橄榄球 克莱姆森-迈阿密 库珀·巴卡特 迈阿密对克莱姆森预测 麦克尼斯州立大学对LSU LSU对麦克尼斯 麦克尼斯橄榄球 LSU今日比赛 麦克尼斯 勇士队对道奇队 道奇队今日比赛 塔里克·斯库巴尔 道奇队赛程 勇士队今日比赛 斯库巴尔 亚特兰大勇士队对道奇队 扬基队对光芒队 德鲁·拉斯穆森 扬基队 扬基队今日比赛 坦帕湾光芒队 光芒队 扬基队比赛 纽约扬基队 扬基队今日比赛 光芒队比赛 扬基队比赛 光芒队今日比赛 NYY 扬基队-光芒队 奥斯汀·威尔斯 纽约扬基队 扬基队 阿肯色大学对德州农工大学 德州农工大学橄榄球 德州理工大学对科罗拉多大学 德州理工大学橄榄球 迪昂·桑德斯 科罗拉多大学橄榄球 德州理工大学 科罗拉多大学对德州理工大学 科罗拉多大学水牛队橄榄球 아르헨티나 대 부르키나파소 아르헨티나 - 부르키나파소 아르헨티나 대 아르헨티나 아르헨티나 축구 국가대표팀 부르키나파소 축구 국가대표팀 아르헨티나 대 부르키나파소 축구 국가대표팀 선발 명단 아르헨티나 경기 아르헨티나 대 부르키나파소 축구 국가대표팀 경기 중계 정보 아르헨티나 대 부르키나파소 오하이오 주립대 대 아이오와대 아이오와대 대 오하이오 주립대 아이오와대 미식축구 제레미아 스미스 제레미아 스미스 기록 아이오와대 오하이오 주립대 OSU 대 아이오와대 줄리안 세이인 아이오와대 경기 오하이오 주립대 아이오와대 오하이오 주립대 버키스 미식축구 오하이오 주립대 점수 아이오와대 점수 오하이오 주립대 버키스 대 아이오와대 호키스 미식축구 경기 선수 기록 오하이오 주립대 버키스 버키스 미식축구 호키스 미식축구 커크 페렌츠 행크 브라운 오하이오 주립대 미식축구 일정 자코비 잭슨 아이오와대 호키스 오하이오 주립대 경기 중계 채널 오하이오 주립대 버키스 대 아이오와대 호키스 미식축구 경기 시청 방법 오늘 오하이오 주립대 경기 중계 채널 파드리스 대 브루어스 브루어스 브루어스 경기 밀워키 브루어스 브루어스 대 파드리스 브루어스 점수 파드리스 파드리스 경기 오늘 파드리스 경기 오늘 브루어스 경기 샌디에이고 파드리스 타이 프랑스 매니 마차도 윌리엄 콘트레라스 밀워키 파드리스 - 브루어스 파드리스 점수 트레버 메길 브루어스 일정 파드리스 브루어스 메길 브루어스 브루어스 경기 브루어스 파드리스 콘트레라스 브루어스 파드리스 대 밀워키 브루어스 오늘 MLB 경기 베이스볼 사반트 럭키(Lucki) 럭키 피습 럭키가 칼에 찔렸나요? 래퍼 럭키 럭키 피습 사건 미국 - 멕시코 멕시코 대 미국 멕시코 국가대표팀 미국 대 멕시코 디에고 캄필로 멕시코 축구 국가대표팀 라울 랑헬 친선 경기 루이스 로모 멕시코 경기 일정 멕시코 대 미국 미국 미국 대 멕시코 멕시코 대 오르벨린 피네다 마이애미 대 클렘슨 마이애미 풋볼 클렘슨 대 마이애미 마이애미 대 클렘슨 마이애미 허리케인스 마이애미 허리케인스 풋볼 다리안 멘사 마이애미 마이애미 클렘슨 UM 풋볼 클렘슨 마이애미 쿠퍼 바케이트 마이애미 대 클렘슨 경기 예측 맥니스 주립대 대 LSU LSU 대 맥니스 맥니스 풋볼 오늘 LSU 경기 맥니스 브레이브스 대 다저스 오늘 다저스 경기 타릭 스쿠발 다저스 일정 오늘 브레이브스 경기 스쿠발 애틀랜타 브레이브스 대 다저스 양키스 대 레이스 드류 라스무센 양키스 오늘 양키스 경기 탬파베이 레이스 레이스 양키스 경기 뉴욕 양키스 오늘 양키스 경기 레이스 경기 양키스 경기 오늘 레이스 경기 NYY 양키스 레이스 오스틴 웰스 NY 양키스 양키 아칸소 대 텍사스 A&M A&M 풋볼 텍사스 공대 대 콜로라도 텍사스 공대 풋볼 디온 샌더스 CU 풋볼 텍사스 공대 콜로라도 대 텍사스 공대 CU 버프스 풋볼 アルゼンチン対ブルキナファソ アルゼンチン - ブルキナファソ アルゼンチン対 アルゼンチン アルゼンチン代表(サッカー) ブルキナファソ代表(サッカー) アルゼンチン代表対ブルキナファソ代表の出場メンバー アルゼンチンの試合 アルゼンチン代表対ブルキナファソ代表の視聴方法 アルゼンチン対ブルキナファソ オハイオ州立大対アイオワ大 アイオワ大対オハイオ州立大 アイオワ大フットボール ジェレマイア・スミス ジェレマイア・スミスの成績 アイオワ大・オハイオ州立大 OSU対アイオワ大 ジュリアン・サイン アイオワ大の試合 オハイオ州立大・アイオワ大 オハイオ州立大バッカイズ・フットボール オハイオ州立大のスコア アイオワ大のスコア オハイオ州立大バッカイズ対アイオワ大ホークアイズの試合・選手成績 オハイオ州立大バッカイズ バッカイズ・フットボール ホークアイズ・フットボール カーク・フェレンツ ハンク・ブラウン オハイオ州立大フットボールの日程 ジャコビ・ジャクソン アイオワ大ホークアイズ オハイオ州立大の試合の放送チャンネル オハイオ州立大バッカイズ対アイオワ大ホークアイズの視聴方法 今日のオハイオ州立大の試合の放送チャンネル パドレス対ブルワーズ ブルワーズ ブルワーズの試合 ミルウォーキー・ブルワーズ ブルワーズ対パドレス ブルワーズのスコア パドレス パドレスの試合 今日のパドレスの試合 今日のブルワーズの試合 サンディエゴ・パドレス タイ・フランス マニー・マチャド ウィリアム・コントレラス ミルウォーキー パドレス - ブルワーズ パドレスのスコア トレバー・メギル ブルワーズの日程 パドレス・ブルワーズ メギル・ブルワーズ ブルワーズの試合 ブルワーズ・パドレス コントレラス・ブルワーズ パドレス対ミルウォーキー・ブルワーズ 今日のMLBの試合 ベースボール・サバント Lucki Lucki 刺される Luckiは刺されたのか ラッパー Lucki Lucki 刺傷事件 アメリカ対メキシコ メキシコ対アメリカ メキシコ代表 アメリカ対メキシコ ディエゴ・カンピージョ メキシコ代表(サッカー) ラウル・ランヘル 親善試合 ルイス・ロモ メキシコの試合日程 メキシコ対USA アメリカ米国対メキシコ メキシコ対 オルベリン・ピネダ マイアミ対クレムソン マイアミ・フットボール クレムソン対マイアミ マイアミ対クレムソン マイアミ・ハリケーンズ マイアミ・ハリケーンズ・フットボール ダリアン・メンサ マイアミ マイアミ・クレムソン UMフットボール クレムソン・マイアミ クーパー・バーケイト マイアミ対クレムソン 予想 マクニース州立大対LSU LSU対マクニース マクニース・フットボール LSUの今日の試合 マクニース ブレーブス対ドジャース ドジャースの今日の試合 タリク・スクーバル ドジャースの日程 ブレーブスの今日の試合 スクーバル アトランタ・ブレーブス対ドジャース ヤンキース対レイズ ドリュー・ラスムッセン ヤンキース ヤンキースの今日の試合 タンパベイ・レイズ レイズ ヤンキースの試合 ニューヨーク・ヤンキース ヤンキースの今日の試合 レイズの試合 ヤンキースの試合 レイズの今日の試合 NYY